diff --git a/.travis.yml b/.travis.yml index ba9f8a2c07..16ccc5722b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,9 +1,15 @@ language: ruby +branches: + only: + - master + - beta + - stable + env: global: - DISCOURSE_HOSTNAME=www.example.com - - RUBY_GC_MALLOC_LIMIT=50000000 + - RUBY_GLOBAL_METHOD_CACHE_SIZE=131072 matrix: - "RAILS_MASTER=0 QUNIT_RUN=0 RUN_LINT=0" - "RAILS_MASTER=0 QUNIT_RUN=1 RUN_LINT=0" @@ -11,8 +17,9 @@ env: addons: chrome: stable - postgresql: 9.5 + postgresql: 9.6 apt: + update: true packages: - gifsicle - jpegoptim @@ -33,6 +40,7 @@ sudo: required dist: trusty cache: + apt: true yarn: true directories: - vendor/bundle @@ -50,10 +58,11 @@ before_install: - export PATH=$HOME/.yarn/bin:$PATH install: - - bash -c "if [ '$RAILS_MASTER' == '1' ]; then bundle update --retry=3 --jobs=3 arel rails seed-fu; fi" - - bash -c "if [ '$RAILS_MASTER' == '0' ]; then bundle install --without development --deployment --retry=3 --jobs=3; fi" - - bash -c "if [ '$RUN_LINT' == '1' ]; then yarn global add eslint babel-eslint; fi" - - bash -c "if [ '$QUNIT_RUN' == '1' ]; then yarn install --dev; fi" + - bash -c "if [ '$RAILS_MASTER' == '1' ]; then bundle update --retry=3 --jobs=3 arel rails seed-fu > /dev/null; fi" + - bash -c "if [ '$RAILS_MASTER' == '0' ]; then bundle install --without development --deployment --retry=3 --jobs=3 > /dev/null; fi" + - bash -c "if [ '$RUN_LINT' == '1' ]; then yarn global add eslint babel-eslint > /dev/null; fi" + - bash -c "if [ '$QUNIT_RUN' == '1' ]; then yarn install --dev > /dev/null; fi" + - bash -c "if [ '$RUN_LINT' != '1' ]; then bundle exec rake db:create db:migrate > /dev/null; fi" script: - | @@ -66,8 +75,6 @@ script: eslint --ext .es6 plugins/**/test/javascripts && \ eslint app/assets/javascripts test/javascripts else - bundle exec rake db:create db:migrate - if [ '$QUNIT_RUN' == '1' ]; then bundle exec rake qunit:test['500000'] && \ bundle exec rake plugin:qunit diff --git a/Gemfile b/Gemfile index c89be78a7c..f5a03d7d5d 100644 --- a/Gemfile +++ b/Gemfile @@ -34,7 +34,7 @@ gem 'redis-namespace' gem 'active_model_serializers', '~> 0.8.3' -gem 'onebox', '1.8.47' +gem 'onebox', '1.8.48' gem 'http_accept_language', '~>2.0.5', require: false @@ -58,7 +58,7 @@ gem 'aws-sdk-s3', require: false gem 'excon', require: false gem 'unf', require: false -gem 'email_reply_trimmer', '0.1.11' +gem 'email_reply_trimmer', '~> 0.1' # Forked until https://github.com/toy/image_optim/pull/149 is merged gem 'discourse_image_optim', require: 'image_optim' @@ -115,7 +115,7 @@ group :test, :development do gem 'listen', require: false gem 'certified', require: false # later appears to break Fabricate(:topic, category: category) - gem 'fabrication', '2.9.8', require: false + gem 'fabrication', require: false gem 'mocha', require: false gem 'rb-fsevent', require: RUBY_PLATFORM =~ /darwin/i ? 'rb-fsevent' : false gem 'rb-inotify', '~> 0.9', require: RUBY_PLATFORM =~ /linux/i ? 'rb-inotify' : false diff --git a/Gemfile.lock b/Gemfile.lock index c5b26bd87c..50f5b5c693 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -89,7 +89,7 @@ GEM image_size (~> 1.5) in_threads (~> 1.3) progress (~> 3.0, >= 3.0.1) - email_reply_trimmer (0.1.11) + email_reply_trimmer (0.1.12) ember-data-source (2.2.1) ember-source (>= 1.8, < 3.0) ember-handlebars-template (0.7.5) @@ -225,7 +225,7 @@ GEM omniauth-twitter (1.3.0) omniauth-oauth (~> 1.1) rack - onebox (1.8.47) + onebox (1.8.48) htmlentities (~> 4.3) moneta (~> 1.0) multi_json (~> 1.11) @@ -415,13 +415,13 @@ DEPENDENCIES certified cppjieba_rb discourse_image_optim - email_reply_trimmer (= 0.1.11) + email_reply_trimmer (~> 0.1) ember-handlebars-template (= 0.7.5) ember-rails (= 0.18.5) ember-source (= 2.13.3) excon execjs - fabrication (= 2.9.8) + fabrication fakeweb (~> 1.3.0) fast_blank fast_xor @@ -461,7 +461,7 @@ DEPENDENCIES omniauth-oauth2 omniauth-openid omniauth-twitter - onebox (= 1.8.47) + onebox (= 1.8.48) openid-redis-store pg (~> 0.21.0) pry-nav diff --git a/app/assets/javascripts/admin/components/admin-graph.js.es6 b/app/assets/javascripts/admin/components/admin-graph.js.es6 index c99c7b186b..724e967374 100644 --- a/app/assets/javascripts/admin/components/admin-graph.js.es6 +++ b/app/assets/javascripts/admin/components/admin-graph.js.es6 @@ -1,4 +1,5 @@ import loadScript from 'discourse/lib/load-script'; +import { number } from 'discourse/lib/formatter'; export default Ember.Component.extend({ tagName: 'canvas', @@ -22,10 +23,16 @@ export default Ember.Component.extend({ data: data, options: { responsive: true, + tooltips: { + callbacks: { + title: (context) => moment(context[0].xLabel, "YYYY-MM-DD").format("LL") + } + }, scales: { yAxes: [{ display: true, ticks: { + callback: (label) => number(label), suggestedMin: 0 } }] diff --git a/app/assets/javascripts/admin/components/dashboard-inline-table.js.es6 b/app/assets/javascripts/admin/components/dashboard-inline-table.js.es6 index 82eceb6691..8fae065f7b 100644 --- a/app/assets/javascripts/admin/components/dashboard-inline-table.js.es6 +++ b/app/assets/javascripts/admin/components/dashboard-inline-table.js.es6 @@ -1,32 +1,13 @@ import { ajax } from "discourse/lib/ajax"; -import Report from "admin/models/report"; import AsyncReport from "admin/mixins/async-report"; export default Ember.Component.extend(AsyncReport, { - classNames: ["dashboard-table", "dashboard-inline-table", "fixed"], - help: null, - helpPage: null, - - loadReport(report_json) { - return Report.create(report_json); - }, + classNames: ["dashboard-inline-table"], fetchReport() { this._super(); - let payload = { data: { cache: true, facets: ["total", "prev30Days"] } }; - - if (this.get("startDate")) { - payload.data.start_date = this.get("startDate").format("YYYY-MM-DD[T]HH:mm:ss.SSSZZ"); - } - - if (this.get("endDate")) { - payload.data.end_date = this.get("endDate").format("YYYY-MM-DD[T]HH:mm:ss.SSSZZ"); - } - - if (this.get("limit")) { - payload.data.limit = this.get("limit"); - } + let payload = this.buildPayload(["total", "prev30Days"]); return Ember.RSVP.Promise.all(this.get("dataSources").map(dataSource => { return ajax(dataSource, payload) diff --git a/app/assets/javascripts/admin/components/dashboard-mini-chart.js.es6 b/app/assets/javascripts/admin/components/dashboard-mini-chart.js.es6 index 0ac44e2bbb..5992e47953 100644 --- a/app/assets/javascripts/admin/components/dashboard-mini-chart.js.es6 +++ b/app/assets/javascripts/admin/components/dashboard-mini-chart.js.es6 @@ -52,17 +52,7 @@ export default Ember.Component.extend(AsyncReport, { fetchReport() { this._super(); - let payload = { - data: { cache: true, facets: ["prev_period"] } - }; - - if (this.get("startDate")) { - payload.data.start_date = this.get("startDate").locale('en').format('YYYY-MM-DD[T]HH:mm:ss.SSSZZ'); - } - - if (this.get("endDate")) { - payload.data.end_date = this.get("endDate").locale('en').format('YYYY-MM-DD[T]HH:mm:ss.SSSZZ'); - } + let payload = this.buildPayload(["prev_period"]); if (this._chart) { this._chart.destroy(); @@ -110,7 +100,7 @@ export default Ember.Component.extend(AsyncReport, { labels, datasets: reportsForPeriod.map(report => { return { - data: Ember.makeArray(report.data).map(d => d.y), + data: Ember.makeArray(report.data).map(d => number(d.y, { ceil: true })), backgroundColor: "rgba(200,220,240,0.3)", borderColor: report.color }; @@ -157,7 +147,7 @@ export default Ember.Component.extend(AsyncReport, { scales: { yAxes: [{ display: true, - ticks: { callback: (label) => number(label) } + ticks: { callback: (label) => number(label, { ceil: true }) } }], xAxes: [{ display: true, diff --git a/app/assets/javascripts/admin/components/dashboard-table.js.es6 b/app/assets/javascripts/admin/components/dashboard-table.js.es6 new file mode 100644 index 0000000000..96b74e6e15 --- /dev/null +++ b/app/assets/javascripts/admin/components/dashboard-table.js.es6 @@ -0,0 +1,19 @@ +import { ajax } from "discourse/lib/ajax"; +import AsyncReport from "admin/mixins/async-report"; + +export default Ember.Component.extend(AsyncReport, { + classNames: ["dashboard-table"], + + fetchReport() { + this._super(); + + let payload = this.buildPayload(["total", "prev30Days"]); + + return Ember.RSVP.Promise.all(this.get("dataSources").map(dataSource => { + return ajax(dataSource, payload) + .then(response => { + this.get("reports").pushObject(this.loadReport(response.report)); + }); + })); + } +}); diff --git a/app/assets/javascripts/admin/components/watched-word-form.js.es6 b/app/assets/javascripts/admin/components/watched-word-form.js.es6 index 9b2213de61..e7ead641f2 100644 --- a/app/assets/javascripts/admin/components/watched-word-form.js.es6 +++ b/app/assets/javascripts/admin/components/watched-word-form.js.es6 @@ -5,7 +5,7 @@ export default Ember.Component.extend({ classNames: ['watched-word-form'], formSubmitted: false, actionKey: null, - showSuccessMessage: false, + showMessage: false, @computed('regularExpressions') placeholderKey(regularExpressions) { @@ -14,21 +14,33 @@ export default Ember.Component.extend({ }, @observes('word') - removeSuccessMessage() { - if (this.get('showSuccessMessage') && !Ember.isEmpty(this.get('word'))) { - this.set('showSuccessMessage', false); + removeMessage() { + if (this.get('showMessage') && !Ember.isEmpty(this.get('word'))) { + this.set('showMessage', false); } }, + @computed('word') + isUniqueWord(word) { + const words = this.get("filteredContent") || []; + const filtered = words.filter(content => content.action === this.get("actionKey")); + return filtered.every(content => content.word.toLowerCase() !== word.toLowerCase()); + }, + actions: { submit() { + if (!this.get("isUniqueWord")) { + this.setProperties({ showMessage: true, message: I18n.t('admin.watched_words.form.exists') }); + return; + } + if (!this.get('formSubmitted')) { this.set('formSubmitted', true); const watchedWord = WatchedWord.create({ word: this.get('word'), action: this.get('actionKey') }); watchedWord.save().then(result => { - this.setProperties({ word: '', formSubmitted: false, showSuccessMessage: true }); + this.setProperties({ word: '', formSubmitted: false, showMessage: true, message: I18n.t('admin.watched_words.form.success') }); this.sendAction('action', WatchedWord.create(result)); Ember.run.schedule('afterRender', () => this.$('.watched-word-input').focus()); }).catch(e => { diff --git a/app/assets/javascripts/admin/controllers/admin-reports.js.es6 b/app/assets/javascripts/admin/controllers/admin-reports.js.es6 index 83fde41c7e..1b02d5575a 100644 --- a/app/assets/javascripts/admin/controllers/admin-reports.js.es6 +++ b/app/assets/javascripts/admin/controllers/admin-reports.js.es6 @@ -4,6 +4,7 @@ import Report from 'admin/models/report'; import computed from 'ember-addons/ember-computed-decorators'; export default Ember.Controller.extend({ + classNames: ["admin-reports"], queryParams: ["mode", "start_date", "end_date", "category_id", "group_id"], viewMode: 'graph', viewingTable: Em.computed.equal('viewMode', 'table'), diff --git a/app/assets/javascripts/admin/controllers/admin-user-index.js.es6 b/app/assets/javascripts/admin/controllers/admin-user-index.js.es6 index ee49a1c119..0d2ae55508 100644 --- a/app/assets/javascripts/admin/controllers/admin-user-index.js.es6 +++ b/app/assets/javascripts/admin/controllers/admin-user-index.js.es6 @@ -50,6 +50,36 @@ export default Ember.Controller.extend(CanCheckEmails, { return userPath(`${username}/preferences`); }, + @computed('model.can_delete_all_posts', 'model.staff', 'model.post_count') + deleteAllPostsExplanation(canDeleteAllPosts, staff, postCount) { + if (canDeleteAllPosts) { + return null; + } + + if (staff) { + return I18n.t('admin.user.delete_posts_forbidden_because_staff'); + } + if (postCount > this.siteSettings.delete_all_posts_max) { + return I18n.t('admin.user.cant_delete_all_too_many_posts', {count: this.siteSettings.delete_all_posts_max}); + } else { + return I18n.t('admin.user.cant_delete_all_posts', {count: this.siteSettings.delete_user_max_post_age}); + } + }, + + @computed('model.canBeDeleted', 'model.staff') + deleteExplanation(canBeDeleted, staff) { + if (canBeDeleted) { + return null; + } + + if (staff) { + return I18n.t('admin.user.delete_forbidden_because_staff'); + } else { + return I18n.t('admin.user.delete_forbidden', {count: this.siteSettings.delete_user_max_post_age}); + } + }, + + actions: { impersonate() { return this.get("model").impersonate(); }, @@ -73,6 +103,16 @@ export default Ember.Controller.extend(CanCheckEmails, { anonymize() { return this.get('model').anonymize(); }, disableSecondFactor() { return this.get('model').disableSecondFactor(); }, + + clearPenaltyHistory() { + let user = this.get('model'); + return ajax(`/admin/users/${user.get('id')}/penalty_history`, { + type: 'DELETE' + }).then(() => { + user.set('tl3_requirements.penalty_counts.total', 0); + }).catch(popupAjaxError); + }, + destroy() { const postCount = this.get('model.post_count'); if (postCount <= 5) { diff --git a/app/assets/javascripts/admin/controllers/admin-watched-words.js.es6 b/app/assets/javascripts/admin/controllers/admin-watched-words.js.es6 index dc4428fc72..7f9bc8fd86 100644 --- a/app/assets/javascripts/admin/controllers/admin-watched-words.js.es6 +++ b/app/assets/javascripts/admin/controllers/admin-watched-words.js.es6 @@ -46,6 +46,10 @@ export default Ember.Controller.extend({ actions: { clearFilter() { this.setProperties({ filter: '' }); + }, + + toggleMenu() { + $('.admin-detail').toggleClass('mobile-closed mobile-open'); } } diff --git a/app/assets/javascripts/admin/mixins/async-report.js.es6 b/app/assets/javascripts/admin/mixins/async-report.js.es6 index 2c22ab15c2..760a205948 100644 --- a/app/assets/javascripts/admin/mixins/async-report.js.es6 +++ b/app/assets/javascripts/admin/mixins/async-report.js.es6 @@ -1,7 +1,8 @@ import computed from "ember-addons/ember-computed-decorators"; +import Report from "admin/models/report"; export default Ember.Mixin.create({ - classNameBindings: ["isLoading"], + classNameBindings: ["isLoading", "dataSourceNames"], reports: null, isLoading: false, dataSourceNames: "", @@ -17,6 +18,24 @@ export default Ember.Mixin.create({ return dataSourceNames.split(",").map(source => `/admin/reports/${source}`); }, + buildPayload(facets) { + let payload = { data: { cache: true, facets } }; + + if (this.get("startDate")) { + payload.data.start_date = this.get("startDate").format("YYYY-MM-DD[T]HH:mm:ss.SSSZZ"); + } + + if (this.get("endDate")) { + payload.data.end_date = this.get("endDate").format("YYYY-MM-DD[T]HH:mm:ss.SSSZZ"); + } + + if (this.get("limit")) { + payload.data.limit = this.get("limit"); + } + + return payload; + }, + @computed("reports.[]", "startDate", "endDate", "dataSourceNames") reportsForPeriod(reports, startDate, endDate, dataSourceNames) { // on a slow network fetchReport could be called multiple times between @@ -25,7 +44,6 @@ export default Ember.Mixin.create({ // the array contains only unique values reports = reports.uniqBy("report_key"); - const sort = (r) => { if (r.length > 1) { return dataSourceNames @@ -40,7 +58,6 @@ export default Ember.Mixin.create({ return sort(reports); } - return sort(reports.filter(report => { return report.report_key.includes(startDate.format("YYYYMMDD")) && report.report_key.includes(endDate.format("YYYYMMDD")); @@ -71,7 +88,9 @@ export default Ember.Mixin.create({ this.set("isLoading", false); }, - loadReport() {}, + loadReport(jsonReport) { + return Report.create(jsonReport); + }, fetchReport() { this.set("reports", []); diff --git a/app/assets/javascripts/admin/models/admin-user.js.es6 b/app/assets/javascripts/admin/models/admin-user.js.es6 index b826426473..ba7528258d 100644 --- a/app/assets/javascripts/admin/models/admin-user.js.es6 +++ b/app/assets/javascripts/admin/models/admin-user.js.es6 @@ -87,21 +87,6 @@ const AdminUser = Discourse.User.extend({ }).then(() => this.set('api_key', null)); }, - deleteAllPostsExplanation: function() { - if (!this.get('can_delete_all_posts')) { - if (this.get('deleteForbidden') && this.get('staff')) { - return I18n.t('admin.user.delete_posts_forbidden_because_staff'); - } - if (this.get('post_count') > Discourse.SiteSettings.delete_all_posts_max) { - return I18n.t('admin.user.cant_delete_all_too_many_posts', {count: Discourse.SiteSettings.delete_all_posts_max}); - } else { - return I18n.t('admin.user.cant_delete_all_posts', {count: Discourse.SiteSettings.delete_user_max_post_age}); - } - } else { - return null; - } - }.property('can_delete_all_posts', 'deleteForbidden'), - deleteAllPosts() { const user = this, message = I18n.messageFormat('admin.user.delete_all_posts_confirm_MF', { "POSTS": user.get('post_count'), "TOPICS": user.get('topic_count') }), @@ -240,8 +225,6 @@ const AdminUser = Discourse.User.extend({ return this.get('trust_level') < 4; }.property('trust_level'), - isSuspended: Em.computed.equal('suspended', true), - isSilenced: Ember.computed.equal('silenced', true), canSuspend: Em.computed.not('staff'), suspendDuration: function() { @@ -353,8 +336,6 @@ const AdminUser = Discourse.User.extend({ }).catch(popupAjaxError); }, - anonymizeForbidden: Em.computed.not("can_be_anonymized"), - anonymize() { const user = this, message = I18n.t("admin.user.anonymize_confirm"); @@ -393,20 +374,6 @@ const AdminUser = Discourse.User.extend({ bootbox.dialog(message, buttons, { "classes": "delete-user-modal" }); }, - deleteForbidden: Em.computed.not("canBeDeleted"), - - deleteExplanation: function() { - if (this.get('deleteForbidden')) { - if (this.get('staff')) { - return I18n.t('admin.user.delete_forbidden_because_staff'); - } else { - return I18n.t('admin.user.delete_forbidden', {count: Discourse.SiteSettings.delete_user_max_post_age}); - } - } else { - return null; - } - }.property('deleteForbidden'), - destroy(opts) { const user = this, message = I18n.t("admin.user.delete_confirm"), diff --git a/app/assets/javascripts/admin/models/report.js.es6 b/app/assets/javascripts/admin/models/report.js.es6 index 5441be004a..80c160a8d9 100644 --- a/app/assets/javascripts/admin/models/report.js.es6 +++ b/app/assets/javascripts/admin/models/report.js.es6 @@ -1,22 +1,24 @@ -import { ajax } from 'discourse/lib/ajax'; +import { ajax } from "discourse/lib/ajax"; import round from "discourse/lib/round"; -import { fillMissingDates } from 'discourse/lib/utilities'; -import computed from 'ember-addons/ember-computed-decorators'; +import { fillMissingDates } from "discourse/lib/utilities"; +import computed from "ember-addons/ember-computed-decorators"; +import { number } from 'discourse/lib/formatter'; const Report = Discourse.Model.extend({ average: false, percent: false, + higher_is_better: true, @computed("type", "start_date", "end_date") reportUrl(type, start_date, end_date) { - start_date = moment(start_date).locale('en').format("YYYY-MM-DD"); - end_date = moment(end_date).locale('en').format("YYYY-MM-DD"); + start_date = moment(start_date).locale("en").format("YYYY-MM-DD"); + end_date = moment(end_date).locale("en").format("YYYY-MM-DD"); return Discourse.getURL(`/admin/reports/${type}?start_date=${start_date}&end_date=${end_date}`); }, valueAt(numDaysAgo) { if (this.data) { - const wantedDate = moment().subtract(numDaysAgo, "days").locale('en').format("YYYY-MM-DD"); + const wantedDate = moment().subtract(numDaysAgo, "days").locale("en").format("YYYY-MM-DD"); const item = this.data.find(d => d.x === wantedDate); if (item) { return item.y; @@ -29,7 +31,7 @@ const Report = Discourse.Model.extend({ if (this.data) { const earliestDate = moment().subtract(endDaysAgo, "days").startOf("day"); const latestDate = moment().subtract(startDaysAgo, "days").startOf("day"); - var d, sum = 0, count = 0; + let d, sum = 0, count = 0; _.each(this.data, datum => { d = moment(datum.x); if (d >= earliestDate && d <= latestDate) { @@ -46,6 +48,7 @@ const Report = Discourse.Model.extend({ yesterdayCount: function() { return this.valueAt(1); }.property("data", "average"), sevenDaysAgoCount: function() { return this.valueAt(7); }.property("data", "average"), thirtyDaysAgoCount: function() { return this.valueAt(30); }.property("data", "average"), + lastSevenDaysCount: function() { return this.averageCount(7, this.valueFor(1, 7)); }.property("data", "average"), @@ -57,112 +60,66 @@ const Report = Discourse.Model.extend({ return this.get("average") ? value / count : value; }, - @computed('yesterdayCount') - yesterdayTrend(yesterdayCount) { - const yesterdayVal = yesterdayCount; - const twoDaysAgoVal = this.valueAt(2); - const change = ((yesterdayVal - twoDaysAgoVal) / yesterdayVal) * 100; - - if (change > 50) { - return "high-trending-up"; - } else if (change > 0) { - return "trending-up"; - } else if (change === 0) { - return "no-change"; - } else if (change < -50) { - return "high-trending-down"; - } else if (change < 0) { - return "trending-down"; - } + @computed("yesterdayCount", "higher_is_better") + yesterdayTrend(yesterdayCount, higherIsBetter) { + return this._computeTrend(this.valueAt(2), yesterdayCount, higherIsBetter); }, - @computed('lastSevenDaysCount') - sevenDayTrend(lastSevenDaysCount) { - const currentPeriod = lastSevenDaysCount; - const prevPeriod = this.valueFor(8, 14); - const change = ((currentPeriod - prevPeriod) / prevPeriod) * 100; - - if (change > 50) { - return "high-trending-up"; - } else if (change > 0) { - return "trending-up"; - } else if (change === 0) { - return "no-change"; - } else if (change < -50) { - return "high-trending-down"; - } else if (change < 0) { - return "trending-down"; - } + @computed("lastSevenDaysCount", "higher_is_better") + sevenDaysTrend(lastSevenDaysCount, higherIsBetter) { + return this._computeTrend(this.valueFor(8, 14), lastSevenDaysCount, higherIsBetter); }, - @computed('data') + @computed("data") currentTotal(data){ return _.reduce(data, (cur, pair) => cur + pair.y, 0); }, - @computed('data', 'currentTotal') + @computed("data", "currentTotal") currentAverage(data, total) { return Ember.makeArray(data).length === 0 ? 0 : parseFloat((total / parseFloat(data.length)).toFixed(1)); }, - @computed("trend") - trendIcon(trend) { - switch (trend) { - case "trending-up": - return "angle-up"; - case "trending-down": - return "angle-down"; - case "high-trending-up": - return "angle-double-up"; - case "high-trending-down": - return "angle-double-down"; - default: - return null; - } + @computed("trend", "higher_is_better") + trendIcon(trend, higherIsBetter) { + return this._iconForTrend(trend, higherIsBetter); }, - @computed('prev_period', 'currentTotal', 'currentAverage') - trend(prev, currentTotal, currentAverage) { - const total = this.get('average') ? currentAverage : currentTotal; - const change = ((total - prev) / total) * 100; - - if (change > 50) { - return "high-trending-up"; - } else if (change > 0) { - return "trending-up"; - } else if (change === 0) { - return "no-change"; - } else if (change < -50) { - return "high-trending-down"; - } else if (change < 0) { - return "trending-down"; - } + @computed("sevenDaysTrend", "higher_is_better") + sevenDaysTrendIcon(sevenDaysTrend, higherIsBetter) { + return this._iconForTrend(sevenDaysTrend, higherIsBetter); }, - @computed('prev30Days', 'lastThirtyDaysCount') - thirtyDayTrend(prev30Days, lastThirtyDaysCount) { - const currentPeriod = lastThirtyDaysCount; - const change = ((currentPeriod - prev30Days) / currentPeriod) * 100; - - if (change > 50) { - return "high-trending-up"; - } else if (change > 0) { - return "trending-up"; - } else if (change === 0) { - return "no-change"; - } else if (change < -50) { - return "high-trending-down"; - } else if (change < 0) { - return "trending-down"; - } + @computed("thirtyDaysTrend", "higher_is_better") + thirtyDaysTrendIcon(thirtyDaysTrend, higherIsBetter) { + return this._iconForTrend(thirtyDaysTrend, higherIsBetter); }, - @computed('type') + @computed("yesterdayTrend", "higher_is_better") + yesterdayTrendIcon(yesterdayTrend, higherIsBetter) { + return this._iconForTrend(yesterdayTrend, higherIsBetter); + }, + + @computed("prev_period", "currentTotal", "currentAverage", "higher_is_better") + trend(prev, currentTotal, currentAverage, higherIsBetter) { + const total = this.get("average") ? currentAverage : currentTotal; + return this._computeTrend(prev, total, higherIsBetter); + }, + + @computed("prev30Days", "lastThirtyDaysCount", "higher_is_better") + thirtyDaysTrend(prev30Days, lastThirtyDaysCount, higherIsBetter) { + return this._computeTrend(prev30Days, lastThirtyDaysCount, higherIsBetter); + }, + + @computed("type") icon(type) { if (type.indexOf("message") > -1) { return "envelope"; } switch (type) { + case "page_view_total_reqs": return "file"; + case "visits": return "user"; + case "time_to_first_response": return "reply"; case "flags": return "flag"; case "likes": return "heart"; case "bookmarks": return "bookmark"; @@ -170,7 +127,7 @@ const Report = Discourse.Model.extend({ } }, - @computed('type') + @computed("type") method(type) { if (type === "time_to_first_response") { return "average"; @@ -180,75 +137,112 @@ const Report = Discourse.Model.extend({ }, percentChangeString(val1, val2) { - const val = ((val1 - val2) / val2) * 100; - if (isNaN(val) || !isFinite(val)) { + const change = this._computeChange(val1, val2); + + if (isNaN(change) || !isFinite(change)) { return null; - } else if (val > 0) { - return "+" + val.toFixed(0) + "%"; + } else if (change > 0) { + return "+" + change.toFixed(0) + "%"; } else { - return val.toFixed(0) + "%"; + return change.toFixed(0) + "%"; } }, - @computed('prev_period', 'currentTotal', 'currentAverage') + @computed("prev_period", "currentTotal", "currentAverage") trendTitle(prev, currentTotal, currentAverage) { - let current = this.get('average') ? currentAverage : currentTotal; - let percent = this.percentChangeString(current, prev); + let current = this.get("average") ? currentAverage : currentTotal; + let percent = this.percentChangeString(prev, current); - if (this.get('average')) { + if (this.get("average")) { prev = prev ? prev.toFixed(1) : "0"; - if (this.get('percent')) { - current += '%'; - prev += '%'; + if (this.get("percent")) { + current += "%"; + prev += "%"; } + } else { + prev = number(prev); + current = number(current); } - return I18n.t('admin.dashboard.reports.trend_title', {percent: percent, prev: prev, current: current}); + return I18n.t("admin.dashboard.reports.trend_title", {percent, prev, current}); }, - changeTitle(val1, val2, prevPeriodString) { - const percentChange = this.percentChangeString(val1, val2); - var title = ""; - if (percentChange) { title += percentChange + " change. "; } - title += "Was " + val2 + " " + prevPeriodString + "."; + changeTitle(valAtT1, valAtT2, prevPeriodString) { + const change = this.percentChangeString(valAtT1, valAtT2); + let title = ""; + if (change) { title += `${change} change. `; } + title += `Was ${number(valAtT1)} ${prevPeriodString}.`; return title; }, - @computed('yesterdayCount') + @computed("yesterdayCount") yesterdayCountTitle(yesterdayCount) { - return this.changeTitle(yesterdayCount, this.valueAt(2), "two days ago"); + return this.changeTitle(this.valueAt(2), yesterdayCount, "two days ago"); }, - @computed('lastSevenDaysCount') - sevenDayCountTitle(lastSevenDaysCount) { - return this.changeTitle(lastSevenDaysCount, this.valueFor(8, 14), "two weeks ago"); + @computed("lastSevenDaysCount") + sevenDaysCountTitle(lastSevenDaysCount) { + return this.changeTitle(this.valueFor(8, 14), lastSevenDaysCount, "two weeks ago"); }, - @computed('prev30Days', 'lastThirtyDaysCount') - thirtyDayCountTitle(prev30Days, lastThirtyDaysCount) { - return this.changeTitle(lastThirtyDaysCount, prev30Days, "in the previous 30 day period"); + @computed("prev30Days", "lastThirtyDaysCount") + thirtyDaysCountTitle(prev30Days, lastThirtyDaysCount) { + return this.changeTitle(prev30Days, lastThirtyDaysCount, "in the previous 30 day period"); }, - @computed('data') + @computed("data") sortedData(data) { - return this.get('xAxisIsDate') ? data.toArray().reverse() : data.toArray(); + return this.get("xAxisIsDate") ? data.toArray().reverse() : data.toArray(); }, - @computed('data') + @computed("data") xAxisIsDate() { if (!this.data[0]) return false; return this.data && this.data[0].x.match(/\d{4}-\d{1,2}-\d{1,2}/); - } + }, + _computeChange(valAtT1, valAtT2) { + return ((valAtT2 - valAtT1) / valAtT1) * 100; + }, + + _computeTrend(valAtT1, valAtT2, higherIsBetter) { + const change = this._computeChange(valAtT1, valAtT2); + + if (change > 50) { + return higherIsBetter ? "high-trending-up" : "high-trending-down"; + } else if (change > 2) { + return higherIsBetter ? "trending-up" : "trending-down"; + } else if (change <= 2 && change >= -2) { + return "no-change"; + } else if (change < -50) { + return higherIsBetter ? "high-trending-down" : "high-trending-up"; + } else if (change < -2) { + return higherIsBetter ? "trending-down" : "trending-up"; + } + }, + + _iconForTrend(trend, higherIsBetter) { + switch (trend) { + case "trending-up": + return higherIsBetter ? "angle-up" : "angle-down"; + case "trending-down": + return higherIsBetter ? "angle-down" : "angle-up"; + case "high-trending-up": + return higherIsBetter ? "angle-double-up" : "angle-double-down"; + case "high-trending-down": + return higherIsBetter ? "angle-double-down" : "angle-double-up"; + default: + return null; + } + } }); Report.reopenClass({ - fillMissingDates(report) { if (_.isArray(report.data)) { - const startDateFormatted = moment.utc(report.start_date).locale('en').format('YYYY-MM-DD'); - const endDateFormatted = moment.utc(report.end_date).locale('en').format('YYYY-MM-DD'); + const startDateFormatted = moment.utc(report.start_date).locale("en").format("YYYY-MM-DD"); + const endDateFormatted = moment.utc(report.end_date).locale("en").format("YYYY-MM-DD"); report.data = fillMissingDates(report.data, startDateFormatted, endDateFormatted); } }, @@ -272,7 +266,7 @@ Report.reopenClass({ // TODO: fillMissingDates if xaxis is date const related = Report.create({ type: json.report.related_report.type }); related.setProperties(json.report.related_report); - model.set('relatedReport', related); + model.set("relatedReport", related); } return model; diff --git a/app/assets/javascripts/admin/models/staff-action-log.js.es6 b/app/assets/javascripts/admin/models/staff-action-log.js.es6 index 78d39869cf..88cba94b4c 100644 --- a/app/assets/javascripts/admin/models/staff-action-log.js.es6 +++ b/app/assets/javascripts/admin/models/staff-action-log.js.es6 @@ -1,54 +1,58 @@ -import { ajax } from 'discourse/lib/ajax'; -import AdminUser from 'admin/models/admin-user'; -import { escapeExpression } from 'discourse/lib/utilities'; +import computed from "ember-addons/ember-computed-decorators"; +import { ajax } from "discourse/lib/ajax"; +import AdminUser from "admin/models/admin-user"; +import { escapeExpression } from "discourse/lib/utilities"; + +function format(label, value, escape = true) { + return value ? `${I18n.t(label)}: ${escape ? escapeExpression(value) : value}` : ""; +}; const StaffActionLog = Discourse.Model.extend({ showFullDetails: false, - actionName: function() { - return I18n.t("admin.logs.staff_actions.actions." + this.get('action_name')); - }.property('action_name'), - - formattedDetails: function() { - let formatted = ""; - formatted += this.format('email', 'email'); - 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'); - } - if (!this.get('useModalForDetails')) { - if (this.get('details')) formatted += escapeExpression(this.get('details')) + '
'; - } - return formatted; - }.property('ip_address', 'email', 'topic_id', 'post_id', 'category_id'), - - format(label, propertyName) { - if (this.get(propertyName)) { - let value = escapeExpression(this.get(propertyName)); - if (propertyName === 'post_id') { - value = `${value}`; - } - return `${I18n.t(label)}: ${value}
`; - } else { - return ''; - } + @computed("action_name") + actionName(actionName) { + return I18n.t(`admin.logs.staff_actions.actions.${actionName}`); }, - useModalForDetails: function() { - return (this.get('details') && this.get('details').length > 100); - }.property('action_name'), + @computed("email", "ip_address", "topic_id", "post_id", "category_id", "new_value", "previous_value", "details", "useCustomModalForDetails", "useModalForDetails") + formattedDetails(email, ipAddress, topicId, postId, categoryId, newValue, previousValue, details, useCustomModalForDetails, useModalForDetails) { + const postLink = postId ? `${postId}` : null; - useCustomModalForDetails: function() { - return _.contains(['change_theme', 'delete_theme'], this.get('action_name')); - }.property('action_name') + let lines = [ + format("email", email), + format("admin.logs.ip_address", ipAddress), + format("admin.logs.topic_id", topicId), + format("admin.logs.post_id", postLink, false), + format("admin.logs.category_id", categoryId), + ]; + + if (!useCustomModalForDetails) { + lines.push(format("admin.logs.staff_actions.new_value", newValue)); + lines.push(format("admin.logs.staff_actions.previous_value", previousValue)); + } + + if (!useModalForDetails && details) { + lines = [...lines, ...escapeExpression(details).split("\n")]; + } + + const formatted = lines.filter(l => l.length > 0).join("
"); + return formatted.length > 0 ? formatted + "
" : ""; + }, + + @computed("details") + useModalForDetails(details) { + return details && details.length > 100; + }, + + @computed("action_name") + useCustomModalForDetails(actionName) { + return ["change_theme", "delete_theme"].includes(actionName); + } }); StaffActionLog.reopenClass({ - create: function(attrs) { + create(attrs) { attrs = attrs || {}; if (attrs.acting_user) { @@ -60,13 +64,11 @@ StaffActionLog.reopenClass({ return this._super(attrs); }, - findAll: function(filters) { - return ajax("/admin/logs/staff_action_logs.json", { data: filters }).then((data) => { + findAll(data) { + return ajax("/admin/logs/staff_action_logs.json", { data }).then(result => { return { - staff_action_logs: data.staff_action_logs.map(function(s) { - return StaffActionLog.create(s); - }), - user_history_actions: data.user_history_actions + staff_action_logs: result.staff_action_logs.map(s => StaffActionLog.create(s)), + user_history_actions: result.user_history_actions }; }); } diff --git a/app/assets/javascripts/admin/templates/badges-show.hbs b/app/assets/javascripts/admin/templates/badges-show.hbs index 6fa158d0f3..7436c48898 100644 --- a/app/assets/javascripts/admin/templates/badges-show.hbs +++ b/app/assets/javascripts/admin/templates/badges-show.hbs @@ -18,7 +18,7 @@
{{input type="text" name="image" value=buffered.image}} -

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

+

{{i18n 'admin.badges.image_help'}}

diff --git a/app/assets/javascripts/admin/templates/components/admin-report-counts.hbs b/app/assets/javascripts/admin/templates/components/admin-report-counts.hbs index 793573e250..d7f37040f6 100644 --- a/app/assets/javascripts/admin/templates/components/admin-report-counts.hbs +++ b/app/assets/javascripts/admin/templates/components/admin-report-counts.hbs @@ -5,18 +5,18 @@ {{report.title}} -{{number report.todayCount}} +{{number report.todayCount ceil=true}} - {{number report.yesterdayCount}} {{d-icon "caret-up" class="up"}} {{d-icon "caret-down" class="down"}} + {{number report.yesterdayCount ceil=true}} {{d-icon report.yesterdayTrendIcon}} - - {{number report.lastSevenDaysCount}} {{d-icon "caret-up" class="up"}} {{d-icon "caret-down" class="down"}} + + {{number report.lastSevenDaysCount ceil=true}} {{d-icon report.sevenDaysTrendIcon}} - - {{number report.lastThirtyDaysCount}} {{d-icon "caret-up" class="up"}} {{d-icon "caret-down" class="down"}} + + {{number report.lastThirtyDaysCount ceil=true}} {{d-icon report.thirtyDaysTrendIcon}} {{#if allTime}} diff --git a/app/assets/javascripts/admin/templates/components/dashboard-inline-table.hbs b/app/assets/javascripts/admin/templates/components/dashboard-inline-table.hbs index f6a44b7b53..9e976f46d2 100644 --- a/app/assets/javascripts/admin/templates/components/dashboard-inline-table.hbs +++ b/app/assets/javascripts/admin/templates/components/dashboard-inline-table.hbs @@ -1,40 +1,27 @@ {{#conditional-loading-section isLoading=isLoading}}

{{title}}

- - {{#if help}} - {{i18n help}} - {{/if}}
{{#each reportsForPeriod as |report|}}
- - - - {{#if report.labels}} - {{#each report.labels as |label|}} - - {{/each}} - {{else}} - {{#each report.data as |data|}} - - {{/each}} - {{/if}} - - - - {{#unless hasBlock}} - {{#each report.data as |data|}} - - - - {{/each}} - {{else}} - {{yield (hash report=report)}} - {{/unless}} - -
{{label}}{{data.x}}
{{number data.y}}
+ {{#unless hasBlock}} + {{#each report.data as |data|}} + + + {{#if data.icon}} + {{d-icon data.icon}} + {{/if}} + {{data.x}} + + + {{number data.y}} + + + {{/each}} + {{else}} + {{yield (hash report=report)}} + {{/unless}}
{{/each}} {{/conditional-loading-section}} diff --git a/app/assets/javascripts/admin/templates/components/dashboard-mini-chart.hbs b/app/assets/javascripts/admin/templates/components/dashboard-mini-chart.hbs index 328e0829ff..62e956cd8c 100644 --- a/app/assets/javascripts/admin/templates/components/dashboard-mini-chart.hbs +++ b/app/assets/javascripts/admin/templates/components/dashboard-mini-chart.hbs @@ -14,9 +14,9 @@
{{#if report.average}} - {{number report.currentAverage}}{{#if report.percent}}%{{/if}} + {{number report.currentAverage ceil=true}}{{#if report.percent}}%{{/if}} {{else}} - {{number report.currentTotal noTitle="true"}}{{#if report.percent}}%{{/if}} + {{number report.currentTotal ceil=true noTitle="true"}}{{#if report.percent}}%{{/if}} {{/if}} diff --git a/app/assets/javascripts/admin/templates/components/dashboard-table.hbs b/app/assets/javascripts/admin/templates/components/dashboard-table.hbs new file mode 100644 index 0000000000..29ab8332cb --- /dev/null +++ b/app/assets/javascripts/admin/templates/components/dashboard-table.hbs @@ -0,0 +1,36 @@ +{{#conditional-loading-section isLoading=isLoading}} +
+

{{title}}

+
+ + {{#each reportsForPeriod as |report|}} +
+ + + + {{#if report.labels}} + {{#each report.labels as |label|}} + + {{/each}} + {{else}} + {{#each report.data as |data|}} + + {{/each}} + {{/if}} + + + + {{#unless hasBlock}} + {{#each report.data as |data|}} + + + + {{/each}} + {{else}} + {{yield (hash report=report)}} + {{/unless}} + +
{{label}}{{data.x}}
{{number data.y}}
+
+ {{/each}} +{{/conditional-loading-section}} diff --git a/app/assets/javascripts/admin/templates/components/watched-word-form.hbs b/app/assets/javascripts/admin/templates/components/watched-word-form.hbs index 7d2b460aa0..e4b2fab801 100644 --- a/app/assets/javascripts/admin/templates/components/watched-word-form.hbs +++ b/app/assets/javascripts/admin/templates/components/watched-word-form.hbs @@ -2,6 +2,6 @@ {{text-field value=word disabled=formSubmitted class="watched-word-input" autocorrect="off" autocapitalize="off" placeholderKey=placeholderKey}} {{d-button action="submit" disabled=formSubmitted label="admin.watched_words.form.add"}} -{{#if showSuccessMessage}} - {{i18n 'admin.watched_words.form.success'}} +{{#if showMessage}} + {{message}} {{/if}} diff --git a/app/assets/javascripts/admin/templates/customize-themes.hbs b/app/assets/javascripts/admin/templates/customize-themes.hbs index e2f9f8b99a..9164492264 100644 --- a/app/assets/javascripts/admin/templates/customize-themes.hbs +++ b/app/assets/javascripts/admin/templates/customize-themes.hbs @@ -5,6 +5,7 @@ {{#each sortedThemes as |theme|}}
  • {{#link-to 'adminCustomizeThemes.show' theme replace=true}} + {{plugin-outlet name="admin-customize-themes-list-item" connectorTagName='span' args=(hash theme=theme)}} {{theme.name}} {{#if theme.user_selectable}} {{d-icon "user"}} diff --git a/app/assets/javascripts/admin/templates/dashboard_next.hbs b/app/assets/javascripts/admin/templates/dashboard_next.hbs index 8782518248..1608d6238c 100644 --- a/app/assets/javascripts/admin/templates/dashboard_next.hbs +++ b/app/assets/javascripts/admin/templates/dashboard_next.hbs @@ -53,7 +53,7 @@
    -
    +
    {{#conditional-loading-section isLoading=isLoading title=(i18n "admin.dashboard.activity_metrics")}}

    {{i18n "admin.dashboard.activity_metrics"}}

    @@ -79,19 +79,11 @@
    {{/conditional-loading-section}}
    +
    + {{dashboard-inline-table dataSourceNames="users_by_type" lastRefreshedAt=lastRefreshedAt}} - {{#dashboard-inline-table dataSourceNames="users_by_type,users_by_trust_level" lastRefreshedAt=lastRefreshedAt as |context|}} - - {{#each context.report.data as |data|}} - - - {{number data.y}} - - - {{/each}} - - {{/dashboard-inline-table}} - + {{dashboard-inline-table dataSourceNames="users_by_trust_level" lastRefreshedAt=lastRefreshedAt}} +
    {{#conditional-loading-section isLoading=isLoading title=(i18n "admin.dashboard.backups")}}
    @@ -116,7 +108,6 @@
    -

    {{i18n "admin.dashboard.last_updated"}}

    @@ -128,58 +119,57 @@
    -

    - {{i18n 'admin.dashboard.find_old'}} {{#link-to 'admin.dashboard'}}{{i18n "admin.dashboard.old_link"}}{{/link-to}} -

    - +

    + {{i18n 'admin.dashboard.find_old'}} {{#link-to 'admin.dashboard'}}{{i18n "admin.dashboard.old_link"}}{{/link-to}} +

    {{/conditional-loading-section}}
    - {{#dashboard-inline-table - dataSourceNames="top_referred_topics" - lastRefreshedAt=lastRefreshedAt - limit=8 - as |context|}} - {{#each context.report.data as |data|}} - - - - {{data.topic_title}} - - - - {{data.num_clicks}} - - - {{/each}} - {{/dashboard-inline-table}} + {{#dashboard-table + dataSourceNames="top_referred_topics" + lastRefreshedAt=lastRefreshedAt + limit=8 + as |context|}} + {{#each context.report.data as |data|}} + + + + {{data.topic_title}} + + + + {{data.num_clicks}} + + + {{/each}} + {{/dashboard-table}}
    +
    diff --git a/app/assets/javascripts/admin/templates/reports.hbs b/app/assets/javascripts/admin/templates/reports.hbs index eab2782425..26b5bfb4fe 100644 --- a/app/assets/javascripts/admin/templates/reports.hbs +++ b/app/assets/javascripts/admin/templates/reports.hbs @@ -4,41 +4,49 @@

    {{model.description}}

    {{/if}} -
    - {{i18n 'admin.dashboard.reports.start_date'}} {{date-picker-past value=startDate defaultDate=startDate}} - {{i18n 'admin.dashboard.reports.end_date'}} {{date-picker-past value=endDate defaultDate=endDate}} - {{#if showCategoryOptions}} - {{combo-box filterable=true valueAttribute="value" content=categoryOptions value=categoryId}} - {{/if}} - {{#if showGroupOptions}} - {{combo-box filterable=true 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"}} +
    +
    + {{#conditional-loading-spinner condition=refreshing}} +
    + {{#if viewingTable}} + {{i18n 'admin.dashboard.reports.view_table'}} + {{else}} + {{i18n 'admin.dashboard.reports.view_table'}} + {{/if}} + | + {{#if viewingGraph}} + {{i18n 'admin.dashboard.reports.view_graph'}} + {{else}} + {{i18n 'admin.dashboard.reports.view_graph'}} + {{/if}} +
    + + {{#if viewingGraph}} + {{admin-graph model=model}} + {{else}} + {{admin-table-report model=model}} + {{/if}} + + {{#if model.relatedReport}} + {{admin-table-report model=model.relatedReport}} + {{/if}} + {{/conditional-loading-spinner}} +
    + +
    + + {{i18n 'admin.dashboard.reports.start_date'}} {{date-picker-past value=startDate defaultDate=startDate}} + + + {{i18n 'admin.dashboard.reports.end_date'}} {{date-picker-past value=endDate defaultDate=endDate}} + + {{#if showCategoryOptions}} + {{combo-box filterable=true valueAttribute="value" content=categoryOptions value=categoryId}} + {{/if}} + {{#if showGroupOptions}} + {{combo-box filterable=true 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"}} +
    - -
    - {{#if viewingTable}} - {{i18n 'admin.dashboard.reports.view_table'}} - {{else}} - {{i18n 'admin.dashboard.reports.view_table'}} - {{/if}} - | - {{#if viewingGraph}} - {{i18n 'admin.dashboard.reports.view_graph'}} - {{else}} - {{i18n 'admin.dashboard.reports.view_graph'}} - {{/if}} -
    - -{{#conditional-loading-spinner condition=refreshing}} - {{#if viewingGraph}} - {{admin-graph model=model}} - {{else}} - {{admin-table-report model=model}} - {{/if}} - - {{#if model.relatedReport}} - {{admin-table-report model=model.relatedReport}} - {{/if}} -{{/conditional-loading-spinner}} diff --git a/app/assets/javascripts/admin/templates/user-index.hbs b/app/assets/javascripts/admin/templates/user-index.hbs index 4ab9ea859a..e36f7cd4b5 100644 --- a/app/assets/javascripts/admin/templates/user-index.hbs +++ b/app/assets/javascripts/admin/templates/user-index.hbs @@ -318,18 +318,18 @@
  • -
    -
    {{i18n 'admin.user.suspended'}}
    -
    - {{i18n-yes-no model.isSuspended}} - {{#if model.isSuspended}} - {{#unless model.suspendedForever}} - {{i18n "admin.user.suspended_until" until=model.suspendedTillDate}} - {{/unless}} - {{/if}} -
    -
    - {{#if model.isSuspended}} +
    +
    {{i18n 'admin.user.suspended'}}
    +
    + {{i18n-yes-no model.suspended}} + {{#if model.suspended}} + {{#unless model.suspendedForever}} + {{i18n "admin.user.suspended_until" until=model.suspendedTillDate}} + {{/unless}} + {{/if}} +
    +
    + {{#if model.suspended}} {{d-button class="btn-danger unsuspend-user" action=(action "unsuspend") @@ -349,7 +349,7 @@
    - {{#if model.isSuspended}} + {{#if model.suspended}}
    {{i18n 'admin.user.suspended_by'}}
    @@ -367,7 +367,7 @@
    {{i18n 'admin.user.silenced'}}
    {{i18n-yes-no model.silenced}} - {{#if model.isSilenced}} + {{#if model.silenced}} {{#unless model.silencedForever}} {{i18n "admin.user.suspended_until" until=model.silencedTillDate}} {{/unless}} @@ -394,7 +394,7 @@
    - {{#if model.isSilenced}} + {{#if model.silenced}}
    {{i18n 'admin.user.silenced_by'}}
    @@ -408,6 +408,21 @@
    {{/if}} + {{#if model.tl3_requirements.penalty_counts.total}} +
    +
    {{i18n 'admin.user.penalty_count'}}
    +
    {{model.tl3_requirements.penalty_counts.total}}
    + {{#if currentUser.admin}} +
    + {{d-button label="admin.user.clear_penalty_history.title" + icon="times" + action=(action "clearPenaltyHistory")}} + {{i18n "admin.user.clear_penalty_history.description"}} +
    + {{/if}} +
    + {{/if}} + {{#if currentUser.admin}} @@ -468,7 +483,7 @@ {{d-button class="btn-danger" action="deleteAllPosts" icon="trash-o" label="admin.user.delete_all_posts"}} {{/if}} {{else}} - {{model.deleteAllPostsExplanation}} + {{deleteAllPostsExplanation}} {{/if}}
    @@ -549,28 +564,26 @@ {{/if}} {{/if}} - {{#unless model.anonymizeForbidden}} + {{#if model.can_be_anonymized}} {{d-button label="admin.user.anonymize" icon="exclamation-triangle" class="btn-danger" - disabled=model.anonymizeForbidden action="anonymize"}} - {{/unless}} + {{/if}} - {{#unless model.deleteForbidden}} + {{#if model.canBeDeleted}} {{d-button label="admin.user.delete" icon="exclamation-triangle" class="btn-danger" - disabled=model.deleteForbidden action="destroy"}} - {{/unless}} + {{/if}}
    - {{#if model.deleteExplanation}} + {{#if deleteExplanation}}

    - {{d-icon "exclamation-triangle"}} {{model.deleteExplanation}} + {{d-icon "exclamation-triangle"}} {{deleteExplanation}}
    {{/if}} diff --git a/app/assets/javascripts/admin/templates/watched-words-action.hbs b/app/assets/javascripts/admin/templates/watched-words-action.hbs index ac0bc4175b..1cf0f77cd9 100644 --- a/app/assets/javascripts/admin/templates/watched-words-action.hbs +++ b/app/assets/javascripts/admin/templates/watched-words-action.hbs @@ -5,6 +5,7 @@ {{watched-word-form actionKey=actionNameKey action="recordAdded" + filteredContent=filteredContent regularExpressions=adminWatchedWords.regularExpressions}} {{watched-word-uploader uploading=uploading actionKey=actionNameKey done="uploadComplete"}} diff --git a/app/assets/javascripts/admin/templates/watched-words.hbs b/app/assets/javascripts/admin/templates/watched-words.hbs index dccbdb29cc..cf5f50cc64 100644 --- a/app/assets/javascripts/admin/templates/watched-words.hbs +++ b/app/assets/javascripts/admin/templates/watched-words.hbs @@ -1,5 +1,6 @@
    + {{d-button action="toggleMenu" class="menu-toggle" icon="bars"}} {{text-field value=filter placeholderKey="admin.watched_words.search" class="no-blur"}} {{d-button action="clearFilter" label="admin.watched_words.clear_filter"}}
    diff --git a/app/assets/javascripts/discourse/components/d-modal-body.js.es6 b/app/assets/javascripts/discourse/components/d-modal-body.js.es6 index 8de322600d..04c9754dd8 100644 --- a/app/assets/javascripts/discourse/components/d-modal-body.js.es6 +++ b/app/assets/javascripts/discourse/components/d-modal-body.js.es6 @@ -42,7 +42,9 @@ export default Ember.Component.extend({ this.getProperties( 'title', 'rawTitle', - 'fixed' + 'fixed', + 'subtitle', + 'rawSubtitle' ) ); }, diff --git a/app/assets/javascripts/discourse/components/d-modal.js.es6 b/app/assets/javascripts/discourse/components/d-modal.js.es6 index c015ca6ba5..a57f4daea0 100644 --- a/app/assets/javascripts/discourse/components/d-modal.js.es6 +++ b/app/assets/javascripts/discourse/components/d-modal.js.es6 @@ -28,6 +28,7 @@ export default Ember.Component.extend({ this.appEvents.on('modal:body-shown', data => { if (this.isDestroying || this.isDestroyed) { return; } + if (data.fixed) { this.$().removeClass('hidden'); } @@ -37,6 +38,16 @@ export default Ember.Component.extend({ } else if (data.rawTitle) { this.set('title', data.rawTitle); } + + if (data.subtitle) { + this.set('subtitle', I18n.t(data.subtitle)); + } else if (data.rawSubtitle) { + this.set('subtitle', data.rawSubtitle); + } else { + // if no subtitle provided, makes sure the previous subtitle + // of another modal is not used + this.set('subtitle', null); + } }); }, diff --git a/app/assets/javascripts/discourse/components/discourse-linked-text.js.es6 b/app/assets/javascripts/discourse/components/discourse-linked-text.js.es6 new file mode 100644 index 0000000000..44e8bf9e59 --- /dev/null +++ b/app/assets/javascripts/discourse/components/discourse-linked-text.js.es6 @@ -0,0 +1,18 @@ +import { default as computed } from 'ember-addons/ember-computed-decorators'; + +export default Ember.Component.extend({ + tagName: 'span', + + @computed("text") + translatedText(text) { + if (text) return I18n.t(text); + }, + + click(event) { + if (event.target.tagName.toUpperCase() === 'A') { + this.sendAction("action", this.get("actionParam")); + } + + return false; + } +}); diff --git a/app/assets/javascripts/discourse/components/edit-topic-timer-form.js.es6 b/app/assets/javascripts/discourse/components/edit-topic-timer-form.js.es6 index 421972b834..4b853e541d 100644 --- a/app/assets/javascripts/discourse/components/edit-topic-timer-form.js.es6 +++ b/app/assets/javascripts/discourse/components/edit-topic-timer-form.js.es6 @@ -46,5 +46,12 @@ export default Ember.Component.extend({ } this.set("topicTimer.updateTime", time); - } + }, + + @observes("selection") + _updateBasedOnLastPost() { + if (!this.get('autoClose')) { + this.set('topicTimer.based_on_last_post', false); + } + }, }); diff --git a/app/assets/javascripts/discourse/components/quote-button.js.es6 b/app/assets/javascripts/discourse/components/quote-button.js.es6 index 5d41b049cc..49ee520e95 100644 --- a/app/assets/javascripts/discourse/components/quote-button.js.es6 +++ b/app/assets/javascripts/discourse/components/quote-button.js.es6 @@ -78,7 +78,10 @@ export default Ember.Component.extend({ const $quoteButton = this.$(); // remove the marker - markerElement.parentNode.removeChild(markerElement); + const parent = markerElement.parentNode; + parent.removeChild(markerElement); + // merge back all text nodes so they don't get messed up + parent.normalize(); // work around Safari that would sometimes lose the selection if (isSafari) { diff --git a/app/assets/javascripts/discourse/components/search-advanced-options.js.es6 b/app/assets/javascripts/discourse/components/search-advanced-options.js.es6 index a171083523..22976d76d3 100644 --- a/app/assets/javascripts/discourse/components/search-advanced-options.js.es6 +++ b/app/assets/javascripts/discourse/components/search-advanced-options.js.es6 @@ -18,6 +18,7 @@ const REGEXP_TAGS_REPLACE = /(^(tags?:|#(?=[a-z0-9\-]+::tag))|::tag\s?$ const REGEXP_IN_MATCH = /^(in|with):(posted|watching|tracking|bookmarks|first|pinned|unpinned|wiki|unseen|image)/ig; const REGEXP_SPECIAL_IN_LIKES_MATCH = /^in:likes/ig; +const REGEXP_SPECIAL_IN_TITLE_MATCH = /^in:title/ig; const REGEXP_SPECIAL_IN_PRIVATE_MATCH = /^in:private/ig; const REGEXP_SPECIAL_IN_SEEN_MATCH = /^in:seen/ig; @@ -81,6 +82,7 @@ export default Em.Component.extend({ in: '', special: { in: { + title: false, likes: false, private: false, seen: false @@ -111,6 +113,7 @@ export default Em.Component.extend({ this.setSearchedTermValueForTags(); this.setSearchedTermValue('searchedTerms.in', REGEXP_IN_PREFIX, REGEXP_IN_MATCH); this.setSearchedTermSpecialInValue('searchedTerms.special.in.likes', REGEXP_SPECIAL_IN_LIKES_MATCH); + this.setSearchedTermSpecialInValue('searchedTerms.special.in.title', REGEXP_SPECIAL_IN_TITLE_MATCH); this.setSearchedTermSpecialInValue('searchedTerms.special.in.private', REGEXP_SPECIAL_IN_PRIVATE_MATCH); this.setSearchedTermSpecialInValue('searchedTerms.special.in.seen', REGEXP_SPECIAL_IN_SEEN_MATCH); this.setSearchedTermValue('searchedTerms.status', REGEXP_STATUS_PREFIX); @@ -424,15 +427,14 @@ export default Em.Component.extend({ } }, - @observes('searchedTerms.special.in.likes') - updateSearchTermForSpecialInLikes() { - const match = this.filterBlocks(REGEXP_SPECIAL_IN_LIKES_MATCH); - const inFilter = this.get('searchedTerms.special.in.likes'); + updateInRegex(regex, filter) { + const match = this.filterBlocks(regex); + const inFilter = this.get('searchedTerms.special.in.' + filter); let searchTerm = this.get('searchTerm') || ''; if (inFilter) { if (match.length === 0) { - searchTerm += ` in:likes`; + searchTerm += ` in:${filter}`; this.set('searchTerm', searchTerm.trim()); } } else if (match.length !== 0) { @@ -441,38 +443,24 @@ export default Em.Component.extend({ } }, + @observes('searchedTerms.special.in.likes') + updateSearchTermForSpecialInLikes() { + this.updateInRegex(REGEXP_SPECIAL_IN_LIKES_MATCH, 'likes'); + }, + @observes('searchedTerms.special.in.private') updateSearchTermForSpecialInPrivate() { - const match = this.filterBlocks(REGEXP_SPECIAL_IN_PRIVATE_MATCH); - const inFilter = this.get('searchedTerms.special.in.private'); - let searchTerm = this.get('searchTerm') || ''; - - if (inFilter) { - if (match.length === 0) { - searchTerm += ` in:private`; - this.set('searchTerm', searchTerm.trim()); - } - } else if (match.length !== 0) { - searchTerm = searchTerm.replace(match, ''); - this.set('searchTerm', searchTerm.trim()); - } + this.updateInRegex(REGEXP_SPECIAL_IN_PRIVATE_MATCH, 'private'); }, @observes('searchedTerms.special.in.seen') updateSearchTermForSpecialInSeen() { - const match = this.filterBlocks(REGEXP_SPECIAL_IN_SEEN_MATCH); - const inFilter = this.get('searchedTerms.special.in.seen'); - let searchTerm = this.get('searchTerm') || ''; + this.updateInRegex(REGEXP_SPECIAL_IN_SEEN_MATCH, 'seen'); + }, - if (inFilter) { - if (match.length === 0) { - searchTerm += ` in:seen`; - this.set('searchTerm', searchTerm.trim()); - } - } else if (match.length !== 0) { - searchTerm = searchTerm.replace(match, ''); - this.set('searchTerm', searchTerm.trim()); - } + @observes('searchedTerms.special.in.title') + updateSearchTermForSpecialInTitle() { + this.updateInRegex(REGEXP_SPECIAL_IN_TITLE_MATCH, 'title'); }, @observes('searchedTerms.status') diff --git a/app/assets/javascripts/discourse/components/site-header.js.es6 b/app/assets/javascripts/discourse/components/site-header.js.es6 index 458e45c93d..ac19edd63d 100644 --- a/app/assets/javascripts/discourse/components/site-header.js.es6 +++ b/app/assets/javascripts/discourse/components/site-header.js.es6 @@ -16,7 +16,7 @@ const SiteHeaderComponent = MountWidget.extend(Docking, { _topic: null, @observes('currentUser.unread_notifications', 'currentUser.unread_private_messages') - _notificationsChanged() { + notificationsChanged() { this.queueRerender(); }, diff --git a/app/assets/javascripts/discourse/components/topic-timer-info.js.es6 b/app/assets/javascripts/discourse/components/topic-timer-info.js.es6 index 98c9ad1c30..e0e8fb9142 100644 --- a/app/assets/javascripts/discourse/components/topic-timer-info.js.es6 +++ b/app/assets/javascripts/discourse/components/topic-timer-info.js.es6 @@ -18,7 +18,6 @@ export default Ember.Component.extend(bufferedRender({ if (!this.get('executeAt')) return; let statusUpdateAt = moment(this.get('executeAt')); - if (statusUpdateAt < new Date()) return; let duration = moment.duration(statusUpdateAt - moment()); let minutesLeft = duration.asMinutes(); diff --git a/app/assets/javascripts/discourse/components/user-card-contents.js.es6 b/app/assets/javascripts/discourse/components/user-card-contents.js.es6 index 140b69a1b5..d75bab921a 100644 --- a/app/assets/javascripts/discourse/components/user-card-contents.js.es6 +++ b/app/assets/javascripts/discourse/components/user-card-contents.js.es6 @@ -18,7 +18,6 @@ export default Ember.Component.extend(CardContentsBase, CanCheckEmails, CleansUp showFilter: Ember.computed.and('viewingTopic', 'postStream.hasNoFilters', 'enoughPostsForFiltering'), showName: propertyNotEqual('user.name', 'user.username'), hasUserFilters: Ember.computed.gt('postStream.userFilters.length', 0), - isSuspended: Ember.computed.notEmpty('user.suspend_reason'), showMoreBadges: Ember.computed.gt('moreBadgesCount', 0), showDelete: Ember.computed.and("viewingAdmin", "showName", "user.canBeDeleted"), linkWebsite: Ember.computed.not('user.isBasic'), diff --git a/app/assets/javascripts/discourse/components/user-stream-item.js.es6 b/app/assets/javascripts/discourse/components/user-stream-item.js.es6 index 103f450b24..b239613c47 100644 --- a/app/assets/javascripts/discourse/components/user-stream-item.js.es6 +++ b/app/assets/javascripts/discourse/components/user-stream-item.js.es6 @@ -11,5 +11,5 @@ export default Ember.Component.extend({ ], moderatorAction: propertyEqual("item.post_type", "site.post_types.moderator_action"), - actionDescription: actionDescription("item.action_code", "item.created_at", "item.username"), + actionDescription: actionDescription("item.action_code", "item.created_at", "item.action_code_who"), }); diff --git a/app/assets/javascripts/discourse/controllers/full-page-search.js.es6 b/app/assets/javascripts/discourse/controllers/full-page-search.js.es6 index 0273b7eaca..5534be1f99 100644 --- a/app/assets/javascripts/discourse/controllers/full-page-search.js.es6 +++ b/app/assets/javascripts/discourse/controllers/full-page-search.js.es6 @@ -146,6 +146,11 @@ export default Ember.Controller.extend({ } }, + @computed('q') + isPrivateMessage(q) { + return q && this.currentUser && (q.indexOf("in:private") > -1 || q.indexOf(`private_messages:${this.currentUser.get('username_lower')}`) > -1); + }, + @observes('loading') _showFooter() { this.set("application.showFooter", !this.get("loading")); diff --git a/app/assets/javascripts/discourse/controllers/preferences/account.js.es6 b/app/assets/javascripts/discourse/controllers/preferences/account.js.es6 index e370efdfaf..40befe7218 100644 --- a/app/assets/javascripts/discourse/controllers/preferences/account.js.es6 +++ b/app/assets/javascripts/discourse/controllers/preferences/account.js.es6 @@ -4,6 +4,7 @@ import { default as computed } from "ember-addons/ember-computed-decorators"; import PreferencesTabController from "discourse/mixins/preferences-tab-controller"; import { setting } from 'discourse/lib/computed'; import { popupAjaxError } from 'discourse/lib/ajax-error'; +import showModal from 'discourse/lib/show-modal'; export default Ember.Controller.extend(CanCheckEmails, PreferencesTabController, { @@ -41,11 +42,6 @@ export default Ember.Controller.extend(CanCheckEmails, PreferencesTabController, return !this.siteSettings.enable_sso && this.siteSettings.enable_local_logins; }, - @computed - showTwoFactorModalText() { - return I18n.t('user.second_factor.title').toLowerCase(); - }, - actions: { save() { this.set('saved', false); @@ -105,6 +101,10 @@ export default Ember.Controller.extend(CanCheckEmails, PreferencesTabController, } ]; bootbox.dialog(message, buttons, {"classes": "delete-account"}); + }, + + showTwoFactorModal() { + showModal('second-factor-intro'); } } }); diff --git a/app/assets/javascripts/discourse/controllers/topic.js.es6 b/app/assets/javascripts/discourse/controllers/topic.js.es6 index 46448d8447..9a464c463c 100644 --- a/app/assets/javascripts/discourse/controllers/topic.js.es6 +++ b/app/assets/javascripts/discourse/controllers/topic.js.es6 @@ -14,6 +14,20 @@ import { popupAjaxError } from 'discourse/lib/ajax-error'; import { spinnerHTML } from 'discourse/helpers/loading-spinner'; import { userPath } from 'discourse/lib/url'; +let customPostMessageCallbacks = {}; + +export function resetCustomPostMessageCallbacks() { + customPostMessageCallbacks = {}; +} + +export function registerCustomPostMessageCallback(type, callback) { + if (customPostMessageCallbacks[type]) { + throw `Error ${type} is an already registered post message!`; + } + + customPostMessageCallbacks[type] = callback; +} + export default Ember.Controller.extend(BufferedContent, { composer: Ember.inject.controller(), application: Ember.inject.controller(), @@ -935,7 +949,12 @@ export default Ember.Controller.extend(BufferedContent, { break; } default: { - Em.Logger.warn("unknown topic bus message type", data); + let callback = customPostMessageCallbacks[data.type]; + if (callback) { + callback(this, data); + } else { + Em.Logger.warn("unknown topic bus message type", data); + } } } diff --git a/app/assets/javascripts/discourse/controllers/user.js.es6 b/app/assets/javascripts/discourse/controllers/user.js.es6 index ecde47f23b..afa3231413 100644 --- a/app/assets/javascripts/discourse/controllers/user.js.es6 +++ b/app/assets/javascripts/discourse/controllers/user.js.es6 @@ -39,9 +39,9 @@ export default Ember.Controller.extend(CanCheckEmails, { showStaffCounters: Ember.computed.or('hasGivenFlags', 'hasFlaggedPosts', 'hasDeletedPosts', 'hasBeenSuspended', 'hasReceivedWarnings'), - @computed('model.isSuspended', 'currentUser.staff') - isNotSuspendedOrIsStaff(isSuspended, isStaff) { - return !isSuspended || isStaff; + @computed('model.suspended', 'currentUser.staff') + isNotSuspendedOrIsStaff(suspended, isStaff) { + return !suspended || isStaff; }, linkWebsite: Em.computed.not('model.isBasic'), diff --git a/app/assets/javascripts/discourse/helpers/application.js.es6 b/app/assets/javascripts/discourse/helpers/application.js.es6 index 5686e07d6b..d43c1a7791 100644 --- a/app/assets/javascripts/discourse/helpers/application.js.es6 +++ b/app/assets/javascripts/discourse/helpers/application.js.es6 @@ -8,6 +8,10 @@ registerUnbound('raw-date', dt => longDate(new Date(dt))); registerUnbound('age-with-tooltip', dt => new safe(autoUpdatingRelativeAge(new Date(dt), {title: true}))); registerUnbound('number', (orig, params) => { + if (params.ceil) { + orig = Math.ceil(orig); + } + orig = parseInt(orig, 10); if (isNaN(orig)) { orig = 0; } diff --git a/app/assets/javascripts/discourse/initializers/register-service-worker.js.es6 b/app/assets/javascripts/discourse/initializers/register-service-worker.js.es6 index bb1bff2b7c..8632ced10e 100644 --- a/app/assets/javascripts/discourse/initializers/register-service-worker.js.es6 +++ b/app/assets/javascripts/discourse/initializers/register-service-worker.js.es6 @@ -6,9 +6,10 @@ export default { (location.hostname === "localhost"); const isSupported= isSecured && ('serviceWorker' in navigator); + const isSafari = /^((?!chrome|android).)*safari/i.test(navigator.userAgent); if (isSupported) { - if (Discourse.ServiceWorkerURL) { + if (Discourse.ServiceWorkerURL && !isSafari) { navigator.serviceWorker .register(`${Discourse.BaseUri}/${Discourse.ServiceWorkerURL}`) .catch(error => { diff --git a/app/assets/javascripts/discourse/initializers/subscribe-user-notifications.js.es6 b/app/assets/javascripts/discourse/initializers/subscribe-user-notifications.js.es6 index fd2c8ff418..75fe71d1d7 100644 --- a/app/assets/javascripts/discourse/initializers/subscribe-user-notifications.js.es6 +++ b/app/assets/javascripts/discourse/initializers/subscribe-user-notifications.js.es6 @@ -35,7 +35,6 @@ export default { bus.subscribe(`/notification/${user.get('id')}`, data => { const store = container.lookup('service:store'); - const oldUnread = user.get('unread_notifications'); const oldPM = user.get('unread_private_messages'); @@ -66,7 +65,7 @@ export default { oldNotifications.insertAt(insertPosition, Em.Object.create(lastNotification)); } - for (let idx=0; idx < data.recent.length; idx++) { + for (let idx = 0; idx < data.recent.length; idx++) { let old; while(old = oldNotifications[idx]) { const info = data.recent[idx]; @@ -96,21 +95,16 @@ export default { }); bus.subscribe("/client_settings", data => Ember.set(siteSettings, data.name, data.value)); - - bus.subscribe("/refresh_client", data => { - Discourse.set("assetVersion", data); - }); + bus.subscribe("/refresh_client", data => Discourse.set("assetVersion", data)); if (!Ember.testing) { - bus.subscribe(alertChannel(user), data => onNotification(data, user)); initDesktopNotifications(bus, appEvents); - if(isPushNotificationsEnabled(user, site.mobileView)) { + if (isPushNotificationsEnabled(user, site.mobileView)) { disableDesktopNotifications(); registerPushNotifications(Discourse.User.current(), site.mobileView, router, appEvents); - } - else { + } else { unsubscribePushNotifications(user); } } diff --git a/app/assets/javascripts/discourse/lib/formatter.js.es6 b/app/assets/javascripts/discourse/lib/formatter.js.es6 index 76e2ab44eb..3eed7e3d97 100644 --- a/app/assets/javascripts/discourse/lib/formatter.js.es6 +++ b/app/assets/javascripts/discourse/lib/formatter.js.es6 @@ -301,9 +301,13 @@ export function relativeAge(date, options) { return "UNKNOWN FORMAT"; } -export function number(val) { +export function number(val, options = {}) { let formattedNumber; + if (options.ceil) { + val = Math.ceil(val); + } + val = parseInt(val, 10); if (isNaN(val)) val = 0; diff --git a/app/assets/javascripts/discourse/lib/plugin-api.js.es6 b/app/assets/javascripts/discourse/lib/plugin-api.js.es6 index ce78480770..3222c2ddd2 100644 --- a/app/assets/javascripts/discourse/lib/plugin-api.js.es6 +++ b/app/assets/javascripts/discourse/lib/plugin-api.js.es6 @@ -25,9 +25,10 @@ import { modifySelectKit } from "select-kit/mixins/plugin-api"; import { addGTMPageChangedCallback } from 'discourse/lib/page-tracker'; import { registerCustomAvatarHelper } from 'discourse/helpers/user-avatar'; import { disableNameSuppression } from 'discourse/widgets/poster-name'; +import { registerCustomPostMessageCallback as registerCustomPostMessageCallback1 } from 'discourse/controllers/topic'; // If you add any methods to the API ensure you bump up this number -const PLUGIN_API_VERSION = '0.8.21'; +const PLUGIN_API_VERSION = '0.8.22'; class PluginApi { constructor(version, container) { @@ -426,6 +427,24 @@ class PluginApi { disableNameSuppression(); } + /** + * Registers a callback that will be invoked when the server calls + * Post#publish_change_to_clients! please ensure your type does not + * match acted,revised,rebaked,recovered, created,move_to_inbox or archived + * + * callback will be called with topicController and Message + * + * Example: + * + * api.registerCustomPostMessageCallback("applied_color", (topicController, message) => { + * let stream = topicController.get("model.postStream"); + * // etc + * }); + */ + registerCustomPostMessageCallback(type, callback) { + registerCustomPostMessageCallback1(type, callback); + } + /** * Changes a setting associated with a widget. For example, if * you wanted small avatars in the post stream: diff --git a/app/assets/javascripts/discourse/models/user.js.es6 b/app/assets/javascripts/discourse/models/user.js.es6 index 19e3ebcd14..a76f17be96 100644 --- a/app/assets/javascripts/discourse/models/user.js.es6 +++ b/app/assets/javascripts/discourse/models/user.js.es6 @@ -169,8 +169,6 @@ const User = RestModel.extend({ isElder: Em.computed.equal('trust_level', 4), canManageTopic: Em.computed.or('staff', 'isElder'), - isSuspended: Em.computed.equal('suspended', true), - @computed("previous_visit_at") previousVisitAt(previous_visit_at) { return new Date(previous_visit_at); diff --git a/app/assets/javascripts/discourse/routes/new-message.js.es6 b/app/assets/javascripts/discourse/routes/new-message.js.es6 index bbae55b1ac..d3ea4fde43 100644 --- a/app/assets/javascripts/discourse/routes/new-message.js.es6 +++ b/app/assets/javascripts/discourse/routes/new-message.js.es6 @@ -6,6 +6,7 @@ export default Discourse.Route.extend({ beforeModel(transition) { const self = this; const params = transition.queryParams; + const groupName = params.groupname || params.group_name; if (self.currentUser) { self.replaceWith("discovery.latest").then(e => { @@ -20,13 +21,13 @@ export default Discourse.Route.extend({ }).catch(function() { bootbox.alert(I18n.t("generic_error")); }); - } else if (params.groupname) { + } else if (groupName) { // send a message to a group - Group.messageable(params.groupname).then(result => { + Group.messageable(groupName).then(result => { if (result.messageable) { - Ember.run.next(() => e.send("createNewMessageViaParams", params.groupname, params.title, params.body)); + Ember.run.next(() => e.send("createNewMessageViaParams", groupName, params.title, params.body)); } else { - bootbox.alert(I18n.t("composer.cant_send_pm", { username: params.groupname })); + bootbox.alert(I18n.t("composer.cant_send_pm", { username: groupName })); } }).catch(function() { bootbox.alert(I18n.t("generic_error")); diff --git a/app/assets/javascripts/discourse/routes/preferences.js.es6 b/app/assets/javascripts/discourse/routes/preferences.js.es6 index 128a301731..1eb3d4b3e1 100644 --- a/app/assets/javascripts/discourse/routes/preferences.js.es6 +++ b/app/assets/javascripts/discourse/routes/preferences.js.es6 @@ -15,10 +15,6 @@ export default RestrictedUserRoute.extend({ }, actions: { - showTwoFactorModal() { - showModal('second-factor-intro'); - }, - showAvatarSelector() { showModal('avatar-selector'); diff --git a/app/assets/javascripts/discourse/templates/components/bread-crumbs.hbs b/app/assets/javascripts/discourse/templates/components/bread-crumbs.hbs index ce6613330e..e46d6c32e1 100644 --- a/app/assets/javascripts/discourse/templates/components/bread-crumbs.hbs +++ b/app/assets/javascripts/discourse/templates/components/bread-crumbs.hbs @@ -7,7 +7,7 @@ category=secondCategory parentCategory=firstCategory categories=childCategories - subCategory="true" + subCategory=true noSubcategories=noSubcategories}} {{/if}} diff --git a/app/assets/javascripts/discourse/templates/components/d-modal.hbs b/app/assets/javascripts/discourse/templates/components/d-modal.hbs index 8ed28a6a0e..852b29f884 100644 --- a/app/assets/javascripts/discourse/templates/components/d-modal.hbs +++ b/app/assets/javascripts/discourse/templates/components/d-modal.hbs @@ -6,7 +6,13 @@ {{d-icon "times"}}
    -

    {{title}}

    +
    +

    {{title}}

    + + {{#if subtitle}} +

    {{subtitle}}

    + {{/if}} +
    diff --git a/app/assets/javascripts/discourse/templates/components/discourse-linked-text.hbs b/app/assets/javascripts/discourse/templates/components/discourse-linked-text.hbs new file mode 100644 index 0000000000..dd15a6dc6a --- /dev/null +++ b/app/assets/javascripts/discourse/templates/components/discourse-linked-text.hbs @@ -0,0 +1 @@ +{{{translatedText}}} diff --git a/app/assets/javascripts/discourse/templates/components/edit-category-settings.hbs b/app/assets/javascripts/discourse/templates/components/edit-category-settings.hbs index 2e657aa156..36e6bfc0b4 100644 --- a/app/assets/javascripts/discourse/templates/components/edit-category-settings.hbs +++ b/app/assets/javascripts/discourse/templates/components/edit-category-settings.hbs @@ -69,7 +69,7 @@
    {{combo-box valueAttribute="value" content=availableSorts value=category.sort_order none="category.sort_options.default"}} {{#unless isDefaultSortOrder}} - {{combo-box valueAttribute="value" content=sortAscendingOptions value=category.sort_ascending none="category.sort_options.default"}} + {{combo-box castBoolean=true valueAttribute="value" content=sortAscendingOptions value=category.sort_ascending none="category.sort_options.default"}} {{/unless}}
    diff --git a/app/assets/javascripts/discourse/templates/components/edit-topic-timer-form.hbs b/app/assets/javascripts/discourse/templates/components/edit-topic-timer-form.hbs index f90534931b..52f618fec9 100644 --- a/app/assets/javascripts/discourse/templates/components/edit-topic-timer-form.hbs +++ b/app/assets/javascripts/discourse/templates/components/edit-topic-timer-form.hbs @@ -9,7 +9,7 @@ input=topicTimer.updateTime statusType=selection includeWeekend=true - basedOnLastPost=false}} + basedOnLastPost=topicTimer.based_on_last_post}} {{else if publishToCategory}}
    @@ -23,7 +23,7 @@ statusType=selection includeWeekend=true categoryId=topicTimer.category_id - basedOnLastPost=false}} + basedOnLastPost=topicTimer.based_on_last_post}} {{else if autoClose}} {{future-date-input input=topicTimer.updateTime diff --git a/app/assets/javascripts/discourse/templates/components/search-advanced-options.hbs b/app/assets/javascripts/discourse/templates/components/search-advanced-options.hbs index 3ce9b3d84f..371a1c3849 100644 --- a/app/assets/javascripts/discourse/templates/components/search-advanced-options.hbs +++ b/app/assets/javascripts/discourse/templates/components/search-advanced-options.hbs @@ -60,6 +60,7 @@
    {{#if currentUser}}
    + diff --git a/app/assets/javascripts/discourse/templates/components/user-card-contents.hbs b/app/assets/javascripts/discourse/templates/components/user-card-contents.hbs index 66275c6634..59c1891fb1 100644 --- a/app/assets/javascripts/discourse/templates/components/user-card-contents.hbs +++ b/app/assets/javascripts/discourse/templates/components/user-card-contents.hbs @@ -84,7 +84,7 @@ args=(hash user=user close=(action "close")) tagName=""}} - {{#if isSuspended}} + {{#if user.suspend_reason}}
    {{d-icon "ban"}} {{i18n 'user.suspended_notice' date=user.suspendedTillDate}}
    diff --git a/app/assets/javascripts/discourse/templates/full-page-search.hbs b/app/assets/javascripts/discourse/templates/full-page-search.hbs index 68d2869183..346b383664 100644 --- a/app/assets/javascripts/discourse/templates/full-page-search.hbs +++ b/app/assets/javascripts/discourse/templates/full-page-search.hbs @@ -85,7 +85,7 @@ {{/if}} {{category-link result.topic.category hideParent=true}} {{#each result.topic.tags as |tag|}} - {{discourse-tag tag}} + {{discourse-tag tag isPrivateMessage=isPrivateMessage}} {{/each}} {{plugin-outlet name="full-page-search-category" args=(hash result=result)}}
    diff --git a/app/assets/javascripts/discourse/templates/group-activity-posts.hbs b/app/assets/javascripts/discourse/templates/group-activity-posts.hbs index 8aea9bf7c4..7599c31cf2 100644 --- a/app/assets/javascripts/discourse/templates/group-activity-posts.hbs +++ b/app/assets/javascripts/discourse/templates/group-activity-posts.hbs @@ -1,11 +1,10 @@ {{#load-more selector=".user-stream-item" action="loadMore"}}
    - {{#each model as |post|}} - {{group-post post=post class="user-stream-item item"}} - {{else}} -
    {{i18n emptyText}}
    - {{/each}} + {{#each model as |post|}} + {{group-post post=post class="user-stream-item item"}} + {{else}} +
    {{i18n emptyText}}
    + {{/each}}
    {{conditional-loading-spinner condition=loading}} {{/load-more}} - diff --git a/app/assets/javascripts/discourse/templates/group-index.hbs b/app/assets/javascripts/discourse/templates/group-index.hbs index 1d9caddcd8..d5a880b8be 100644 --- a/app/assets/javascripts/discourse/templates/group-index.hbs +++ b/app/assets/javascripts/discourse/templates/group-index.hbs @@ -1,9 +1,7 @@
    - {{#if hasMembers}} {{text-field value=filterInput placeholderKey=filterPlaceholder class="group-username-filter no-blur"}} - {{/if}}
    {{#if canManageGroup}} diff --git a/app/assets/javascripts/discourse/templates/groups/index.hbs b/app/assets/javascripts/discourse/templates/groups/index.hbs index 4562d82d43..c9a96ebe04 100644 --- a/app/assets/javascripts/discourse/templates/groups/index.hbs +++ b/app/assets/javascripts/discourse/templates/groups/index.hbs @@ -9,7 +9,7 @@
    {{text-field value=filterInput - placeholderKey="groups.index.all_groups" + placeholderKey="groups.index.all" class="groups-header-filters-name no-blur"}} {{combo-box value=type diff --git a/app/assets/javascripts/discourse/templates/mobile/modal/login.hbs b/app/assets/javascripts/discourse/templates/mobile/modal/login.hbs index 90d322ed68..c98f8badd6 100644 --- a/app/assets/javascripts/discourse/templates/mobile/modal/login.hbs +++ b/app/assets/javascripts/discourse/templates/mobile/modal/login.hbs @@ -14,7 +14,7 @@ @@ -51,8 +51,7 @@ {{/second-factor-form}} {{/if}} - {{authMessage}} -
    {{alert}}
    + {{/d-modal-body}} +
    {{authMessage}}
    +
    {{alert}}
    {{/login-modal}} diff --git a/app/assets/javascripts/discourse/templates/modal.hbs b/app/assets/javascripts/discourse/templates/modal.hbs index 43c4e79f49..953578f6ef 100644 --- a/app/assets/javascripts/discourse/templates/modal.hbs +++ b/app/assets/javascripts/discourse/templates/modal.hbs @@ -1,6 +1,7 @@ {{#d-modal modalClass=modalClass title=title + subtitle=subtitle class="hidden" errors=errors closeModal=(route-action "closeModal")}} diff --git a/app/assets/javascripts/discourse/templates/modal/create-account.hbs b/app/assets/javascripts/discourse/templates/modal/create-account.hbs index 033e31368c..e79b2c7454 100644 --- a/app/assets/javascripts/discourse/templates/modal/create-account.hbs +++ b/app/assets/javascripts/discourse/templates/modal/create-account.hbs @@ -1,13 +1,13 @@ {{#create-account email=accountEmail disabled=submitDisabled action="createAccount"}} - {{#unless complete}} {{#d-modal-body title="create_account.title"}} + {{#unless hasAuthOptions}} {{login-buttons externalLogin="externalLogin"}} {{/unless}} - + {{#if showCreateForm}} -
    +
    - + {{text-field value=loginName type="email" placeholderKey="login.email_placeholder" id="login-account-name" autocorrect="off" autocapitalize="off"}} @@ -32,10 +32,10 @@ {{/if}}
    - + - {{text-field value=loginPassword type="password" id="login-account-password" maxlength="200"}}   + {{text-field value=loginPassword type="password" id="login-account-password" maxlength="200"}}
    @@ -15,12 +15,13 @@ + - + {{input-tip validation=emailValidation}} + {{#if usernameRequired}} @@ -28,11 +29,11 @@ + {{input-tip validation=usernameValidation id="username-validation"}} {{/if}} @@ -43,11 +44,12 @@ + {{input-tip validation=nameValidation}} {{/if}} @@ -63,14 +65,14 @@ + {{input-tip validation=passwordValidation}} @@ -97,6 +99,7 @@ {{/if}} + {{/d-modal-body}} {{#if showCreateForm}} diff --git a/app/assets/javascripts/discourse/templates/modal/login.hbs b/app/assets/javascripts/discourse/templates/modal/login.hbs index 17a38baac9..fe2ec0f575 100644 --- a/app/assets/javascripts/discourse/templates/modal/login.hbs +++ b/app/assets/javascripts/discourse/templates/modal/login.hbs @@ -1,12 +1,5 @@ {{#login-modal screenX=lastX screenY=lastY loginName=loginName loginPassword=loginPassword loginSecondFactor=loginSecondFactor action="login"}} {{#d-modal-body title="login.title" class="login-modal"}} - {{#if showLoginButtons}} - {{login-buttons - canLoginLocalWithEmail=canLoginLocalWithEmail - processingEmailLink=processingEmailLink - emailLogin='emailLogin' - externalLogin='externalLogin'}} - {{/if}} {{#if canLoginLocal}} @@ -30,7 +23,7 @@ - +
    {{input type="email" value=accountEmail id="new-account-email" disabled=emailValidated name="email" autofocus="autofocus"}} -  {{input-tip validation=emailValidation}}
    {{input value=accountUsername id="new-account-username" name="username" maxlength=maxUsernameLength autocomplete="off"}} -  {{input-tip validation=usernameValidation id="username-validation"}}
    - {{text-field value=accountName id="new-account-name"}} {{input-tip validation=nameValidation}} + {{text-field value=accountName id="new-account-name"}}
    {{password-field value=accountPassword type="password" id="new-account-password" capsLockOn=capsLockOn}} -  {{input-tip validation=passwordValidation}}
    -
    +
    {{d-icon "exclamation-triangle"}} {{i18n 'login.caps_lock_warning'}}
    {{d-icon "exclamation-triangle"}} {{i18n 'login.caps_lock_warning'}}
    {{d-icon "exclamation-triangle"}} {{i18n 'login.caps_lock_warning'}}
    @@ -40,8 +33,14 @@ {{/second-factor-form}} {{/if}} - {{authMessage}} -
    {{alert}}
    + + {{#if showLoginButtons}} + {{login-buttons + canLoginLocalWithEmail=canLoginLocalWithEmail + processingEmailLink=processingEmailLink + emailLogin='emailLogin' + externalLogin='externalLogin'}} + {{/if}} {{/d-modal-body}} + +
    {{authMessage}}
    +
    {{alert}}
    {{/login-modal}} diff --git a/app/assets/javascripts/discourse/templates/preferences/account.hbs b/app/assets/javascripts/discourse/templates/preferences/account.hbs index c9a6b01105..2a7f3a0d19 100644 --- a/app/assets/javascripts/discourse/templates/preferences/account.hbs +++ b/app/assets/javascripts/discourse/templates/preferences/account.hbs @@ -71,9 +71,7 @@ {{#if model.second_factor_enabled}} {{i18n 'user.second_factor.disable'}} {{else}} - {{i18n 'enable'}} - {{showTwoFactorModalText}} - {{i18n 'user.second_factor.enable'}} + {{discourse-linked-text action="showTwoFactorModal" text="user.second_factor.enable"}} {{/if}} {{#if isCurrentUser}} diff --git a/app/assets/javascripts/discourse/templates/preferences/emails.hbs b/app/assets/javascripts/discourse/templates/preferences/emails.hbs index b73cffa4d8..d877bf7f82 100644 --- a/app/assets/javascripts/discourse/templates/preferences/emails.hbs +++ b/app/assets/javascripts/discourse/templates/preferences/emails.hbs @@ -1,3 +1,10 @@ +{{#unless siteSettings.disable_mailing_list_mode}} +
    + {{#if model.user_option.mailing_list_mode}} +
    {{i18n 'user.mailing_list_mode.warning'}}
    + {{/if}} +
    +{{/unless}}
    diff --git a/app/assets/javascripts/discourse/templates/preferences/tags.hbs b/app/assets/javascripts/discourse/templates/preferences/tags.hbs index 1bf4043b2b..ef1dcc541f 100644 --- a/app/assets/javascripts/discourse/templates/preferences/tags.hbs +++ b/app/assets/javascripts/discourse/templates/preferences/tags.hbs @@ -16,7 +16,7 @@
    {{i18n 'user.watched_tags_instructions'}}
    - + {{tag-chooser tags=model.tracked_tags blacklist=selectedTags diff --git a/app/assets/javascripts/discourse/templates/user.hbs b/app/assets/javascripts/discourse/templates/user.hbs index 177a8fec05..3b3acc6fa9 100644 --- a/app/assets/javascripts/discourse/templates/user.hbs +++ b/app/assets/javascripts/discourse/templates/user.hbs @@ -107,7 +107,7 @@
    - {{#if model.isSuspended}} + {{#if model.suspended}}
    {{d-icon "ban"}} diff --git a/app/assets/javascripts/discourse/widgets/post-menu.js.es6 b/app/assets/javascripts/discourse/widgets/post-menu.js.es6 index 7b177a39e6..7a0f643fa2 100644 --- a/app/assets/javascripts/discourse/widgets/post-menu.js.es6 +++ b/app/assets/javascripts/discourse/widgets/post-menu.js.es6 @@ -69,7 +69,7 @@ registerButton('like-count', attrs => { const title = attrs.liked ? count === 1 ? 'post.has_likes_title_only_you' : 'post.has_likes_title_you' : 'post.has_likes_title'; - const icon = attrs.yours ? 'heart' : ''; + const icon = attrs.yours ? 'd-liked' : ''; const additionalClass = attrs.yours ? 'my-likes' : 'regular-likes'; return { action: 'toggleWhoLiked', diff --git a/app/assets/javascripts/discourse/widgets/search-menu.js.es6 b/app/assets/javascripts/discourse/widgets/search-menu.js.es6 index aa2a45c4a7..4bec0f16cd 100644 --- a/app/assets/javascripts/discourse/widgets/search-menu.js.es6 +++ b/app/assets/javascripts/discourse/widgets/search-menu.js.es6 @@ -105,7 +105,7 @@ export default createWidget('search-menu', { if (contextEnabled && ctx) { if (this.currentUser && - ctx.id.toString().toLowerCase() === this.currentUser.username_lower && + ctx.id.toString().toLowerCase() === this.currentUser.get('username_lower') && type === "private_messages") { query += ' in:private'; } else { diff --git a/app/assets/javascripts/discourse/widgets/topic-timeline.js.es6 b/app/assets/javascripts/discourse/widgets/topic-timeline.js.es6 index a82525157f..7cff52d3f8 100644 --- a/app/assets/javascripts/discourse/widgets/topic-timeline.js.es6 +++ b/app/assets/javascripts/discourse/widgets/topic-timeline.js.es6 @@ -4,6 +4,8 @@ import { h } from 'virtual-dom'; import { relativeAge } from 'discourse/lib/formatter'; import { iconNode } from 'discourse-common/lib/icon-library'; import RawHtml from 'discourse/widgets/raw-html'; +import renderTags from 'discourse/lib/render-tags'; +import renderTopicFeaturedLink from 'discourse/lib/render-topic-featured-link'; const SCROLLER_HEIGHT = 50; const LAST_READ_HEIGHT = 20; @@ -382,6 +384,7 @@ export default createWidget('topic-timeline', { const createdAt = new Date(topic.created_at); const stream = attrs.topic.get('postStream.stream'); const { currentUser } = this; + const { tagging_enabled, topic_featured_link_enabled } = this.siteSettings; attrs["currentUser"] = currentUser; @@ -399,6 +402,34 @@ export default createWidget('topic-timeline', { action: 'jumpTop' }))]; + // duplicate of the {{topic-category}} component + let category = []; + + if (!topic.get("isPrivateMessage")) { + if (topic.category.parentCategory) { + category.push(this.attach("category-link", { category: topic.category.parentCategory })); + } + category.push(this.attach("category-link", { category: topic.category })); + } + + const showTags = tagging_enabled && topic.tags && topic.tags.length > 0; + + if (showTags || topic_featured_link_enabled) { + let extras = []; + if (showTags) { + const tagsHtml = new RawHtml({ html: renderTags(topic, { mode: "list" }) }); + extras.push(h("div.list-tags", tagsHtml)); + } + if (topic_featured_link_enabled) { + extras.push(new RawHtml({ html: renderTopicFeaturedLink(topic) })); + } + category.push(h("div.topic-header-extra", extras)); + } + + if (category.length > 0) { + elems.push(h("div.topic-category", category)); + } + if (this.state.excerpt) { elems.push(new RawHtml({ html: `
    ${this.state.excerpt}
    ` diff --git a/app/assets/javascripts/locales/bg.js.erb b/app/assets/javascripts/locales/bg.js.erb new file mode 100644 index 0000000000..006dfde319 --- /dev/null +++ b/app/assets/javascripts/locales/bg.js.erb @@ -0,0 +1,3 @@ +//= depend_on 'client.bg.yml' +//= require locales/i18n +<%= JsLocaleHelper.output_locale(:bg) %> diff --git a/app/assets/javascripts/pretty-text/engines/discourse-markdown/bbcode-block.js.es6 b/app/assets/javascripts/pretty-text/engines/discourse-markdown/bbcode-block.js.es6 index b35d716189..b7348d0262 100644 --- a/app/assets/javascripts/pretty-text/engines/discourse-markdown/bbcode-block.js.es6 +++ b/app/assets/javascripts/pretty-text/engines/discourse-markdown/bbcode-block.js.es6 @@ -11,7 +11,7 @@ function trailingSpaceOnly(src, start, max) { return true; } -const ATTR_REGEX = /^\s*=(.+)$|((([a-z0-9]*)\s*)=)(["“”'].*["“”']|\S+)/ig; +const ATTR_REGEX = /^\s*=(.+)$|((([a-z0-9]*)\s*)=)(["“”'].*?["“”']|\S+)/ig; // parse a tag [test a=1 b=2] to a data structure // {tag: "test", attrs={a: "1", b: "2"} diff --git a/app/assets/javascripts/select-kit/components/category-drop.js.es6 b/app/assets/javascripts/select-kit/components/category-drop.js.es6 index cbfaa32961..d88fa7ff58 100644 --- a/app/assets/javascripts/select-kit/components/category-drop.js.es6 +++ b/app/assets/javascripts/select-kit/components/category-drop.js.es6 @@ -20,6 +20,7 @@ export default ComboBoxComponent.extend({ fullWidthOnMobile: true, caretDownIcon: "caret-right", caretUpIcon: "caret-down", + subCategory: false, init() { this._super(); @@ -50,13 +51,15 @@ export default ComboBoxComponent.extend({ collectionHeader(allCategoriesUrl, allCategoriesLabel, noCategoriesUrl, noCategoriesLabel) { let shortcuts = ""; - shortcuts += ` - - ${allCategoriesLabel} - - `; + if (this.get("hasSelection") || (this.get("noSubcategories") && this.get("subCategory"))) { + shortcuts += ` + + ${allCategoriesLabel} + + `; + } - if (this.get("subCategory")) { + if (this.get("subCategory") && (this.get("hasSelection") || !this.get("noSubcategories"))) { shortcuts += ` ${noCategoriesLabel} diff --git a/app/assets/javascripts/select-kit/components/composer-actions.js.es6 b/app/assets/javascripts/select-kit/components/composer-actions.js.es6 index ff587c2bdc..5a3479f751 100644 --- a/app/assets/javascripts/select-kit/components/composer-actions.js.es6 +++ b/app/assets/javascripts/select-kit/components/composer-actions.js.es6 @@ -28,6 +28,7 @@ export default DropdownSelectBoxComponent.extend({ allowInitialValueMutation: false, allowAutoSelectFirst: false, showFullTitle: false, + isHidden: Ember.computed.empty("content"), didReceiveAttrs() { this._super(); @@ -68,7 +69,7 @@ export default DropdownSelectBoxComponent.extend({ content(options, canWhisper, action) { let items = []; - if (action !== CREATE_TOPIC && action !== CREATE_SHARED_DRAFT) { + if (action !== CREATE_TOPIC && action !== CREATE_SHARED_DRAFT && _topicSnapshot) { items.push({ name: I18n.t("composer.composer_actions.reply_as_new_topic.label"), description: I18n.t("composer.composer_actions.reply_as_new_topic.desc"), diff --git a/app/assets/javascripts/select-kit/components/future-date-input-selector.js.es6 b/app/assets/javascripts/select-kit/components/future-date-input-selector.js.es6 index 580c351bb4..66b378d891 100644 --- a/app/assets/javascripts/select-kit/components/future-date-input-selector.js.es6 +++ b/app/assets/javascripts/select-kit/components/future-date-input-selector.js.es6 @@ -155,7 +155,7 @@ export default ComboBoxComponent.extend(DatetimeMixin, { }, mutateValue(value) { - if (this.get("isCustom") || this.get("isBasedOnLastPost")) { + if (value === 'pick_date_and_time' || this.get("isBasedOnLastPost")) { this.set("value", value); } else { let input = null; diff --git a/app/assets/javascripts/select-kit/components/group-dropdown.js.es6 b/app/assets/javascripts/select-kit/components/group-dropdown.js.es6 index b2939b0278..7657a28e31 100644 --- a/app/assets/javascripts/select-kit/components/group-dropdown.js.es6 +++ b/app/assets/javascripts/select-kit/components/group-dropdown.js.es6 @@ -29,11 +29,15 @@ export default ComboBoxComponent.extend({ @computed collectionHeader() { - return ` - - ${I18n.t("groups.index.all").toLowerCase()} - - `.htmlSafe(); + if (this.siteSettings.enable_group_directory || + (this.currentUser && this.currentUser.get('staff'))) { + + return ` + + ${I18n.t("groups.index.all").toLowerCase()} + + `.htmlSafe(); + } }, actions: { diff --git a/app/assets/javascripts/select-kit/components/multi-select.js.es6 b/app/assets/javascripts/select-kit/components/multi-select.js.es6 index 9a9453445b..8e7622e1e3 100644 --- a/app/assets/javascripts/select-kit/components/multi-select.js.es6 +++ b/app/assets/javascripts/select-kit/components/multi-select.js.es6 @@ -79,7 +79,7 @@ export default SelectKitComponent.extend({ shouldDisplayFilter() { return true; }, _beforeWillComputeValues(values) { - return values.map(v => this._castInteger(v === "" ? null : v)); + return values.map(v => this._cast(v === "" ? null : v)); }, willComputeValues(values) { return values; }, computeValues(values) { return values; }, diff --git a/app/assets/javascripts/select-kit/components/select-kit.js.es6 b/app/assets/javascripts/select-kit/components/select-kit.js.es6 index a45da128fd..d07fe5cdc2 100644 --- a/app/assets/javascripts/select-kit/components/select-kit.js.es6 +++ b/app/assets/javascripts/select-kit/components/select-kit.js.es6 @@ -62,6 +62,7 @@ export default Ember.Component.extend(UtilsMixin, PluginApiMixin, DomHelpersMixi horizontalOffset: 0, fullWidthOnMobile: false, castInteger: false, + castBoolean: false, allowAny: false, allowInitialValueMutation: false, content: null, @@ -169,7 +170,7 @@ export default Ember.Component.extend(UtilsMixin, PluginApiMixin, DomHelpersMixi } let computedContentItem = { - value: this._castInteger(this.valueForContentItem(contentItem)), + value: this._cast(this.valueForContentItem(contentItem)), name: name || this._nameForContent(contentItem), locked: false, created: options.created || false, @@ -333,7 +334,10 @@ export default Ember.Component.extend(UtilsMixin, PluginApiMixin, DomHelpersMixi }, stopLoading() { - this.focus(); + if (this.site && !this.site.isMobileDevice) { + this.focusFilterOrHeader(); + } + this.set("isLoading", false); this._boundaryActionHandler("onStopLoading"); }, diff --git a/app/assets/javascripts/select-kit/components/select-kit/select-kit-header.js.es6 b/app/assets/javascripts/select-kit/components/select-kit/select-kit-header.js.es6 index d719c1ca66..207de3259f 100644 --- a/app/assets/javascripts/select-kit/components/select-kit/select-kit-header.js.es6 +++ b/app/assets/javascripts/select-kit/components/select-kit/select-kit-header.js.es6 @@ -9,7 +9,7 @@ export default Ember.Component.extend({ "tabindex", "ariaLabel:aria-label", "ariaHasPopup:aria-haspopup", - "title", + "sanitizedTitle:title", "value:data-value", "name:data-name", ], @@ -18,7 +18,7 @@ export default Ember.Component.extend({ ariaHasPopup: true, - ariaLabel: Ember.computed.or("computedContent.ariaLabel", "title"), + ariaLabel: Ember.computed.or("computedContent.ariaLabel", "sanitizedTitle"), @computed("computedContent.title", "name") title(computedContentTitle, name) { @@ -28,6 +28,13 @@ export default Ember.Component.extend({ return null; }, + // this might need a more advanced solution + // but atm it's the only case we have to handle + @computed("title") + sanitizedTitle(title) { + return String(title).replace("…", ""); + }, + label: Ember.computed.or("computedContent.label", "title", "name"), name: Ember.computed.alias("computedContent.name"), diff --git a/app/assets/javascripts/select-kit/components/single-select.js.es6 b/app/assets/javascripts/select-kit/components/single-select.js.es6 index 65e73840ad..e10ae018aa 100644 --- a/app/assets/javascripts/select-kit/components/single-select.js.es6 +++ b/app/assets/javascripts/select-kit/components/single-select.js.es6 @@ -63,7 +63,7 @@ export default SelectKitComponent.extend({ switch (typeof value) { case "string": case "number": - return this._castInteger(value === "" ? null : value); + return this._cast(value === "" ? null : value); default: return value; } diff --git a/app/assets/javascripts/select-kit/components/tag-drop.js.es6 b/app/assets/javascripts/select-kit/components/tag-drop.js.es6 index 4e3768753c..e508227747 100644 --- a/app/assets/javascripts/select-kit/components/tag-drop.js.es6 +++ b/app/assets/javascripts/select-kit/components/tag-drop.js.es6 @@ -77,14 +77,25 @@ export default ComboBoxComponent.extend({ @computed("allTagsUrl", "allTagsLabel", "noTagsUrl", "noTagsLabel") collectionHeader(allTagsUrl, allTagsLabel, noTagsUrl, noTagsLabel) { - return ` - - ${allTagsLabel} - - - ${noTagsLabel} - - `; + let content = ""; + + if (this.get("tagId") !== "none") { + content += ` + + ${noTagsLabel} + + `; + } + + if (this.get("hasSelection") || this.get("tagId") === "none") { + content += ` + + ${allTagsLabel} + + `; + } + + return content; }, @computed("tag") diff --git a/app/assets/javascripts/select-kit/mixins/tags.js.es6 b/app/assets/javascripts/select-kit/mixins/tags.js.es6 index 1c2e10f6f4..e1c2d0e0d9 100644 --- a/app/assets/javascripts/select-kit/mixins/tags.js.es6 +++ b/app/assets/javascripts/select-kit/mixins/tags.js.es6 @@ -28,7 +28,6 @@ export default Ember.Mixin.create({ }) .finally(() => { self.stopLoading(); - self.focusFilterOrHeader(); }); }, diff --git a/app/assets/javascripts/select-kit/mixins/utils.js.es6 b/app/assets/javascripts/select-kit/mixins/utils.js.es6 index 11f4418cf4..ad61c7926b 100644 --- a/app/assets/javascripts/select-kit/mixins/utils.js.es6 +++ b/app/assets/javascripts/select-kit/mixins/utils.js.es6 @@ -27,6 +27,19 @@ export default Ember.Mixin.create({ return !isNaN(parseFloat(input)) && isFinite(input); }, + _cast(value) { + if (value === this.noneValue) return value; + return this._castInteger(this._castBoolean(value)); + }, + + _castBoolean(value) { + if (this.get("castBoolean") && Ember.isPresent(value) && typeof(value) === "string") { + return value === "true"; + } + + return value; + }, + _castInteger(value) { if (this.get("castInteger") && Ember.isPresent(value) && this._isNumeric(value)) { return parseInt(value, 10); diff --git a/app/assets/javascripts/service-worker.js.erb b/app/assets/javascripts/service-worker.js.erb index fba1cfdef2..3f6ab9b472 100644 --- a/app/assets/javascripts/service-worker.js.erb +++ b/app/assets/javascripts/service-worker.js.erb @@ -37,6 +37,8 @@ self.addEventListener('install', function(event) { return caches.open(CURRENT_CACHES.offline).then(function(cache) { return cache.put(OFFLINE_URL, response); }); + }).then(function(cache) { + self.skipWaiting(); }) ); }); @@ -60,11 +62,17 @@ self.addEventListener('activate', function(event) { } }) ); + }).then(function() { + self.clients.claim() }) ); }); self.addEventListener('fetch', function(event) { + // Bypass service workers if this is a url with a token param + if(/\?.*token/i.test(event.request.url)) { + return; + } // We only want to call event.respondWith() if this is a navigation request // for an HTML page. // request.mode of 'navigate' is unfortunately not supported in Chrome diff --git a/app/assets/stylesheets/common/admin/admin_base.scss b/app/assets/stylesheets/common/admin/admin_base.scss index 33da3ec0e0..5557f7c795 100644 --- a/app/assets/stylesheets/common/admin/admin_base.scss +++ b/app/assets/stylesheets/common/admin/admin_base.scss @@ -6,6 +6,7 @@ @import "common/admin/customize"; @import "common/admin/flagging"; @import "common/admin/dashboard_next"; +@import "common/admin/admin_reports"; @import "common/admin/moderation_history"; @import "common/admin/suspend"; @@ -880,7 +881,6 @@ section.details { .upgrade-header { flex: 1 1 100%; - margin: .25em 0 1em 0; @media screen and (max-width: 650px) { margin: 0; } @@ -1969,6 +1969,12 @@ table#user-badges { margin-right: 20px; } +.admin-reports, .dashboard-next { + &.admin-contents { + margin: 0; + } +} + .cbox0 { background: blend-primary-secondary(0%); } .cbox10 { background: blend-primary-secondary(10%); } .cbox20 { background: blend-primary-secondary(20%); } diff --git a/app/assets/stylesheets/common/admin/admin_reports.scss b/app/assets/stylesheets/common/admin/admin_reports.scss new file mode 100644 index 0000000000..9a064a85c0 --- /dev/null +++ b/app/assets/stylesheets/common/admin/admin_reports.scss @@ -0,0 +1,53 @@ +.admin-reports { + h3 { + border-bottom: 1px solid $primary-low; + margin-bottom: .5em; + padding-bottom: .5em; + } + + .report-container { + display: flex; + + .loading-container { + width: 100%; + } + + .visualization { + display: flex; + flex: 4; + } + + .filters { + display: flex; + flex: 1; + align-items: center; + flex-direction: column; + margin-left: 2em; + + .date-picker { + margin: 0; + width: 195px; + } + + .combo-box, .date-picker-wrapper, .btn { + width: 100%; + margin-bottom: 1em; + } + } + + @include small-width { + flex-direction: column; + min-width: 100%; + + .visualization { + order: 2; + } + + .filters { + order: 1; + margin: 0; + align-items: flex-start; + } + } + } +} diff --git a/app/assets/stylesheets/common/admin/dashboard_next.scss b/app/assets/stylesheets/common/admin/dashboard_next.scss index 71cb1ec305..78e4cdf0c0 100644 --- a/app/assets/stylesheets/common/admin/dashboard_next.scss +++ b/app/assets/stylesheets/common/admin/dashboard_next.scss @@ -1,8 +1,4 @@ .dashboard-next { - &.admin-contents { - margin: 0; - } - .section-top { margin-bottom: 1em; } @@ -17,6 +13,15 @@ .section-column { min-width: calc(50% - .5em); + max-width: 100%; + + &:last-child, { + margin-left: 1em; + } + + &:first-child { + margin-right: 1em; + } @include small-width { min-width: 100%; @@ -31,16 +36,9 @@ } } - .section-column:last-child, { - margin-left: 1em; - } - - .section-column:first-child { - margin-right: 1em; - } - @include small-width { - .section-column:last-child, .section-column:first-child { + .section-column:last-child, + .section-column:first-child { margin: 0; } } @@ -53,6 +51,9 @@ } display: flex; + @media screen and (max-width: 400px) { + flex-wrap: wrap; + } align-items: center; justify-content: space-between; border-bottom: 1px solid $primary-low; @@ -61,7 +62,7 @@ } .section-body { - padding: 1em 0; + padding: 1em 0 0; } } @@ -103,16 +104,17 @@ .durability, .last-dashboard-update { flex: 1 1 50%; box-sizing: border-box; - margin: 20px 0; - padding: 0 20px; + margin: 1em 0; + padding: 0 1em; } .durability { display: flex; flex-wrap: wrap; justify-content: space-between; + .backups, .uploads { - flex: 1 1 100%; + flex: 1 1 100%; } .uploads p:last-of-type { @@ -142,7 +144,7 @@ border-left: 1px solid $primary-low; text-align: center; display: flex; - justify-content: center; + justify-content: center; div { align-self: center; h4 { @@ -152,7 +154,17 @@ } } + .top-referred-topics, .trending-search { + th:first-of-type { + text-align: left; + } + } + .top-referred-topics { + .dashboard-table table { + table-layout: auto; + } + } .community-health { .period-chooser .period-chooser-header { @@ -167,7 +179,6 @@ } } - .dashboard-mini-chart { .status { display: flex; @@ -186,6 +197,10 @@ cursor: pointer; margin-left: .25em; color: $primary-low-mid; + + &:hover { + color: $primary-medium; + } } } @@ -200,6 +215,10 @@ color: $success; } + &.no-change { + color: $primary-medium; + } + .trend-value { font-size: $font-up-1; } @@ -217,6 +236,7 @@ justify-content: space-between; flex: 1; width: 100%; + min-width: 0; } @include small-width { @@ -234,7 +254,7 @@ width: 100%; } - .d-icon-question-circle { + .tooltip { cursor: pointer; } @@ -250,30 +270,6 @@ } } } - - &.high-trending-up, &.trending-up { - .chart-trend, .data-point { - color: $success; - } - } - - &.high-trending-down, &.trending-down { - .chart-trend, .data-point { - color: $danger; - } - } -} - -.top-referred-topics, .trending-search { - th:first-of-type { - text-align: left; - } -} - -.top-referred-topics { - .dashboard-table table { - table-layout: auto; - } } .dashboard-table { @@ -335,6 +331,7 @@ text-align: center; padding: 8px; } + td.left { text-align: left; } @@ -345,9 +342,11 @@ td.value { text-align: right; - transform: translateX(-40%); + padding: 8px 21px 8px 8px; // accounting for negative right caret margin + &:nth-of-type(2) { + padding: 8px 12px 8px; + } i { - display: none; margin-right: -12px; // align on caret @media screen and (max-width: 650px) { margin-right: -9px; @@ -355,25 +354,158 @@ } &.high-trending-up, &.trending-up { - i.up { - color: $success; - display: inline; - } + i { color: $success; } } &.high-trending-down, &.trending-down { - i.down { - color: $danger; - display: inline; - } - } - &.no-change { - i.down { - display: inline; - visibility: hidden; - } + i { color: $danger; } } } } } } } + +.user-metrics { + display: flex; + flex-wrap: wrap; + justify-content: space-between; + margin-left: -5%; + margin: 2em 0 .75em -5%; // Negative margin allows for a margin when in 2-columns, + .dashboard-inline-table { // and "hides" margin when the item spans 100% width + flex: 1 0 auto; + max-width: 95%; + } + .table-cell { + display: flex; + flex: 0 1 auto; + margin: 0 10px 5px 0; + border: 1px solid $primary-low; + border-radius: 10px; + .label { + display: flex; + align-items: center; + color: $primary; + background: $primary-very-low; + justify-content: center; + border-radius: 9px 0 0 9px; + padding: 0 5px 0 8px; + + .d-icon { + margin-right: 5px; + font-size: $font-down-1; + } + } + + .value { + padding: 0 8px 0 5px; + } + &.user-newuser{ + .label { + color: $primary-high; + } + } + &.user-basic , &.user-member { + border-color: $bronze; + .label { + border-color: $bronze; + background: $bronze; + color: $secondary; + } + } + &.user-regular { + border-color: $silver; + .label { + border-color: $silver; + background: $silver; + color: $secondary; + } + } + &.user-leader { + border-color: $gold; + .label { + background: $gold; + border-color: $gold; + color: $secondary; + } + } + } +} + +.dashboard-inline-table { + margin-left: 5%; + margin-bottom: 1.25em; + + .table-title { + border-bottom: 1px solid $primary-low; + margin-bottom: 1em; + } + + .table-container { + display: flex; + flex-wrap: wrap; + flex: 1 1 auto; + } +} + +.dashboard-table.activity-metrics { + table { + @media screen and (min-width: 400px) { + table-layout: auto; + } + tr th { + text-align: right; + } + .d-icon { + color: $primary-low-mid; + min-width: 14px; + text-align: center; + } + @media screen and (max-width: 400px) { + .d-icon { display: none; } + td.title { + padding: 8px 0 8px 4px; + } + } + } +} + + +.rtl .dashboard-next { + .section-column { + &:last-child, { + margin-right: 1em; + margin-left: 0; + } + + &:first-child { + margin-left: 1em; + margin-right: 0; + } + } + + .dashboard-table table tbody tr { + td.title { + text-align: right; + } + + td.value i { + margin-right: 0; + margin-left: -12px; + } + } + + .user-metrics .table-cell { + margin: 0 0 5px 10px; + } + + .table-cell { + .label { + border-radius: 0 9px 9px 0; + + .d-icon { + margin-right: 0; + margin-left: 5px; + } + } + } +} diff --git a/app/assets/stylesheets/common/base/colorpicker.scss b/app/assets/stylesheets/common/base/colorpicker.scss index 83f29f7853..d78ff1684b 100644 --- a/app/assets/stylesheets/common/base/colorpicker.scss +++ b/app/assets/stylesheets/common/base/colorpicker.scss @@ -3,19 +3,19 @@ .category-color-editor { input { width: 70px; + margin-right: 10px; } .color-title { display: inline-block; - width: 130px; + width: 120px; } .colors-container { display: inline-block; vertical-align: middle; padding-top: 4px; - padding-left: 15px; - max-width: 300px; + max-width: 240px; .colorpicker { border: 1px solid $primary-low; diff --git a/app/assets/stylesheets/common/base/login.scss b/app/assets/stylesheets/common/base/login.scss index 901a2deb74..683406cfef 100644 --- a/app/assets/stylesheets/common/base/login.scss +++ b/app/assets/stylesheets/common/base/login.scss @@ -13,6 +13,9 @@ } #login-form { + table { + width: 100%; + } a { color: dark-light-choose($primary-high, $secondary-low); } @@ -40,6 +43,12 @@ $input-width: 220px; td { label, input { margin-bottom: 0; + width: 100%; + } + } + .modal-footer { + .inline-spinner { + display: inline-flex; } } } @@ -56,9 +65,8 @@ $input-width: 220px; } .disclaimer { - font-size: $font-down-1; color: dark-light-choose($primary-medium, $secondary-medium); - clear: both; + margin-top: .5em; } .user-field.confirm { @@ -106,12 +114,16 @@ $input-width: 220px; .invites-show { .two-col { position: relative; + display: flex; } .col-image { - position: absolute; - top: 0; - left: 0; + position: relative; + width: 150px; + margin-right: 20px; + @media screen and (max-width: 600px) { + display: none; + } } form { @@ -135,6 +147,21 @@ $input-width: 220px; } } +.auth-message { + padding: 0 15px 15px 15px; + &:empty { + padding: 0; + } +} + +.modal tr.instructions { + display: flex; + flex-direction: column; + margin-top: 0.15em; + label { + color: dark-light-choose($primary-medium, $secondary-medium); + } +} // alternate login / create new account buttons should be de-emphasized @@ -142,4 +169,4 @@ button#login-link, button#new-account-link { background: transparent; color: dark-light-choose($primary-high, $secondary-low); -} +} \ No newline at end of file diff --git a/app/assets/stylesheets/common/base/menu-panel.scss b/app/assets/stylesheets/common/base/menu-panel.scss index 013a94da3a..c724aea82d 100644 --- a/app/assets/stylesheets/common/base/menu-panel.scss +++ b/app/assets/stylesheets/common/base/menu-panel.scss @@ -76,8 +76,9 @@ float: left; background-color: transparent; display: inline-flex; - margin: 0.25em 0.5em; - width: 43%; + padding: 0.25em 0.5em; + width: 50%; + box-sizing: border-box; .badge-notification { color: dark-light-choose($primary-medium, $secondary-medium); background-color: transparent; diff --git a/app/assets/stylesheets/common/base/modal.scss b/app/assets/stylesheets/common/base/modal.scss index bf3ee57cfa..ce3ff6ca87 100644 --- a/app/assets/stylesheets/common/base/modal.scss +++ b/app/assets/stylesheets/common/base/modal.scss @@ -31,9 +31,17 @@ align-items: center; padding: 10px 15px; border-bottom: 1px solid $primary-low; - h3 { - margin-bottom: 0; + + .title { + h3 { + margin-bottom: 0; + } + + p { + margin: 0; + } } + .modal-close { order: 2; margin-left: auto; @@ -80,12 +88,20 @@ } .modal-inner-container { + display: table; + width: 100%; + min-width: 320px; max-width: 700px; margin: 0 auto; background-color: $secondary; background-clip: padding-box; box-shadow: shadow("modal"); + @media screen and (min-width: 475px) { + min-width: 475px; + width: auto; + } + .select-kit { width: 220px; @@ -145,6 +161,11 @@ height: 10em; } } + @media screen and (min-width: 524px) { + .modal-inner-container { + min-width: 525px; + } + } } .modal { @@ -253,6 +274,11 @@ .modal-body.forgot-password-modal p { font-size: $font-0; } + + pre code { + white-space: pre-wrap; + max-width: 700px; + } } .reply-where-modal { @@ -308,6 +334,7 @@ label { margin-top: 7px; + max-width: 450px; } .optional { @@ -404,6 +431,8 @@ } .incoming-email-content { height: 300px; + max-width: 700px; + width: 90vw; // forcing textarea wider textarea, .incoming-email-html-part { height: 95%; border: none; @@ -503,4 +532,3 @@ position: absolute; width: 95%; } - diff --git a/app/assets/stylesheets/common/base/onebox.scss b/app/assets/stylesheets/common/base/onebox.scss index 25fcd39168..7a306a96d8 100644 --- a/app/assets/stylesheets/common/base/onebox.scss +++ b/app/assets/stylesheets/common/base/onebox.scss @@ -329,7 +329,7 @@ pre.onebox code li{ pre.onebox code ol.lines{ position:relative; - margin-left: 40px; + margin: 0 0 0 40px; } pre.onebox code ol.lines li { diff --git a/app/assets/stylesheets/common/base/user-badges.scss b/app/assets/stylesheets/common/base/user-badges.scss index 63a31d2a15..98c47475ff 100644 --- a/app/assets/stylesheets/common/base/user-badges.scss +++ b/app/assets/stylesheets/common/base/user-badges.scss @@ -20,15 +20,15 @@ } &.badge-type-gold .fa { - color: rgb(231, 195, 0) !important; + color: $gold !important; } &.badge-type-silver .fa { - color: #c0c0c0 !important; + color: $silver !important; } &.badge-type-bronze .fa { - color: #cd7f32 !important; + color: $bronze !important; } &.disabled { diff --git a/app/assets/stylesheets/common/base/user.scss b/app/assets/stylesheets/common/base/user.scss index 749dbab90a..b5543ccec6 100644 --- a/app/assets/stylesheets/common/base/user.scss +++ b/app/assets/stylesheets/common/base/user.scss @@ -541,6 +541,11 @@ width: 520px; } + .warning-wrap { + height: 30px; + margin-bottom: 10px; + } + .category-notifications .category-controls, .tag-notifications .tag-controls { margin-top: 24px; diff --git a/app/assets/stylesheets/common/components/conditional-loading-section.scss b/app/assets/stylesheets/common/components/conditional-loading-section.scss index e081dcde46..cb6c052b18 100644 --- a/app/assets/stylesheets/common/components/conditional-loading-section.scss +++ b/app/assets/stylesheets/common/components/conditional-loading-section.scss @@ -1,5 +1,4 @@ .conditional-loading-section { - &.is-loading { padding: 2em; margin: 1em; diff --git a/app/assets/stylesheets/common/foundation/variables.scss b/app/assets/stylesheets/common/foundation/variables.scss index 1bd5900407..6a91f1006a 100644 --- a/app/assets/stylesheets/common/foundation/variables.scss +++ b/app/assets/stylesheets/common/foundation/variables.scss @@ -22,6 +22,13 @@ $twitter: #00bced !default; $yahoo: #810293 !default; $github: #6d6d6d !default; +// Badge color variables +// -------------------------------------------------- + +$gold: rgb(231, 195, 0) !default; +$silver: #c0c0c0 !default; +$bronze: #cd7f32 !default; + // Fonts // -------------------------------------------------- diff --git a/app/assets/stylesheets/common/select-kit/mini-tag-chooser.scss b/app/assets/stylesheets/common/select-kit/mini-tag-chooser.scss index 71a8e700f7..b05db54dc3 100644 --- a/app/assets/stylesheets/common/select-kit/mini-tag-chooser.scss +++ b/app/assets/stylesheets/common/select-kit/mini-tag-chooser.scss @@ -58,6 +58,7 @@ .collection-header { max-height: 125px; overflow-y: auto; + flex: 1 0 auto; .selected-tags { display: flex; diff --git a/app/assets/stylesheets/desktop/login.scss b/app/assets/stylesheets/desktop/login.scss index b7ce599cb8..0828ae0e69 100644 --- a/app/assets/stylesheets/desktop/login.scss +++ b/app/assets/stylesheets/desktop/login.scss @@ -1,104 +1,177 @@ -// style that apply to the login popup +// shared styles used +// on both the login and +// create account modals +.login-modal, +.create-account { + #login-buttons:not(.hidden) { + display: flex; + flex-direction: column; + justify-content: center; + flex-basis: 40%; + align-items: center; + min-height: 175px; + border-left: 1px solid $primary-low; + padding: 15px; + order: 2; -#login-buttons { - button { - margin: 0 5px 5px 0; - min-width: 180px; - &:lang(zh_CN) { - min-width: 200px; + button { + margin: 0.35em; + width: 160px; + &:lang(zh_CN) { + min-width: 200px; + } } } - margin-top: 10px; - margin-bottom: 20px; -} -// Create account + #login-form { + flex: 1 0 auto; + padding: 0 15px; + } -.create-account { - form { + tr:not(.instructions) { + td { + display: flex; + padding: 5px 0 0 0; + } + } + + tr.input label { margin-bottom: 0; } - table { - width: 100%; - } - tr.input { - td { - padding-top: 10px; +} + +// styles used on +// login modal only +.d-modal.login-modal { + .modal-body, + #credentials { + display: flex; + align-items: center; + padding: 15px 0; + + tr { + display: flex; + flex-direction: column; } - input, label { + } +} + +// styles used on the +// create account +// modal only +.d-modal.create-account { + .modal-body { + display: flex; + padding: 15px 0; + } + + .create-account-form tr { + display: flex; + flex-direction: column; + } + + .login-form { + display: flex; + flex: 1 1 50%; + align-items: center; + padding: 0 15px; + form, table { + width: 100%; + } + + tr { + display: flex; + flex-direction: column; + margin-top: 0.15em; + &.password-confirmation { + display: none; + } + } + } + + tr.input { + input, + label { margin-bottom: 0; + width: 100%; } .tip { max-width: 340px; } } + .invites-show { + padding-top: 20px; + + .two-col { + margin-top: 30px; + } + .col-image { + width: 200px; + img { + width: 200px; + } + } + .col-form { + margin-left: 200px; + .inline-invite-img { + display: none; + } + } + form { + .controls, + .input { + margin-left: 20px; + } + input, + label { + margin-bottom: 0; + } + .user-field .control-label:not(.checkbox-label) { + margin-left: 20px; + } + } + } + + .password-reset, + .invites-show { + .col-form { + padding-left: 20px; + } + h2 { + margin-bottom: 12px; + } + .col-image img { + width: 200px; + height: 200px; + } + } + + .password-reset { + .col-form { + padding-top: 40px; + } + } + .tos-agree { margin-bottom: 12px; } - .disclaimer { - margin-top: 15px; - } - - .instructions { - label { - color: dark-light-choose($primary-medium, $secondary-medium); - } - } - .user-fields { border-top: 1px solid $primary-low; padding-top: 20px; } } -.password-reset, .invites-show { - .col-form { - padding-left: 20px; - } - h2 { - margin-bottom: 12px; - } - .col-image img { - width: 200px; - height: 200px; - } -} - -.password-reset { - .col-form { - padding-top: 40px; - } -} - -.invites-show { - padding-top: 20px; - - .two-col { - margin-top: 30px; - } - .col-image { - width: 200px; - img { - width: 200px; - } - } - .col-form { - margin-left: 200px; - .inline-invite-img { +.login-form { + .tip { + &:not(:empty) + td { display: none; } - } - form { - .controls, .input { - margin-left: 20px; - } - input, label { - margin-bottom: 0; - } - .user-field .control-label:not(.checkbox-label) { - margin-left: 20px; + &:not(:empty), + &:empty + td { + min-height: 1.75em; + width: 240px; } } -} +} \ No newline at end of file diff --git a/app/assets/stylesheets/desktop/upload.scss b/app/assets/stylesheets/desktop/upload.scss index 20e53afa92..fce130e7d3 100644 --- a/app/assets/stylesheets/desktop/upload.scss +++ b/app/assets/stylesheets/desktop/upload.scss @@ -4,10 +4,16 @@ padding-left: 10px; } .radios { - height: 60px; + min-height: 60px; + display: flex; + align-items: flex-start; + label { + flex: 1 0 auto; + margin-right: 1em; + margin-top: 1px; + } .inputs { - float: right; - width: 75%; + width: 100%; input { width: 90%; margin: 0 0 5px 0; @@ -26,8 +32,8 @@ } } } - .radios:last-child { - height: 20px; + .radios:last-child:not(:nth-child(2)) { // last child for composer modal, but not theme import modal + min-height: 20px; } } diff --git a/app/assets/stylesheets/mobile/login.scss b/app/assets/stylesheets/mobile/login.scss index e7b346f9ac..77e32ca9d8 100644 --- a/app/assets/stylesheets/mobile/login.scss +++ b/app/assets/stylesheets/mobile/login.scss @@ -1,63 +1,153 @@ -// style that apply to the login popup +// shared styles +// used in both login and +// create account modals +.login-modal, +.create-account { -.btn-social { - width: 150px; - font-size: $font-up-1; - overflow: hidden; - white-space: nowrap; -} - -#login-buttons { - button { - margin: 0 0 5px 0; + .modal-inner-container { + max-width: 350px; } - display: inline-block; -} -#login-form { - - label { float: left; display: block; } - textarea, input, select { - font-size: $font-up-1; - clear: left; - margin-top: 0; + .close { + padding: 0; + } + + #login-buttons:not(.hidden) { + display: flex; + flex-wrap: wrap; + justify-content: center; + width: 102%; + padding-bottom: 10px; + margin-left: -2%; + + button { + flex: 1 1 48%; + max-width: 50%; + margin: 1% 0 1% 2%; + font-size: $font-up-1; + white-space: nowrap; + @media screen and (max-width: 360px) { + font-size: $font-0; + } } - td { padding: 4px; } -} -a#new-account-link { white-space:nowrap; } + + #login-form { + border-top: 1px solid $primary-low; + } + } -// Create account + form { + display: flex; + justify-content: center; + } -.login-modal, .create-account { - .btn-primary { - margin-bottom: 10px; - float: left; + table { + width: 100%; + padding: 10px; + } + + tr { + &.input td label { + margin-top: 0.75em; + } + + &:not(.instructions) td { + padding: 2px 0 0 0; + } + + &:not(.password-confirmation) { + display: flex; + flex-direction: column; + } + } + + .tip { + &:not(:empty) + td { + display: none; + } + } + + .modal-body input[type="text"], + .modal-body input[type="email"], + .modal-body input[type="password"] { + margin-top: 0; + width: 100%; + box-sizing: border-box; + } + + .modal-footer { + box-sizing: border-box; + margin: 0 auto; + font-size: $font-down-1; + } + + .alert.alert-error { + padding: 0.5em 1em; + margin: 0; + } + + #new-account-link { + white-space: nowrap; } } +// Styles for the +// login modal only +.d-modal.login-modal { + #credentials { + width: 100%; + tr { + display: flex; + flex-direction: column; + } + } -$label-width: 85px; -$input-width: 184px; + #login-form { + margin-bottom: 0.75em; + td { + padding: 0; + width: 100%; + margin: 0 auto; + } + label { + float: left; + display: block; + } + textarea, + input, + select { + font-size: $font-up-1; + clear: left; + margin-top: 0; + } + } + + tr { + td label { + margin-top: 0.75em; + padding: 4px 0; + } + } +} + +// styles for the +// create account +// modal only .create-account .modal-body { - input[type=text], input[type=email], input[type=password] { - display: inline-block; - margin-bottom: 5px; - margin-top: 10px; - width: $input-width; - } - + display: flex; + flex-direction: column; tr.instructions { label { color: dark-light-choose($primary-medium, $secondary-medium); } } - tr.input { - td.label { - width: $label-width; - } + #login-buttons + .login-form { + border-top: 1px solid $primary-low; + } + .login-form { + margin-bottom: 0.75em; } } @@ -65,31 +155,17 @@ $input-width: 184px; .user-fields { margin-top: 10px; padding-top: 15px; - border-top: 1px solid #e9e9e9; + border-top: 1px solid $primary-low; } .user-field.confirm { margin-top: 10px; margin-bottom: 10px; } - - .user-field { - label { - width: $label-width; - } - - input[type=text] { - margin-top: 0; - width: $input-width; - } - .controls { - margin-left: $label-width; - } - } } - -.password-reset, .invites-show { +.password-reset, +.invites-show { margin-top: 30px; .col-image { padding-top: 12px; @@ -120,7 +196,6 @@ $input-width: 184px; } } - .invites-show { .col-image { display: none; diff --git a/app/assets/stylesheets/mobile/modal.scss b/app/assets/stylesheets/mobile/modal.scss index 7d2e19e7b3..8c5f55e3e6 100644 --- a/app/assets/stylesheets/mobile/modal.scss +++ b/app/assets/stylesheets/mobile/modal.scss @@ -28,7 +28,7 @@ // we need a little extra room on mobile for the // stuff inside the footer to fit .modal-footer { - padding: 15px 7px 10px 7px; + padding: 10px } .modal-header { diff --git a/app/assets/stylesheets/mobile/topic.scss b/app/assets/stylesheets/mobile/topic.scss index df79b7f6f3..4281d322b8 100644 --- a/app/assets/stylesheets/mobile/topic.scss +++ b/app/assets/stylesheets/mobile/topic.scss @@ -196,6 +196,9 @@ sup sup, sub sup, sup sub, sub sub { top: 0; } font-size: $font-up-1; padding: 5px; } + .topic-category { + margin-bottom: .5rem; + } } .edit-topic-timer-modal { diff --git a/app/controllers/admin/badges_controller.rb b/app/controllers/admin/badges_controller.rb index e84a7dc65f..53089c8e51 100644 --- a/app/controllers/admin/badges_controller.rb +++ b/app/controllers/admin/badges_controller.rb @@ -15,10 +15,8 @@ class Admin::BadgesController < Admin::AdminController end def preview - unless SiteSetting.enable_badge_sql - render json: "preview not allowed", status: 403 - return + return render json: "preview not allowed", status: 403 end render json: BadgeGranter.preview(params[:sql], @@ -39,13 +37,12 @@ class Admin::BadgesController < Admin::AdminController end def save_badge_groupings - badge_groupings = BadgeGrouping.all.order(:position).to_a ids = params[:ids].map(&:to_i) params[:names].each_with_index do |name, index| id = ids[index].to_i - group = badge_groupings.find { |b| b.id == id } || BadgeGrouping.new() + group = badge_groupings.find { |b| b.id == id } || BadgeGrouping.new group.name = name group.position = index group.save @@ -66,24 +63,27 @@ class Admin::BadgesController < Admin::AdminController if errors.present? render_json_error errors else + StaffActionLogger.new(current_user).log_badge_creation(badge) render_serialized(badge, AdminBadgeSerializer, root: "badge") end end def update badge = find_badge - errors = update_badge_from_params(badge) if errors.present? render_json_error errors else + StaffActionLogger.new(current_user).log_badge_change(badge) render_serialized(badge, AdminBadgeSerializer, root: "badge") end end def destroy - find_badge.destroy + badge = find_badge + StaffActionLogger.new(current_user).log_badge_deletion(badge) + badge.destroy render body: nil end diff --git a/app/controllers/admin/email_templates_controller.rb b/app/controllers/admin/email_templates_controller.rb index 33e3c67f8a..feae4de5d1 100644 --- a/app/controllers/admin/email_templates_controller.rb +++ b/app/controllers/admin/email_templates_controller.rb @@ -23,7 +23,7 @@ class Admin::EmailTemplatesController < Admin::AdminController "system_messages.unsilenced", "system_messages.user_automatically_silenced", "system_messages.welcome_invite", "system_messages.welcome_user", "test_mailer", "user_notifications.account_created", "user_notifications.admin_login", - "user_notifications.confirm_new_email", "user_notifications.confirm_old_email", + "user_notifications.confirm_new_email", "user_notifications.notify_old_email", "user_notifications.forgot_password", "user_notifications.set_password", "user_notifications.signup", "user_notifications.signup_after_approval", diff --git a/app/controllers/admin/site_texts_controller.rb b/app/controllers/admin/site_texts_controller.rb index ebb99aa8c5..33e636926d 100644 --- a/app/controllers/admin/site_texts_controller.rb +++ b/app/controllers/admin/site_texts_controller.rb @@ -7,6 +7,12 @@ class Admin::SiteTextsController < Admin::AdminController 'login_required.welcome_message'] end + def self.restricted_keys + ['user_notifications.confirm_old_email.title', + 'user_notifications.confirm_old_email.subject_template', + 'user_notifications.confirm_old_email.text_body_template'] + end + def index overridden = params[:overridden] == 'true' extras = {} @@ -80,7 +86,7 @@ class Admin::SiteTextsController < Admin::AdminController end def find_site_text - raise Discourse::NotFound unless I18n.exists?(params[:id]) + raise Discourse::NotFound unless I18n.exists?(params[:id]) && !self.class.restricted_keys.include?(params[:id]) record_for(params[:id]) end diff --git a/app/controllers/admin/users_controller.rb b/app/controllers/admin/users_controller.rb index b9a24b38fd..7b7f42096c 100644 --- a/app/controllers/admin/users_controller.rb +++ b/app/controllers/admin/users_controller.rb @@ -54,6 +54,46 @@ class Admin::UsersController < Admin::AdminController end end + # DELETE action to delete penalty history for a user + def penalty_history + + # We don't delete any history, we merely remove the action type + # with a removed type. It can still be viewed in the logs but + # will not affect TL3 promotions. + sql = <<~SQL + UPDATE user_histories + SET action = CASE + WHEN action = :silence_user THEN :removed_silence_user + WHEN action = :unsilence_user THEN :removed_unsilence_user + WHEN action = :suspend_user THEN :removed_suspend_user + WHEN action = :unsuspend_user THEN :removed_unsuspend_user + END + WHERE target_user_id = :user_id + AND action IN ( + :silence_user, + :suspend_user, + :unsilence_user, + :unsuspend_user + ) + SQL + + UserHistory.exec_sql( + sql, + UserHistory.actions.slice( + :silence_user, + :suspend_user, + :unsilence_user, + :unsuspend_user, + :removed_silence_user, + :removed_unsilence_user, + :removed_suspend_user, + :removed_unsuspend_user + ).merge(user_id: params[:user_id].to_i) + ) + + render json: success_json + end + def suspend guardian.ensure_can_suspend!(@user) @user.suspended_till = params[:suspend_until] @@ -382,7 +422,7 @@ class Admin::UsersController < Admin::AdminController render json: { deleted: false, message: "User #{user.username} has #{user.post_count} posts, so they can't be deleted." - } + }, status: 403 end end end diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index fa8e02832a..218e04eb46 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -254,6 +254,8 @@ class ApplicationController < ActionController::Base if notifications.present? notification_ids = notifications.split(",").map(&:to_i) Notification.read(current_user, notification_ids) + current_user.reload + current_user.publish_notifications_state cookies.delete('cn') end end @@ -681,6 +683,7 @@ class ApplicationController < ActionController::Base @slug = params[:slug].class == String ? params[:slug] : '' @slug = (params[:id].class == String ? params[:id] : '') if @slug.blank? @slug.tr!('-', ' ') + @hide_google = true if SiteSetting.login_required render_to_string status: status, layout: layout, formats: [:html], template: '/exceptions/not_found' end diff --git a/app/controllers/categories_controller.rb b/app/controllers/categories_controller.rb index 027a5ddf62..f9216fc56b 100644 --- a/app/controllers/categories_controller.rb +++ b/app/controllers/categories_controller.rb @@ -150,7 +150,6 @@ class CategoriesController < ApplicationController old_permissions = cat.permissions_params if result = cat.update(category_params) - DiscourseEvent.trigger(:category_updated, cat) Scheduler::Defer.later "Log staff action change category settings" do @staff_action_logger.log_category_settings_change(@category, category_params, old_permissions) end @@ -167,7 +166,6 @@ class CategoriesController < ApplicationController custom_slug = params[:slug].to_s if custom_slug.present? && @category.update_attributes(slug: custom_slug) - DiscourseEvent.trigger(:category_updated, @category) render json: success_json else render_json_error(@category) diff --git a/app/controllers/email_controller.rb b/app/controllers/email_controller.rb index cff20ff7c0..644876248f 100644 --- a/app/controllers/email_controller.rb +++ b/app/controllers/email_controller.rb @@ -41,6 +41,8 @@ class EmailController < ApplicationController end def perform_unsubscribe + RateLimiter.new(nil, "unsubscribe_#{request.ip}", 10, 1.minute).performed! + key = UnsubscribeKey.find_by(key: params[:key]) raise Discourse::NotFound unless key && key.user @@ -99,19 +101,24 @@ class EmailController < ApplicationController unless updated redirect_back fallback_location: path("/") else + + key = "unsub_#{SecureRandom.hex}" + $redis.setex key, 1.hour, user.email + + url = path("/email/unsubscribed?key=#{key}") if topic - redirect_to path("/email/unsubscribed?topic_id=#{topic.id}&email=#{user.email}") - else - redirect_to path("/email/unsubscribed?email=#{user.email}") + url += "&topic_id=#{topic.id}" end + + redirect_to url end end def unsubscribed - @email = params[:email] + @email = $redis.get(params[:key]) @topic_id = params[:topic_id] - user = User.find_by_email(params[:email]) + user = User.find_by_email(@email) raise Discourse::NotFound unless user topic = Topic.find_by(id: params[:topic_id].to_i) if @topic_id @topic = topic if topic && Guardian.new(nil).can_see?(topic) diff --git a/app/controllers/groups_controller.rb b/app/controllers/groups_controller.rb index 54906c2d61..40dab0ff3e 100644 --- a/app/controllers/groups_controller.rb +++ b/app/controllers/groups_controller.rb @@ -136,8 +136,6 @@ class GroupsController < ApplicationController if group.update(group_params(automatic: group.automatic)) GroupActionLogger.new(current_user, group).log_change_group_settings - DiscourseEvent.trigger(:group_updated, group) - render json: success_json else render_json_error(group) diff --git a/app/controllers/metadata_controller.rb b/app/controllers/metadata_controller.rb index e5993b7a69..e123b7c535 100644 --- a/app/controllers/metadata_controller.rb +++ b/app/controllers/metadata_controller.rb @@ -14,6 +14,10 @@ class MetadataController < ApplicationController def default_manifest logo = SiteSetting.large_icon_url.presence || SiteSetting.logo_small_url.presence || SiteSetting.apple_touch_icon_url.presence + if !logo + logo = path('/images/d-logo-sketch-small.png') + end + file_info = get_file_info(logo) manifest = { name: SiteSetting.title, @@ -29,8 +33,8 @@ class MetadataController < ApplicationController icons: [ { src: logo, - sizes: "512x512", - type: "image/png" + sizes: file_info[:size], + type: file_info[:type] } ] } @@ -49,4 +53,11 @@ class MetadataController < ApplicationController manifest end + + def get_file_info(filename) + type = MiniMime.lookup_by_filename(filename)&.content_type || "image/png" + upload = Upload.find_by_url(filename) + { size: "#{upload&.width || 512}x#{upload&.height || 512}", type: type } + end + end diff --git a/app/controllers/notifications_controller.rb b/app/controllers/notifications_controller.rb index f20e6b9b13..7fbc06a2b0 100644 --- a/app/controllers/notifications_controller.rb +++ b/app/controllers/notifications_controller.rb @@ -59,10 +59,11 @@ class NotificationsController < ApplicationController else Notification.where(user_id: current_user.id).includes(:topic).where(read: false).update_all(read: true) current_user.saw_notification_id(Notification.recent_report(current_user, 1).max.try(:id)) - current_user.reload - current_user.publish_notifications_state end + current_user.reload + current_user.publish_notifications_state + render json: success_json end diff --git a/app/controllers/static_controller.rb b/app/controllers/static_controller.rb index 76a2085883..196a4fe02c 100644 --- a/app/controllers/static_controller.rb +++ b/app/controllers/static_controller.rb @@ -160,8 +160,11 @@ class StaticController < ApplicationController format.js do # https://github.com/w3c/ServiceWorker/blob/master/explainer.md#updating-a-service-worker # Maximum cache that the service worker will respect is 24 hours. - immutable_for 24.hours + # However, ensure that these may be cached and served for longer on servers. + immutable_for 1.year + path = File.expand_path(Rails.root + "public/assets/#{Rails.application.assets_manifest.assets['service-worker.js']}") + response.headers["Last-Modified"] = File.ctime(path).httpdate render( plain: Rails.application.assets_manifest.find_sources('service-worker.js').first, content_type: 'application/javascript' diff --git a/app/controllers/tags_controller.rb b/app/controllers/tags_controller.rb index 67c4ee54d3..a673bb06d0 100644 --- a/app/controllers/tags_controller.rb +++ b/app/controllers/tags_controller.rb @@ -111,7 +111,6 @@ class TagsController < ::ApplicationController tag.name = new_tag_name if tag.save StaffActionLogger.new(current_user).log_custom('renamed_tag', previous_value: params[:tag_id], new_value: new_tag_name) - DiscourseEvent.trigger(:tag_updated, tag) render json: { tag: { id: new_tag_name } } else render_json_error tag.errors.full_messages @@ -277,10 +276,14 @@ class TagsController < ::ApplicationController def construct_url_with(action, opts) method = url_method(opts) - url = if action == :prev - public_send(method, opts.merge(prev_page_params(opts))) - else # :next - public_send(method, opts.merge(next_page_params(opts))) + begin + url = if action == :prev + public_send(method, opts.merge(prev_page_params(opts))) + else # :next + public_send(method, opts.merge(next_page_params(opts))) + end + rescue ActionController::UrlGenerationError + raise Discourse::NotFound end url.sub('.json?', '?') end diff --git a/app/controllers/topics_controller.rb b/app/controllers/topics_controller.rb index b9334d490d..fd20607f9e 100644 --- a/app/controllers/topics_controller.rb +++ b/app/controllers/topics_controller.rb @@ -622,9 +622,12 @@ class TopicsController < ApplicationController topic_time = allowed_params[:topic_time].to_i timings = allowed_params[:timings].to_h || {} + # ensure we capture current user for the block + user = current_user + hijack do PostTiming.process_timings( - current_user, + user, topic_id, topic_time, timings.map { |post_number, t| [post_number.to_i, t.to_i] }, diff --git a/app/controllers/users/omniauth_callbacks_controller.rb b/app/controllers/users/omniauth_callbacks_controller.rb index 3341ff44f4..9f708bd0cf 100644 --- a/app/controllers/users/omniauth_callbacks_controller.rb +++ b/app/controllers/users/omniauth_callbacks_controller.rb @@ -120,6 +120,7 @@ class Users::OmniauthCallbacksController < ApplicationController def user_found(user) if user.totp_enabled? @auth_result.omniauth_disallow_totp = true + @auth_result.email = user.email return end diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb index 5b47b9c6f6..548ce754c6 100644 --- a/app/controllers/users_controller.rb +++ b/app/controllers/users_controller.rb @@ -357,7 +357,7 @@ class UsersController < ApplicationController authentication = UserAuthenticator.new(user, session) if !authentication.has_authenticator? && !SiteSetting.enable_local_logins - return render body: nil, status: 500 + return render body: nil, status: :forbidden end authentication.start @@ -749,7 +749,7 @@ class UsersController < ApplicationController enqueue_activation_email render json: success_json else - render_json_error(@user) + render_json_error(primary_email) end end end diff --git a/app/jobs/regular/emit_web_hook_event.rb b/app/jobs/regular/emit_web_hook_event.rb index 5ec6f4fa68..db90dd0401 100644 --- a/app/jobs/regular/emit_web_hook_event.rb +++ b/app/jobs/regular/emit_web_hook_event.rb @@ -2,8 +2,13 @@ require 'excon' module Jobs class EmitWebHookEvent < Jobs::Base + PING_EVENT = 'ping'.freeze + def execute(args) - [:web_hook_id, :event_type].each do |key| + %i{ + web_hook_id + event_type + }.each do |key| raise Discourse::InvalidParameters.new(key) unless args[key].present? end @@ -19,8 +24,8 @@ module Jobs return if web_hook.category_ids.present? && (!args[:category_id].present? || !web_hook.category_ids.include?(args[:category_id])) - event_type = args[:event_type].to_s - return unless self.send("setup_#{event_type}", args) + raise Discourse::InvalidParameters.new(:payload) unless args[:payload].present? + args[:payload] = JSON.parse(args[:payload]) end web_hook_request(args, web_hook) @@ -32,50 +37,8 @@ module Jobs Guardian.new(Discourse.system_user) end - def setup_post(args) - post = Post.with_deleted.find_by(id: args[:post_id]) - return if post.blank? - args[:payload] = WebHookPostSerializer.new(post, scope: guardian, root: false).as_json - end - - def setup_topic(args) - topic_view = TopicView.new(args[:topic_id], Discourse.system_user) - return if topic_view.blank? - args[:payload] = WebHookTopicViewSerializer.new(topic_view, scope: guardian, root: false).as_json - end - - def setup_user(args) - user = User.find_by(id: args[:user_id]) - return if user.blank? - args[:payload] = WebHookUserSerializer.new(user, scope: guardian, root: false).as_json - end - - def setup_group(args) - group = Group.find(args[:group_id]) - return if group.blank? - args[:payload] = WebHookGroupSerializer.new(group, scope: guardian, root: false).as_json - end - - def setup_category(args) - category = Category.find(args[:category_id]) - return if category.blank? - args[:payload] = WebHookCategorySerializer.new(category, scope: guardian, root: false).as_json - end - - def setup_tag(args) - tag = Tag.find(args[:tag_id]) - return if tag.blank? - args[:payload] = TagSerializer.new(tag, scope: guardian, root: false).as_json - end - - def setup_flag(args) - flag = PostAction.find(args[:flag_id]) - return if flag.blank? - args[:payload] = WebHookFlagSerializer.new(flag, scope: guardian, root: false).as_json - end - def ping_event?(event_type) - event_type.to_s == 'ping'.freeze + PING_EVENT == event_type.to_s end def build_web_hook_body(args, web_hook) @@ -89,7 +52,6 @@ module Jobs end new_body = Plugin::Filter.apply(:after_build_web_hook_body, self, body) - MultiJson.dump(new_body) end @@ -120,7 +82,7 @@ module Jobs 'Content-Length' => body.bytesize, 'Content-Type' => content_type, 'Host' => uri.host, - 'User-Agent' => "Discourse/" + Discourse::VERSION::STRING, + 'User-Agent' => "Discourse/#{Discourse::VERSION::STRING}", 'X-Discourse-Instance' => Discourse.base_url, 'X-Discourse-Event-Id' => web_hook_event.id, 'X-Discourse-Event-Type' => args[:event_type] @@ -129,7 +91,7 @@ module Jobs headers['X-Discourse-Event'] = args[:event_name].to_s if args[:event_name].present? if web_hook.secret.present? - headers['X-Discourse-Event-Signature'] = "sha256=" + OpenSSL::HMAC.hexdigest("sha256", web_hook.secret, body) + headers['X-Discourse-Event-Signature'] = "sha256=#{OpenSSL::HMAC.hexdigest("sha256", web_hook.secret, body)}" end now = Time.zone.now diff --git a/app/jobs/regular/export_csv_file.rb b/app/jobs/regular/export_csv_file.rb index a95e43a235..2ebfb75df7 100644 --- a/app/jobs/regular/export_csv_file.rb +++ b/app/jobs/regular/export_csv_file.rb @@ -183,11 +183,11 @@ module Jobs report_hash = {} Report.find(@extra[:name], @extra).data.each do |row| - report_hash[row[:x].to_s(:db)] = row[:y].to_s(:db) + report_hash[row[:x].to_s] = row[:y].to_s end (@extra[:start_date].to_date..@extra[:end_date].to_date).each do |date| - yield [date.to_s(:db), report_hash.fetch(date.to_s(:db), 0)] + yield [date.to_s(:db), report_hash.fetch(date.to_s, 0)] end end diff --git a/app/jobs/regular/notify_category_change.rb b/app/jobs/regular/notify_category_change.rb new file mode 100644 index 0000000000..ed8a55c7f7 --- /dev/null +++ b/app/jobs/regular/notify_category_change.rb @@ -0,0 +1,15 @@ +require_dependency "post_alerter" + +module Jobs + class NotifyCategoryChange < Jobs::Base + def execute(args) + post = Post.find_by(id: args[:post_id]) + + if post&.topic + post_alerter = PostAlerter.new + post_alerter.notify_post_users(post, User.where(id: args[:notified_user_ids])) + post_alerter.notify_first_post_watchers(post, post_alerter.category_watchers(post.topic)) + end + end + end +end diff --git a/app/jobs/regular/post_alert.rb b/app/jobs/regular/post_alert.rb index 6fb5fb0616..6f5fc2523c 100644 --- a/app/jobs/regular/post_alert.rb +++ b/app/jobs/regular/post_alert.rb @@ -4,9 +4,12 @@ module Jobs class PostAlert < Jobs::Base def execute(args) - # maybe it was removed by the time we are making the post - post = Post.where(id: args[:post_id]).first - PostAlerter.post_created(post, args[:options] || {}) if post && post.topic + post = Post.find_by(id: args[:post_id]) + if post&.topic + opts = args[:options] || {} + new_record = true == args[:new_record] + PostAlerter.new(opts).after_save_post(post, new_record) + end end end diff --git a/app/jobs/regular/send_push_notification.rb b/app/jobs/regular/send_push_notification.rb index c27f1bbf27..355e2465cb 100644 --- a/app/jobs/regular/send_push_notification.rb +++ b/app/jobs/regular/send_push_notification.rb @@ -1,8 +1,8 @@ module Jobs class SendPushNotification < Jobs::Base def execute(args) - user = User.find(args[:user_id]) - PushNotificationPusher.push(user, args[:payload]) + user = User.find_by(id: args[:user_id]) + PushNotificationPusher.push(user, args[:payload]) if user end end end diff --git a/app/jobs/regular/update_username.rb b/app/jobs/regular/update_username.rb index e8a45d9366..c59275b716 100644 --- a/app/jobs/regular/update_username.rb +++ b/app/jobs/regular/update_username.rb @@ -11,9 +11,11 @@ module Jobs @raw_mention_regex = /(?:(? div.title").each do |div| + doc.css("aside.quote").each do |aside| + next unless div = aside.at_css("div.title") + + username_replaced = false + div.children.each do |child| - child.content = child.content.gsub(@cooked_quote_username_regex, @new_username) if child.text? + if child.text? + content = child.content + username_replaced = content.gsub!(@cooked_quote_username_regex, @new_username).present? + child.content = content if username_replaced + end + end + + if username_replaced || quotes_correct_user?(aside) + div.at_css("img.avatar")&.replace(@avatar_img) end - div.at_css("img.avatar")&.replace(@avatar_img) end doc.to_html end + + def quotes_correct_user?(aside) + Post.where( + topic_id: aside["data-topic"], + post_number: aside["data-post"] + ).pluck(:user_id).first == @user_id + end end end diff --git a/app/jobs/regular/user_email.rb b/app/jobs/regular/user_email.rb index 0eeea9ecbb..ac7e1d58d0 100644 --- a/app/jobs/regular/user_email.rb +++ b/app/jobs/regular/user_email.rb @@ -6,6 +6,8 @@ module Jobs # Asynchronously send an email to a user class UserEmail < Jobs::Base + sidekiq_options queue: 'low' + def execute(args) raise Discourse::InvalidParameters.new(:user_id) unless args[:user_id].present? raise Discourse::InvalidParameters.new(:type) unless args[:type].present? diff --git a/app/jobs/scheduled/poll_feed.rb b/app/jobs/scheduled/poll_feed.rb index 17f210f240..494fcf2a70 100644 --- a/app/jobs/scheduled/poll_feed.rb +++ b/app/jobs/scheduled/poll_feed.rb @@ -87,7 +87,7 @@ module Jobs private def parsed_feed - raw_feed = fetch_rss.encode("UTF-8", invalid: :replace, undef: :replace, replace: "") + raw_feed = fetch_rss return nil if raw_feed.blank? if SiteSetting.embed_username_key_from_feed.present? diff --git a/app/mailers/user_notifications.rb b/app/mailers/user_notifications.rb index cda60d2897..5e8a60af06 100644 --- a/app/mailers/user_notifications.rb +++ b/app/mailers/user_notifications.rb @@ -421,7 +421,7 @@ class UserNotifications < ActionMailer::Base end # category name - category = Topic.find_by(id: post.topic_id).category + category = Topic.find_by(id: post.topic_id)&.category if opts[:show_category_in_subject] && post.topic_id && category && !category.uncategorized? show_category_in_subject = category.name diff --git a/app/models/category.rb b/app/models/category.rb index 432509ded6..4d042500af 100644 --- a/app/models/category.rb +++ b/app/models/category.rb @@ -62,6 +62,7 @@ class Category < ActiveRecord::Base after_update :create_category_permalink, if: :saved_change_to_slug? after_commit :trigger_category_created_event, on: :create + after_commit :trigger_category_updated_event, on: :update after_commit :trigger_category_destroyed_event, on: :destroy belongs_to :parent_category, class_name: 'Category' @@ -512,14 +513,15 @@ SQL subcategory_list_style.end_with?("with_featured_topics") end - def trigger_category_created_event - DiscourseEvent.trigger(:category_created, self) - true - end - - def trigger_category_destroyed_event - DiscourseEvent.trigger(:category_destroyed, self) - true + %i{ + category_created + category_updated + category_destroyed + }.each do |event| + define_method("trigger_#{event}_event") do + DiscourseEvent.trigger(event, self) + true + end end end diff --git a/app/models/color_scheme.rb b/app/models/color_scheme.rb index 9f2f7eae5e..8b55f896eb 100644 --- a/app/models/color_scheme.rb +++ b/app/models/color_scheme.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require_dependency 'distributed_cache' class ColorScheme < ActiveRecord::Base @@ -108,12 +110,12 @@ class ColorScheme < ActiveRecord::Base def self.lookup_hex_for_name(name) enabled_color_scheme = Theme.where(key: SiteSetting.default_theme_key).first&.color_scheme - (enabled_color_scheme || base).colors.find { |c| c.name == name }.try(:hex) || :nil + (enabled_color_scheme || base).colors.find { |c| c.name == name }.try(:hex) || "nil" end def self.hex_for_name(name) hex_cache[name] ||= lookup_hex_for_name(name) - hex_cache[name] == :nil ? nil : hex_cache[name] + hex_cache[name] == "nil" ? nil : hex_cache[name] end def colors=(arr) diff --git a/app/models/concerns/has_custom_fields.rb b/app/models/concerns/has_custom_fields.rb index b33b4fa213..a2bc01b254 100644 --- a/app/models/concerns/has_custom_fields.rb +++ b/app/models/concerns/has_custom_fields.rb @@ -6,7 +6,7 @@ module HasCustomFields def self.append_field(target, key, value, types) if target.has_key?(key) target[key] = [target[key]] if !target[key].is_a? Array - target[key] << cast_custom_field(key, value, types) + target[key] << cast_custom_field(key, value, types, _return_array = false) else target[key] = cast_custom_field(key, value, types) end @@ -28,16 +28,26 @@ module HasCustomFields types[key] end - def self.cast_custom_field(key, value, types) + def self.cast_custom_field(key, value, types, return_array = true) return value unless type = get_custom_field_type(types, key) - case type - when :boolean then !!CUSTOM_FIELD_TRUE.include?(value) - when :integer then value.to_i - when :json then ::JSON.parse(value) - else - value + array = nil + + if Array === type + type = type[0] + array = true if return_array end + + result = + case type + when :boolean then !!CUSTOM_FIELD_TRUE.include?(value) + when :integer then value.to_i + when :json then ::JSON.parse(value) + else + value + end + + array ? [result] : result end end diff --git a/app/models/global_setting.rb b/app/models/global_setting.rb index f0fb74b5a3..c81430d2cd 100644 --- a/app/models/global_setting.rb +++ b/app/models/global_setting.rb @@ -85,6 +85,10 @@ class GlobalSetting end) == :true end + def self.s3_bucket_name + @s3_bucket_name ||= s3_bucket.downcase.split("/")[0] + end + # for testing def self.reset_s3_cache! @use_s3 = nil diff --git a/app/models/group.rb b/app/models/group.rb index 53f9d6a3ca..1a895775de 100644 --- a/app/models/group.rb +++ b/app/models/group.rb @@ -36,6 +36,7 @@ class Group < ActiveRecord::Base after_destroy :expire_cache after_commit :trigger_group_created_event, on: :create + after_commit :trigger_group_updated_event, on: :update after_commit :trigger_group_destroyed_event, on: :destroy def expire_cache @@ -584,14 +585,15 @@ class Group < ActiveRecord::Base self.member_of(groups, user).where("gu.owner") end - def trigger_group_created_event - DiscourseEvent.trigger(:group_created, self) - true - end - - def trigger_group_destroyed_event - DiscourseEvent.trigger(:group_destroyed, self) - true + %i{ + group_created + group_updated + group_destroyed + }.each do |event| + define_method("trigger_#{event}_event") do + DiscourseEvent.trigger(event, self) + true + end end protected diff --git a/app/models/invite.rb b/app/models/invite.rb index 6b63855f01..0065d69c47 100644 --- a/app/models/invite.rb +++ b/app/models/invite.rb @@ -139,7 +139,7 @@ class Invite < ActiveRecord::Base end else if topic && topic.category && Guardian.new(invited_by).can_invite_to?(topic) - group_ids = topic.category.groups.pluck(:id) - invite.invited_groups.pluck(:group_id) + group_ids = topic.category.groups.where(automatic: false).pluck(:id) - invite.invited_groups.pluck(:group_id) group_ids.each { |group_id| invite.invited_groups.create!(group_id: group_id) } end end diff --git a/app/models/notification.rb b/app/models/notification.rb index 48e3293c5c..8e213851bc 100644 --- a/app/models/notification.rb +++ b/app/models/notification.rb @@ -58,27 +58,24 @@ class Notification < ActiveRecord::Base end def self.mark_posts_read(user, topic_id, post_numbers) - count = Notification - .where(user_id: user.id, - topic_id: topic_id, - post_number: post_numbers, - read: false) - .update_all("read = 't'") - - if count > 0 - user.publish_notifications_state - end - - count + Notification + .where( + user_id: user.id, + topic_id: topic_id, + post_number: post_numbers, + read: false + ) + .update_all(read: true) end def self.read(user, notification_ids) - count = Notification.where(user_id: user.id) - .where(id: notification_ids) - .where(read: false) + Notification + .where( + id: notification_ids, + user_id: user.id, + read: false + ) .update_all(read: true) - - user.publish_notifications_state if count > 0 end def self.interesting_after(min_date) @@ -202,7 +199,11 @@ class Notification < ActiveRecord::Base protected def refresh_notification_count - user.publish_notifications_state + begin + user.reload.publish_notifications_state + rescue ActiveRecord::RecordNotFound + # happens when we delete a user + end end def send_email diff --git a/app/models/post.rb b/app/models/post.rb index def180ffe5..142066cead 100644 --- a/app/models/post.rb +++ b/app/models/post.rb @@ -48,7 +48,7 @@ class Post < ActiveRecord::Base has_many :post_details has_many :post_revisions - has_many :revisions, foreign_key: :post_id, class_name: 'PostRevision' + has_many :revisions, -> { order(:number) }, foreign_key: :post_id, class_name: 'PostRevision' has_many :user_actions, foreign_key: :target_post_id diff --git a/app/models/post_action.rb b/app/models/post_action.rb index 3bab03db7b..479091d8af 100644 --- a/app/models/post_action.rb +++ b/app/models/post_action.rb @@ -245,7 +245,7 @@ SQL title = I18n.t("post_action_types.#{post_action_type}.email_title", title: post.topic.title, locale: SiteSetting.default_locale) body = I18n.t("post_action_types.#{post_action_type}.email_body", message: opts[:message], link: "#{Discourse.base_url}#{post.url}", locale: SiteSetting.default_locale) warning = opts[:is_warning] if opts[:is_warning].present? - title = title.truncate(255, separator: /\s/) + title = title.truncate(SiteSetting.max_topic_title_length, separator: /\s/) opts = { archetype: Archetype.private_message, diff --git a/app/models/quoted_post.rb b/app/models/quoted_post.rb index ecfe19e73d..c6d24675f5 100644 --- a/app/models/quoted_post.rb +++ b/app/models/quoted_post.rb @@ -10,7 +10,8 @@ class QuotedPost < ActiveRecord::Base doc = Nokogiri::HTML.fragment(post.cooked) uniq = {} - ids = [] + + exec_sql("DELETE FROM quoted_posts WHERE post_id = :post_id", post_id: post.id) doc.css("aside.quote[data-topic]").each do |a| topic_id = a['data-topic'].to_i @@ -22,34 +23,26 @@ class QuotedPost < ActiveRecord::Base begin # It would be so much nicer if we used post_id in quotes - results = exec_sql "INSERT INTO quoted_posts(post_id, quoted_post_id, created_at, updated_at) - SELECT :post_id, p.id, current_timestamp, current_timestamp - FROM posts p - LEFT JOIN quoted_posts q on q.post_id = :post_id AND q.quoted_post_id = p.id - WHERE post_number = :post_number AND - topic_id = :topic_id AND - q.id IS NULL - RETURNING quoted_post_id - ", post_id: post.id, post_number: post_number, topic_id: topic_id - - results = results.to_a - ids << results[0]["quoted_post_id"].to_i if results.length > 0 + exec_sql(<<~SQL, post_id: post.id, post_number: post_number, topic_id: topic_id) + INSERT INTO quoted_posts (post_id, quoted_post_id, created_at, updated_at) + SELECT :post_id, p.id, current_timestamp, current_timestamp + FROM posts p + LEFT JOIN quoted_posts q on q.post_id = :post_id AND q.quoted_post_id = p.id + WHERE post_number = :post_number AND + topic_id = :topic_id AND + q.id IS NULL + SQL rescue ActiveRecord::RecordNotUnique, PG::UniqueViolation # it's fine end end - if ids.length > 0 - exec_sql "DELETE FROM quoted_posts WHERE post_id = :post_id AND quoted_post_id NOT IN (:ids)", - post_id: post.id, ids: ids - end - # simplest place to add this code reply_quoted = false if post.reply_to_post_number reply_post_id = Post.where(topic_id: post.topic_id, post_number: post.reply_to_post_number).pluck(:id).first - reply_quoted = !!(reply_post_id && ids.include?(reply_post_id)) + reply_quoted = reply_post_id.present? && QuotedPost.where(post_id: post.id, quoted_post_id: reply_post_id).count > 0 end if reply_quoted != post.reply_quoted diff --git a/app/models/report.rb b/app/models/report.rb index 744275b155..87452154cb 100644 --- a/app/models/report.rb +++ b/app/models/report.rb @@ -4,7 +4,8 @@ class Report attr_accessor :type, :data, :total, :prev30Days, :start_date, :end_date, :category_id, :group_id, :labels, :async, - :prev_period, :facets, :limit, :processing, :average, :percent + :prev_period, :facets, :limit, :processing, :average, :percent, + :higher_is_better def self.default_days 30 @@ -14,6 +15,9 @@ class Report @type = type @start_date ||= Report.default_days.days.ago.beginning_of_day @end_date ||= Time.zone.now.end_of_day + @average = false + @percent = false + @higher_is_better = true end def self.cache_key(report) @@ -54,7 +58,8 @@ class Report labels: labels, processing: self.processing, average: self.average, - percent: self.percent + percent: self.percent, + higher_is_better: self.higher_is_better }.tap do |json| json[:total] = total if total json[:prev_period] = prev_period if prev_period @@ -83,8 +88,9 @@ class Report report.facets = opts[:facets] || [:total, :prev30Days] report.limit = opts[:limit] if opts[:limit] report.processing = false - report.average = opts[:average] || false - report.percent = opts[:percent] || false + report.average = opts[:average] if opts[:average] + report.percent = opts[:percent] if opts[:percent] + report.higher_is_better = opts[:higher_is_better] if opts[:higher_is_better] report end @@ -278,6 +284,7 @@ class Report end def self.report_time_to_first_response(report) + report.higher_is_better = false report.data = [] Topic.time_to_first_response_per_day(report.start_date, report.end_date, category_id: report.category_id).each do |r| report.data << { x: Date.parse(r["date"]), y: r["hours"].to_f.round(2) } @@ -334,13 +341,18 @@ class Report def self.report_users_by_trust_level(report) report.data = [] + User.real.group('trust_level').count.sort.each do |level, count| - report.data << { key: TrustLevel.levels[level.to_i], x: level.to_i, y: count } + key = TrustLevel.levels[level.to_i] + url = Proc.new { |key| "/admin/users/list/#{key}" } + report.data << { url: url.call(key), key: key, x: level.to_i, y: count } end end # Post action counts: def self.report_flags(report) + report.higher_is_better = false + basic_report_about report, PostAction, :flag_count_by_date, report.start_date, report.end_date, report.category_id countable = PostAction.where(post_action_type_id: PostActionType.flag_types_without_custom.values) countable = countable.joins(post: :topic).where("topics.category_id = ?", report.category_id) if report.category_id @@ -409,19 +421,20 @@ class Report def self.report_users_by_type(report) report.data = [] - label = Proc.new { |key| I18n.t("reports.users_by_type.xaxis_labels.#{key}") } + label = Proc.new { |x| I18n.t("reports.users_by_type.xaxis_labels.#{x}") } + url = Proc.new { |key| "/admin/users/list/#{key}" } admins = User.real.admins.count - report.data << { key: "admins", x: label.call("admin"), y: admins } if admins > 0 + report.data << { url: url.call("admins"), icon: "shield", key: "admins", x: label.call("admin"), y: admins } if admins > 0 moderators = User.real.moderators.count - report.data << { key: "moderators", x: label.call("moderator"), y: moderators } if moderators > 0 + report.data << { url: url.call("moderators"), icon: "shield", key: "moderators", x: label.call("moderator"), y: moderators } if moderators > 0 suspended = User.real.suspended.count - report.data << { key: "suspended", x: label.call("suspended"), y: suspended } if suspended > 0 + report.data << { url: url.call("suspended"), icon: "ban", key: "suspended", x: label.call("suspended"), y: suspended } if suspended > 0 silenced = User.real.silenced.count - report.data << { key: "silenced", x: label.call("silenced"), y: silenced } if silenced > 0 + report.data << { url: url.call("silenced"), icon: "ban", key: "silenced", x: label.call("silenced"), y: silenced } if silenced > 0 end def self.report_top_referred_topics(report) diff --git a/app/models/site_setting.rb b/app/models/site_setting.rb index 8f8332a39c..ec8b8e7624 100644 --- a/app/models/site_setting.rb +++ b/app/models/site_setting.rb @@ -133,7 +133,7 @@ class SiteSetting < ActiveRecord::Base end def self.absolute_base_url - bucket = SiteSetting.enable_s3_uploads ? Discourse.store.s3_bucket_name : GlobalSetting.s3_bucket + bucket = SiteSetting.enable_s3_uploads ? Discourse.store.s3_bucket_name : GlobalSetting.s3_bucket_name # cf. http://docs.aws.amazon.com/general/latest/gr/rande.html#s3_region if SiteSetting.Upload.s3_region == "us-east-1" diff --git a/app/models/tag.rb b/app/models/tag.rb index 62aee017d3..46ef77bde7 100644 --- a/app/models/tag.rb +++ b/app/models/tag.rb @@ -17,6 +17,7 @@ class Tag < ActiveRecord::Base after_save :index_search after_commit :trigger_tag_created_event, on: :create + after_commit :trigger_tag_updated_event, on: :update after_commit :trigger_tag_destroyed_event, on: :destroy def self.ensure_consistency! @@ -124,14 +125,15 @@ class Tag < ActiveRecord::Base SearchIndexer.index(self) end - def trigger_tag_created_event - DiscourseEvent.trigger(:tag_created, self) - true - end - - def trigger_tag_destroyed_event - DiscourseEvent.trigger(:tag_destroyed, self) - true + %i{ + tag_created + tag_updated + tag_destroyed + }.each do |event| + define_method("trigger_#{event}_event") do + DiscourseEvent.trigger(event, self) + true + end end end diff --git a/app/models/theme.rb b/app/models/theme.rb index 024218ae93..5dfcd54b3e 100644 --- a/app/models/theme.rb +++ b/app/models/theme.rb @@ -8,6 +8,7 @@ class Theme < ActiveRecord::Base @cache = DistributedCache.new('theme') + belongs_to :user belongs_to :color_scheme has_many :theme_fields, dependent: :destroy has_many :theme_settings, dependent: :destroy diff --git a/app/models/topic.rb b/app/models/topic.rb index 4ee0068001..78cc39584e 100644 --- a/app/models/topic.rb +++ b/app/models/topic.rb @@ -446,6 +446,7 @@ class Topic < ActiveRecord::Base @post_numbers = nil @public_topic_timer = nil @private_topic_timer = nil + @is_category_topic = nil super(options) end @@ -674,13 +675,9 @@ SQL CategoryUser.auto_watch(category_id: new_category.id, topic_id: self.id) CategoryUser.auto_track(category_id: new_category.id, topic_id: self.id) - post = self.ordered_posts.first - - if post - PostAlerter.new.notify_post_users( - post, - [post.user, post.last_editor].uniq - ) + if post = self.ordered_posts.first + notified_user_ids = [post.user_id, post.last_editor_id].uniq + Jobs.enqueue(:notify_category_change, post_id: post.id, notified_user_ids: notified_user_ids) end end @@ -781,8 +778,7 @@ SQL last_post = posts.order('post_number desc').where('not hidden AND posts.deleted_at IS NULL').first if last_post - # ensure all the notifications are out - PostAlerter.new.after_save_post(last_post) + Jobs.enqueue(:post_alert, post_id: last_post.id) add_small_action(user, "invited_group", group.name) group_id = group.id @@ -1341,6 +1337,10 @@ SQL private_messages.with_subtype(topic_subtype).where('topics.created_at >= ? AND topics.created_at <= ?', start_date, end_date).group('date(topics.created_at)').order('date(topics.created_at)').count end + def is_category_topic? + @is_category_topic ||= Category.exists?(topic_id: self.id.to_i) + end + private def update_category_topic_count_by(num) diff --git a/app/models/topic_link_click.rb b/app/models/topic_link_click.rb index ce0f7fcbe1..422c974bfd 100644 --- a/app/models/topic_link_click.rb +++ b/app/models/topic_link_click.rb @@ -7,7 +7,6 @@ class TopicLinkClick < ActiveRecord::Base belongs_to :user validates_presence_of :topic_link_id - validates_presence_of :ip_address WHITELISTED_REDIRECT_HOSTNAMES = Set.new(%W{www.youtube.com youtu.be}) @@ -108,6 +107,7 @@ class TopicLinkClick < ActiveRecord::Base rate_key = "link-clicks:#{link.id}:#{args[:user_id] || args[:ip]}" if $redis.setnx(rate_key, "1") $redis.expire(rate_key, 1.day.to_i) + args[:ip] = nil if args[:user_id] create!(topic_link_id: link.id, user_id: args[:user_id], ip_address: args[:ip]) end @@ -125,7 +125,7 @@ end # user_id :integer # created_at :datetime not null # updated_at :datetime not null -# ip_address :inet not null +# ip_address :inet # # Indexes # diff --git a/app/models/upload.rb b/app/models/upload.rb index 055b396e27..754e5d7f69 100644 --- a/app/models/upload.rb +++ b/app/models/upload.rb @@ -84,8 +84,8 @@ class Upload < ActiveRecord::Base # always try to get the path uri = begin - URI(url) - rescue URI::InvalidURIError + URI(URI.unescape(url)) + rescue URI::InvalidURIError, URI::InvalidComponentError end url = uri.path if uri.try(:scheme) diff --git a/app/models/user.rb b/app/models/user.rb index 765050e92f..90f5064c8f 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -208,7 +208,8 @@ class User < ActiveRecord::Base def self.username_available?(username, email = nil) lower = username.downcase return false if reserved_username?(lower) - return true if !User.exists?(username_lower: lower) + return true if User.exec_sql(User::USERNAME_EXISTS_SQL, username: lower).count == 0 + # staged users can use the same username since they will take over the account email.present? && User.joins(:user_emails).exists?(staged: true, username_lower: lower, user_emails: { primary: true, email: email }) end @@ -286,9 +287,9 @@ class User < ActiveRecord::Base user end - def self.suggest_name(email) - return "" if email.blank? - email[/\A[^@]+/].tr(".", " ").titleize + def self.suggest_name(string) + return "" if string.blank? + (string[/\A[^@]+/].presence || string[/[^@]+\z/]).tr(".", " ").titleize end def self.find_by_username_or_email(username_or_email) @@ -376,14 +377,15 @@ class User < ActiveRecord::Base def unread_notifications_of_type(notification_type) # perf critical, much more efficient than AR - sql = " - SELECT COUNT(*) FROM notifications n - LEFT JOIN topics t ON n.topic_id = t.id - WHERE - t.deleted_at IS NULL AND - n.notification_type = :type AND - n.user_id = :user_id AND - NOT read" + sql = <<~SQL + SELECT COUNT(*) + FROM notifications n + LEFT JOIN topics t ON t.id = n.topic_id + WHERE t.deleted_at IS NULL + AND n.notification_type = :type + AND n.user_id = :user_id + AND NOT read + SQL User.exec_sql(sql, user_id: id, type: notification_type).getvalue(0, 0).to_i end @@ -393,24 +395,25 @@ class User < ActiveRecord::Base end def unread_notifications - @unread_notifications ||= - begin - # perf critical, much more efficient than AR - sql = " - SELECT COUNT(*) FROM notifications n - LEFT JOIN topics t ON n.topic_id = t.id - WHERE - t.deleted_at IS NULL AND - n.notification_type <> :pm AND - n.user_id = :user_id AND - NOT read AND - n.id > :seen_notification_id" + @unread_notifications ||= begin + # perf critical, much more efficient than AR + sql = <<~SQL + SELECT COUNT(*) + FROM notifications n + LEFT JOIN topics t ON t.id = n.topic_id + WHERE t.deleted_at IS NULL + AND n.notification_type <> :pm + AND n.user_id = :user_id + AND n.id > :seen_notification_id + AND NOT read + SQL - User.exec_sql(sql, user_id: id, - seen_notification_id: seen_notification_id, - pm: Notification.types[:private_message]) - .getvalue(0, 0).to_i - end + User.exec_sql(sql, + user_id: id, + seen_notification_id: seen_notification_id, + pm: Notification.types[:private_message] + ).getvalue(0, 0).to_i + end end def total_unread_notifications @@ -439,8 +442,7 @@ class User < ActiveRecord::Base end def publish_notifications_state - # publish last notification json with the message so we - # can apply an update + # publish last notification json with the message so we can apply an update notification = notifications.visible.order('notifications.id desc').first json = NotificationSerializer.new(notification).as_json if notification @@ -476,17 +478,17 @@ class User < ActiveRecord::Base [id.to_i, read] end - MessageBus.publish("/notification/#{id}", - { unread_notifications: unread_notifications, - unread_private_messages: unread_private_messages, - total_unread_notifications: total_unread_notifications, - read_first_notification: read_first_notification?, - last_notification: json, - recent: recent, - seen_notification_id: seen_notification_id - }, - user_ids: [id] # only publish the notification to this user - ) + payload = { + unread_notifications: unread_notifications, + unread_private_messages: unread_private_messages, + total_unread_notifications: total_unread_notifications, + read_first_notification: read_first_notification?, + last_notification: json, + recent: recent, + seen_notification_id: seen_notification_id, + } + + MessageBus.publish("/notification/#{id}", payload, user_ids: [id]) end # A selection of people to autocomplete on @mention diff --git a/app/models/user_action.rb b/app/models/user_action.rb index 20a3acde6c..f36c034b0e 100644 --- a/app/models/user_action.rb +++ b/app/models/user_action.rb @@ -212,6 +212,7 @@ SQL p.hidden, p.post_type, p.action_code, + pc.value AS action_code_who, p.edit_reason, t.category_id FROM user_actions as a @@ -222,6 +223,7 @@ SQL JOIN users pu on pu.id = COALESCE(p.user_id, t.user_id) JOIN users au on au.id = a.user_id LEFT JOIN categories c on c.id = t.category_id + LEFT JOIN post_custom_fields pc ON pc.post_id = a.target_post_id AND pc.name = 'action_code_who' /*where*/ /*order_by*/ /*offset*/ diff --git a/app/models/user_history.rb b/app/models/user_history.rb index 7155d2ad3e..f500d83179 100644 --- a/app/models/user_history.rb +++ b/app/models/user_history.rb @@ -72,7 +72,14 @@ class UserHistory < ActiveRecord::Base post_edit: 53, topic_published: 54, recover_topic: 55, - post_approved: 56 + post_approved: 56, + create_badge: 57, + change_badge: 58, + delete_badge: 59, + removed_silence_user: 60, + removed_suspend_user: 61, + removed_unsilence_user: 62, + removed_unsuspend_user: 63, ) end @@ -87,6 +94,8 @@ class UserHistory < ActiveRecord::Base :change_site_text, :suspend_user, :unsuspend_user, + :removed_suspend_user, + :removed_unsuspend_user, :grant_badge, :revoke_badge, :check_email, @@ -103,6 +112,8 @@ class UserHistory < ActiveRecord::Base :create_category, :silence_user, :unsilence_user, + :removed_silence_user, + :removed_unsilence_user, :grant_admin, :revoke_admin, :grant_moderation, @@ -123,7 +134,10 @@ class UserHistory < ActiveRecord::Base :post_edit, :topic_published, :recover_topic, - :post_approved + :post_approved, + :create_badge, + :change_badge, + :delete_badge, ] end diff --git a/app/models/user_profile.rb b/app/models/user_profile.rb index 721d04196a..11ebf37cb5 100644 --- a/app/models/user_profile.rb +++ b/app/models/user_profile.rb @@ -140,7 +140,10 @@ class UserProfile < ActiveRecord::Base allowed_domains = SiteSetting.user_website_domains_whitelist return if (allowed_domains.blank? || self.website.blank?) - domain = URI.parse(self.website).host + domain = begin + URI.parse(self.website).host + rescue URI::InvalidURIError + end self.errors.add :base, (I18n.t('user.website.domain_not_allowed', domains: allowed_domains.split('|').join(", "))) unless allowed_domains.split('|').include?(domain) end diff --git a/app/models/user_profile_view.rb b/app/models/user_profile_view.rb index 716b26c07c..237318a101 100644 --- a/app/models/user_profile_view.rb +++ b/app/models/user_profile_view.rb @@ -1,5 +1,5 @@ class UserProfileView < ActiveRecord::Base - validates_presence_of :user_profile_id, :ip_address, :viewed_at + validates_presence_of :user_profile_id, :viewed_at belongs_to :user_profile @@ -9,6 +9,7 @@ class UserProfileView < ActiveRecord::Base if user_id return if user_id < 1 redis_key << ":user-#{user_id}" + ip = nil else redis_key << ":ip-#{ip}" end @@ -59,13 +60,12 @@ end # id :integer not null, primary key # user_profile_id :integer not null # viewed_at :datetime not null -# ip_address :inet not null +# ip_address :inet # user_id :integer # # Indexes # # index_user_profile_views_on_user_id (user_id) # index_user_profile_views_on_user_profile_id (user_profile_id) -# unique_profile_view_ip (viewed_at,ip_address,user_profile_id) UNIQUE -# unique_profile_view_user (viewed_at,user_id,user_profile_id) UNIQUE +# unique_profile_view_user_or_ip (viewed_at,user_id,ip_address,user_profile_id) UNIQUE # diff --git a/app/models/web_hook.rb b/app/models/web_hook.rb index dd8df00b67..c2c016741e 100644 --- a/app/models/web_hook.rb +++ b/app/models/web_hook.rb @@ -30,30 +30,72 @@ class WebHook < ActiveRecord::Base [WebHookEventType.find(WebHookEventType::POST)] end - def self.find_by_type(type) - WebHook.where(active: true) - .joins(:web_hook_event_types) - .where("web_hooks.wildcard_web_hook = ? OR web_hook_event_types.name = ?", true, type.to_s) - .uniq - end - - def self.enqueue_hooks(type, opts = {}) - find_by_type(type).each do |w| - Jobs.enqueue(:emit_web_hook_event, opts.merge(web_hook_id: w.id, event_type: type.to_s)) - end - end - - def self.enqueue_topic_hooks(event, topic, user = nil) - WebHook.enqueue_hooks(:topic, topic_id: topic.id, category_id: topic&.category_id, event_name: event.to_s) - end - - def self.enqueue_post_hooks(event, post, user = nil) - WebHook.enqueue_hooks(:post, post_id: post.id, category_id: post&.topic&.category_id, event_name: event.to_s) - end - def strip_url self.payload_url = (payload_url || "").strip.presence end + + def self.active_web_hooks(type) + WebHook.where(active: true) + .joins(:web_hook_event_types) + .where("web_hooks.wildcard_web_hook = ? OR web_hook_event_types.name = ?", true, type.to_s) + .distinct + end + + def self.enqueue_hooks(type, opts = {}) + active_web_hooks(type).each do |web_hook| + Jobs.enqueue(:emit_web_hook_event, opts.merge( + web_hook_id: web_hook.id, event_type: type.to_s + )) + end + end + + def self.enqueue_object_hooks(type, object, event, serializer = nil) + if active_web_hooks(type).exists? + serializer ||= "WebHook#{type.capitalize}Serializer".constantize + + WebHook.enqueue_hooks(type, + event_name: event.to_s, + payload: serializer.new(object, + scope: self.guardian, + root: false + ).to_json + ) + end + end + + def self.enqueue_topic_hooks(event, topic) + if active_web_hooks('topic').exists? + topic_view = TopicView.new(topic.id, Discourse.system_user) + + WebHook.enqueue_hooks(:topic, + category_id: topic&.category_id, + event_name: event.to_s, + payload: WebHookTopicViewSerializer.new(topic_view, + scope: self.guardian, + root: false + ).to_json + ) + end + end + + def self.enqueue_post_hooks(event, post) + if active_web_hooks('post').exists? + WebHook.enqueue_hooks(:post, + category_id: post&.topic&.category_id, + event_name: event.to_s, + payload: WebHookPostSerializer.new(post, + scope: self.guardian, + root: false + ).to_json + ) + end + end + + private + + def self.guardian + @guardian ||= Guardian.new(Discourse.system_user) + end end # == Schema Information diff --git a/app/serializers/basic_group_serializer.rb b/app/serializers/basic_group_serializer.rb index aec7f7cf85..26fb3ea2de 100644 --- a/app/serializers/basic_group_serializer.rb +++ b/app/serializers/basic_group_serializer.rb @@ -43,7 +43,7 @@ class BasicGroupSerializer < ApplicationSerializer end def include_has_messages? - staff? + staff? || scope.can_see_group_messages?(object) end def include_bio_raw? diff --git a/app/serializers/penalty_counts_serializer.rb b/app/serializers/penalty_counts_serializer.rb index 68d1641f14..94f5722ee0 100644 --- a/app/serializers/penalty_counts_serializer.rb +++ b/app/serializers/penalty_counts_serializer.rb @@ -1,5 +1,9 @@ class PenaltyCountsSerializer < ApplicationSerializer - attributes :silenced, :suspended + attributes :silenced, :suspended, :total + + def total + object.silenced + object.suspended + end def silenced object.silenced diff --git a/app/serializers/post_serializer.rb b/app/serializers/post_serializer.rb index f12ad4fcca..e66fa720fd 100644 --- a/app/serializers/post_serializer.rb +++ b/app/serializers/post_serializer.rb @@ -374,6 +374,10 @@ class PostSerializer < BasicPostSerializer object.revisions.size > 0 end + def include_hidden_reason_id? + object.hidden + end + private def topic diff --git a/app/serializers/theme_serializer.rb b/app/serializers/theme_serializer.rb index 8cf183b4a8..4938b5fac9 100644 --- a/app/serializers/theme_serializer.rb +++ b/app/serializers/theme_serializer.rb @@ -58,6 +58,8 @@ end class ThemeSerializer < ChildThemeSerializer attributes :color_scheme, :color_scheme_id, :user_selectable, :remote_theme_id, :settings + has_one :user, serializer: UserNameSerializer, embed: :object + has_many :theme_fields, serializer: ThemeFieldSerializer, embed: :objects has_many :child_themes, serializer: ChildThemeSerializer, embed: :objects has_one :remote_theme, serializer: RemoteThemeSerializer, embed: :objects diff --git a/app/serializers/topic_view_serializer.rb b/app/serializers/topic_view_serializer.rb index 7ca94fd87a..44479aa7e0 100644 --- a/app/serializers/topic_view_serializer.rb +++ b/app/serializers/topic_view_serializer.rb @@ -36,7 +36,6 @@ class TopicViewSerializer < ApplicationSerializer :deleted_at, :pending_posts_count, :user_id, - :pm_with_non_human_user?, :featured_link, :featured_link_root_domain, :pinned_globally, @@ -67,7 +66,8 @@ class TopicViewSerializer < ApplicationSerializer :unicode_title, :message_bus_last_id, :participant_count, - :destination_category_id + :destination_category_id, + :pm_with_non_human_user, # TODO: Split off into proper object / serializer def details @@ -281,6 +281,10 @@ class TopicViewSerializer < ApplicationSerializer private_message?(object.topic) end + def pm_with_non_human_user + object.topic.pm_with_non_human_user? + end + def participant_count object.participant_count end diff --git a/app/serializers/user_action_serializer.rb b/app/serializers/user_action_serializer.rb index c6abea6a5c..2aec75ceed 100644 --- a/app/serializers/user_action_serializer.rb +++ b/app/serializers/user_action_serializer.rb @@ -26,6 +26,7 @@ class UserActionSerializer < ApplicationSerializer :hidden, :post_type, :action_code, + :action_code_who, :edit_reason, :category_id, :closed, @@ -79,4 +80,12 @@ class UserActionSerializer < ApplicationSerializer object.topic_archived end + def include_action_code_who? + action_code_who.present? + end + + def action_code_who + object.action_code_who + end + end diff --git a/app/serializers/user_serializer.rb b/app/serializers/user_serializer.rb index b93aa2ee78..f7b56ebf4b 100644 --- a/app/serializers/user_serializer.rb +++ b/app/serializers/user_serializer.rb @@ -339,22 +339,36 @@ class UserSerializer < BasicUserSerializer User.system_avatar_template(object.username) end + def include_gravatar_avatar_upload_id? + object.user_avatar&.gravatar_upload_id + end + def gravatar_avatar_upload_id - object.user_avatar.try(:gravatar_upload_id) + object.user_avatar.gravatar_upload_id + end + + def include_gravatar_avatar_template? + include_gravatar_avatar_upload_id? end def gravatar_avatar_template - return unless gravatar_upload_id = object.user_avatar.try(:gravatar_upload_id) - User.avatar_template(object.username, gravatar_upload_id) + User.avatar_template(object.username, object.user_avatar.gravatar_upload_id) + end + + def include_custom_avatar_upload_id? + object.user_avatar&.custom_upload_id end def custom_avatar_upload_id - object.user_avatar.try(:custom_upload_id) + object.user_avatar.custom_upload_id + end + + def include_custom_avatar_template? + include_custom_avatar_upload_id? end def custom_avatar_template - return unless custom_upload_id = object.user_avatar.try(:custom_upload_id) - User.avatar_template(object.username, custom_upload_id) + User.avatar_template(object.username, object.user_avatar.custom_upload_id) end def has_title_badges diff --git a/app/serializers/web_hook_flag_serializer.rb b/app/serializers/web_hook_flag_serializer.rb index 67674fef8e..847ae810e3 100644 --- a/app/serializers/web_hook_flag_serializer.rb +++ b/app/serializers/web_hook_flag_serializer.rb @@ -8,7 +8,7 @@ class WebHookFlagSerializer < ApplicationSerializer :resolved_by def post - BasicPostSerializer.new(object.post, scope: scope, root: false).as_json + WebHookPostSerializer.new(object.post, scope: scope, root: false).as_json end def flag_type @@ -32,9 +32,7 @@ class WebHookFlagSerializer < ApplicationSerializer end def resolved_by - if object.disposed_by_id.present? - User.find(object.disposed_by_id).username - end + User.find(object.disposed_by_id).username end def include_resolved_by? diff --git a/app/serializers/web_hook_group_serializer.rb b/app/serializers/web_hook_group_serializer.rb index c580451db8..66264abcaf 100644 --- a/app/serializers/web_hook_group_serializer.rb +++ b/app/serializers/web_hook_group_serializer.rb @@ -1,4 +1,4 @@ -class WebHookGroupSerializer < GroupShowSerializer +class WebHookGroupSerializer < BasicGroupSerializer %i{ is_group_user diff --git a/app/serializers/web_hook_post_serializer.rb b/app/serializers/web_hook_post_serializer.rb index 31e214cecc..455c1383e7 100644 --- a/app/serializers/web_hook_post_serializer.rb +++ b/app/serializers/web_hook_post_serializer.rb @@ -12,6 +12,12 @@ class WebHookPostSerializer < PostSerializer can_delete can_recover can_wiki + actions_summary + can_view_edit_history + yours + primary_group_flair_url + primary_group_flair_bg_color + primary_group_flair_color }.each do |attr| define_method("include_#{attr}?") do false diff --git a/app/serializers/web_hook_topic_view_serializer.rb b/app/serializers/web_hook_topic_view_serializer.rb index 8c1aa0a3a7..1aa71ccfd1 100644 --- a/app/serializers/web_hook_topic_view_serializer.rb +++ b/app/serializers/web_hook_topic_view_serializer.rb @@ -1,6 +1,8 @@ require_dependency 'pinned_check' class WebHookTopicViewSerializer < TopicViewSerializer + attributes :created_by, + :last_poster %i{ post_stream @@ -11,9 +13,24 @@ class WebHookTopicViewSerializer < TopicViewSerializer draft_sequence message_bus_last_id suggested_topics + has_summary + actions_summary + current_post_number + chunk_size + topic_timer + private_topic_timer + details }.each do |attr| define_method("include_#{attr}?") do false end end + + def created_by + BasicUserSerializer.new(object.topic.user, scope: scope, root: false) + end + + def last_poster + BasicUserSerializer.new(object.topic.last_poster, scope: scope, root: false) + end end diff --git a/app/serializers/web_hook_user_serializer.rb b/app/serializers/web_hook_user_serializer.rb index e964174bad..d715e4b025 100644 --- a/app/serializers/web_hook_user_serializer.rb +++ b/app/serializers/web_hook_user_serializer.rb @@ -5,6 +5,31 @@ class WebHookUserSerializer < UserSerializer def staff_attributes(*attrs) end + %i{ + can_edit + can_edit_username + can_edit_email + can_edit_name + can_send_private_messages + can_send_private_message_to_user + uploaded_avatar_id + has_title_badges + bio_cooked + custom_fields + can_be_deleted + can_delete_all_posts + system_avatar_upload_id + gravatar_avatar_upload_id + custom_avatar_upload_id + can_change_bio + user_api_keys + group_users + }.each do |attr| + define_method("include_#{attr}?") do + false + end + end + def include_email? scope.is_admin? end diff --git a/app/services/post_action_notifier.rb b/app/services/post_action_notifier.rb index a25524b543..cc42feec42 100644 --- a/app/services/post_action_notifier.rb +++ b/app/services/post_action_notifier.rb @@ -41,7 +41,6 @@ class PostActionNotifier end def self.post_action_deleted(post_action) - return if @disabled # We only care about deleting post actions for now @@ -69,7 +68,6 @@ class PostActionNotifier end def self.post_action_created(post_action) - return if @disabled # We only notify on likes for now @@ -89,7 +87,6 @@ class PostActionNotifier end def self.after_create_post_revision(post_revision) - return if @disabled post = post_revision.post diff --git a/app/services/post_alerter.rb b/app/services/post_alerter.rb index 2bc5524cf4..476856253b 100644 --- a/app/services/post_alerter.rb +++ b/app/services/post_alerter.rb @@ -101,41 +101,44 @@ class PostAlerter topic = post.topic if topic.present? - cat_watchers = topic.category_users - .where(notification_level: CategoryUser.notification_levels[:watching_first_post]) - .pluck(:user_id) - - tag_watchers = topic.tag_users - .where(notification_level: TagUser.notification_levels[:watching_first_post]) - .pluck(:user_id) - - group_ids = topic.allowed_groups.pluck(:group_id) - - group_watchers = GroupUser.where( - group_id: group_ids, - notification_level: GroupUser.notification_levels[:watching_first_post] - ).pluck(:user_id) - - watchers = [cat_watchers, tag_watchers, group_watchers].flatten - + watchers = category_watchers(topic) + tag_watchers(topic) + group_watchers(topic) notify_first_post_watchers(post, watchers) end end end + def group_watchers(topic) + GroupUser.where( + group_id: topic.allowed_groups.pluck(:group_id), + notification_level: GroupUser.notification_levels[:watching_first_post] + ).pluck(:user_id) + end + + def tag_watchers(topic) + topic.tag_users + .where(notification_level: TagUser.notification_levels[:watching_first_post]) + .pluck(:user_id) + end + + def category_watchers(topic) + topic.category_users + .where(notification_level: CategoryUser.notification_levels[:watching_first_post]) + .pluck(:user_id) + end + def notify_first_post_watchers(post, user_ids) return if user_ids.blank? user_ids.uniq! + warn_if_not_sidekiq + # Don't notify the OP user_ids -= [post.user_id] users = User.where(id: user_ids) - Scheduler::Defer.later("Notify First Post Watchers") do - DiscourseEvent.trigger(:before_create_notifications_for_users, users, post) - users.each do |user| - create_notification(user, Notification.types[:watching_first_post], post) - end + DiscourseEvent.trigger(:before_create_notifications_for_users, users, post) + users.each do |user| + create_notification(user, Notification.types[:watching_first_post], post) end end @@ -171,14 +174,19 @@ class PostAlerter unread_posts(user, topic).count end - def destroy_notifications(user, type, topic) + def destroy_notifications(user, types, topic) return if user.blank? return unless Guardian.new(user).can_see?(topic) - user.notifications.where(notification_type: type, - topic_id: topic.id).destroy_all - # HACK so notification counts sync up correctly - user.reload + User.transaction do + user.notifications.where( + notification_type: types, + topic_id: topic.id + ).destroy_all + + # Reload so notification counts sync up correctly + user.reload + end end NOTIFIABLE_TYPES = [:mentioned, :replied, :quoted, :posted, :linked, :private_message, :group_mentioned].map { |t| @@ -323,9 +331,7 @@ class PostAlerter collapsed = false if COLLAPSED_NOTIFICATION_TYPES.include?(type) - COLLAPSED_NOTIFICATION_TYPES.each do |t| - destroy_notifications(user, t, post.topic) - end + destroy_notifications(user, COLLAPSED_NOTIFICATION_TYPES, post.topic) collapsed = true end @@ -376,7 +382,7 @@ class PostAlerter end # Create the notification - created = user.notifications.create( + created = user.notifications.create!( notification_type: type, topic_id: post.topic_id, post_number: post.post_number, @@ -403,6 +409,7 @@ class PostAlerter DiscourseEvent.trigger(:post_notification_alert, user, payload) end end + created.id ? created : nil end @@ -412,10 +419,16 @@ class PostAlerter end def push_notification(user, payload) + if user.push_subscriptions.exists? + Jobs.enqueue(:send_push_notification, user_id: user.id, payload: payload) + end + if SiteSetting.allow_user_api_key_scopes.split("|").include?("push") && SiteSetting.allowed_user_api_push_urls.present? clients = user.user_api_keys - .where("('push' = ANY(scopes) OR 'notifications' = ANY(scopes)) AND push_url IS NOT NULL AND position(push_url in ?) > 0 AND revoked_at IS NULL", - SiteSetting.allowed_user_api_push_urls) + .where("('push' = ANY(scopes) OR 'notifications' = ANY(scopes))") + .where("push_url IS NOT NULL") + .where("position(push_url IN ?) > 0", SiteSetting.allowed_user_api_push_urls) + .where("revoked_at IS NULL") .pluck(:client_id, :push_url) if clients.length > 0 @@ -479,11 +492,11 @@ class PostAlerter users = [users] unless users.is_a?(Array) users = users.reject { |u| u.staged? } if post.topic&.private_message? - Scheduler::Defer.later("Notify Users") do - DiscourseEvent.trigger(:before_create_notifications_for_users, users, post) - users.each do |u| - create_notification(u, Notification.types[type], post, opts) - end + warn_if_not_sidekiq + + DiscourseEvent.trigger(:before_create_notifications_for_users, users, post) + users.each do |u| + create_notification(u, Notification.types[type], post, opts) end users @@ -492,28 +505,28 @@ class PostAlerter def notify_pm_users(post, reply_to_user, notified) return unless post.topic - Scheduler::Defer.later("Notify PM Users") do - # users that aren't part of any mentioned groups - users = directly_targeted_users(post).reject { |u| notified.include?(u) } - DiscourseEvent.trigger(:before_create_notifications_for_users, users, post) - users.each do |user| - notification_level = TopicUser.get(post.topic, user)&.notification_level - if reply_to_user == user || notification_level == TopicUser.notification_levels[:watching] || user.staged? - create_notification(user, Notification.types[:private_message], post) - end - end + warn_if_not_sidekiq - # users that are part of all mentionned groups - users = indirectly_targeted_users(post).reject { |u| notified.include?(u) } - DiscourseEvent.trigger(:before_create_notifications_for_users, users, post) - users.each do |user| - case TopicUser.get(post.topic, user)&.notification_level - when TopicUser.notification_levels[:watching] - # only create a notification when watching the group - create_notification(user, Notification.types[:private_message], post) - when TopicUser.notification_levels[:tracking] - notify_group_summary(user, post) - end + # users that aren't part of any mentioned groups + users = directly_targeted_users(post).reject { |u| notified.include?(u) } + DiscourseEvent.trigger(:before_create_notifications_for_users, users, post) + users.each do |user| + notification_level = TopicUser.get(post.topic, user)&.notification_level + if reply_to_user == user || notification_level == TopicUser.notification_levels[:watching] || user.staged? + create_notification(user, Notification.types[:private_message], post) + end + end + + # users that are part of all mentionned groups + users = indirectly_targeted_users(post).reject { |u| notified.include?(u) } + DiscourseEvent.trigger(:before_create_notifications_for_users, users, post) + users.each do |user| + case TopicUser.get(post.topic, user)&.notification_level + when TopicUser.notification_levels[:watching] + # only create a notification when watching the group + create_notification(user, Notification.types[:private_message], post) + when TopicUser.notification_levels[:tracking] + notify_group_summary(user, post) end end end @@ -521,6 +534,8 @@ class PostAlerter def notify_post_users(post, notified) return unless post.topic + warn_if_not_sidekiq + condition = <<~SQL id IN ( SELECT user_id @@ -568,13 +583,15 @@ class PostAlerter exclude_user_ids = notified.map(&:id) notify = notify.where("id NOT IN (?)", exclude_user_ids) if exclude_user_ids.present? - Scheduler::Defer.later("Notify Post Users") do - DiscourseEvent.trigger(:before_create_notifications_for_users, notify, post) - notify.pluck(:id).each do |user_id| - user = User.find_by(id: user_id) - create_notification(user, Notification.types[:posted], post) - end + DiscourseEvent.trigger(:before_create_notifications_for_users, notify, post) + notify.pluck(:id).each do |user_id| + user = User.find_by(id: user_id) + create_notification(user, Notification.types[:posted], post) end end + def warn_if_not_sidekiq + Rails.logger.warn("PostAlerter.#{caller_locations(1, 1)[0].label} was called outside of sidekiq") unless Sidekiq.server? + end + end diff --git a/app/services/random_topic_selector.rb b/app/services/random_topic_selector.rb index 1ac2d8500a..a484c91be1 100644 --- a/app/services/random_topic_selector.rb +++ b/app/services/random_topic_selector.rb @@ -91,4 +91,8 @@ class RandomTopicSelector "random_topic_cache_#{category&.id}" end + def self.clear_cache! + $redis.delete_prefixed(cache_key) + end + end diff --git a/app/services/staff_action_logger.rb b/app/services/staff_action_logger.rb index ff137a0db5..07a47a4c48 100644 --- a/app/services/staff_action_logger.rb +++ b/app/services/staff_action_logger.rb @@ -12,11 +12,16 @@ class StaffActionLogger raise Discourse::InvalidParameters.new(:admin) unless @admin && @admin.is_a?(User) end + USER_FIELDS ||= %i{id username name created_at trust_level last_seen_at last_emailed_at} + def log_user_deletion(deleted_user, opts = {}) raise Discourse::InvalidParameters.new(:deleted_user) unless deleted_user && deleted_user.is_a?(User) - UserHistory.create(params(opts).merge(action: UserHistory.actions[:delete_user], - ip_address: deleted_user.ip_address.to_s, - details: [:id, :username, :name, :created_at, :trust_level, :last_seen_at, :last_emailed_at].map { |x| "#{x}: #{deleted_user.send(x)}" }.join("\n"))) + details = USER_FIELDS.map { |x| "#{x}: #{deleted_user.send(x)}" }.join("\n") + UserHistory.create!(params(opts).merge( + action: UserHistory.actions[:delete_user], + ip_address: deleted_user.ip_address.to_s, + details: details + )) end def log_custom(custom_type, details = nil) @@ -33,7 +38,7 @@ class StaffActionLogger attrs[:action] = UserHistory.actions[:custom_staff] attrs[:custom_type] = custom_type - UserHistory.create(attrs) + UserHistory.create!(attrs) end def log_post_deletion(deleted_post, opts = {}) @@ -54,9 +59,11 @@ class StaffActionLogger "raw: #{deleted_post.raw}" ] - UserHistory.create(params(opts).merge(action: UserHistory.actions[:delete_post], - post_id: deleted_post.id, - details: details.join("\n"))) + UserHistory.create!(params(opts).merge( + action: UserHistory.actions[:delete_post], + post_id: deleted_post.id, + details: details.join("\n") + )) end def log_topic_delete_recover(topic, action = "delete_topic", opts = {}) @@ -75,24 +82,31 @@ class StaffActionLogger details << "raw: #{first_post.raw}" end - UserHistory.create(params(opts).merge(action: UserHistory.actions[action.to_sym], - topic_id: topic.id, - details: details.join("\n"))) + UserHistory.create!(params(opts).merge( + action: UserHistory.actions[action.to_sym], + topic_id: topic.id, + details: details.join("\n") + )) end def log_trust_level_change(user, old_trust_level, new_trust_level, opts = {}) raise Discourse::InvalidParameters.new(:user) unless user && user.is_a?(User) raise Discourse::InvalidParameters.new(:old_trust_level) unless TrustLevel.valid? old_trust_level raise Discourse::InvalidParameters.new(:new_trust_level) unless TrustLevel.valid? new_trust_level - UserHistory.create!(params(opts).merge(action: UserHistory.actions[:change_trust_level], - target_user_id: user.id, - details: "old trust level: #{old_trust_level}\nnew trust level: #{new_trust_level}")) + UserHistory.create!(params(opts).merge( + action: UserHistory.actions[:change_trust_level], + target_user_id: user.id, + details: "old trust level: #{old_trust_level}\nnew trust level: #{new_trust_level}" + )) end def log_lock_trust_level(user, opts = {}) raise Discourse::InvalidParameters.new(:user) unless user && user.is_a?(User) - UserHistory.create!(params(opts).merge(action: UserHistory.actions[user.manual_locked_trust_level.nil? ? :unlock_trust_level : :lock_trust_level], - target_user_id: user.id)) + action = UserHistory.actions[user.manual_locked_trust_level.nil? ? :unlock_trust_level : :lock_trust_level] + UserHistory.create!(params(opts).merge( + action: action, + target_user_id: user.id + )) end def log_topic_published(topic, opts = {}) @@ -122,10 +136,12 @@ class StaffActionLogger def log_site_setting_change(setting_name, previous_value, new_value, opts = {}) raise Discourse::InvalidParameters.new(:setting_name) unless setting_name.present? && SiteSetting.respond_to?(setting_name) - UserHistory.create(params(opts).merge(action: UserHistory.actions[:change_site_setting], - subject: setting_name, - previous_value: previous_value, - new_value: new_value)) + UserHistory.create!(params(opts).merge( + action: UserHistory.actions[:change_site_setting], + subject: setting_name, + previous_value: previous_value, + new_value: new_value + )) end def theme_json(theme) @@ -157,41 +173,51 @@ class StaffActionLogger old_json, new_json = strip_duplicates(old_json, new_json) - UserHistory.create(params(opts).merge(action: UserHistory.actions[:change_theme], - subject: new_theme.name, - previous_value: old_json, - new_value: new_json)) + UserHistory.create!(params(opts).merge( + action: UserHistory.actions[:change_theme], + subject: new_theme.name, + previous_value: old_json, + new_value: new_json + )) end def log_theme_destroy(theme, opts = {}) raise Discourse::InvalidParameters.new(:theme) unless theme - UserHistory.create(params(opts).merge(action: UserHistory.actions[:delete_theme], - subject: theme.name, - previous_value: theme_json(theme))) + UserHistory.create!(params(opts).merge( + action: UserHistory.actions[:delete_theme], + subject: theme.name, + previous_value: theme_json(theme) + )) end def log_site_text_change(subject, new_text = nil, old_text = nil, opts = {}) raise Discourse::InvalidParameters.new(:subject) unless subject.present? - UserHistory.create!(params(opts).merge(action: UserHistory.actions[:change_site_text], - subject: subject, - previous_value: old_text, - new_value: new_text)) + UserHistory.create!(params(opts).merge( + action: UserHistory.actions[:change_site_text], + subject: subject, + previous_value: old_text, + new_value: new_text + )) end def log_username_change(user, old_username, new_username, opts = {}) raise Discourse::InvalidParameters.new(:user) unless user - UserHistory.create(params(opts).merge(action: UserHistory.actions[:change_username], - target_user_id: user.id, - previous_value: old_username, - new_value: new_username)) + UserHistory.create!(params(opts).merge( + action: UserHistory.actions[:change_username], + target_user_id: user.id, + previous_value: old_username, + new_value: new_username + )) end def log_name_change(user_id, old_name, new_name, opts = {}) raise Discourse::InvalidParameters.new(:user) unless user_id - UserHistory.create(params(opts).merge(action: UserHistory.actions[:change_name], - target_user_id: user_id, - previous_value: old_name, - new_value: new_name)) + UserHistory.create!(params(opts).merge( + action: UserHistory.actions[:change_name], + target_user_id: user_id, + previous_value: old_name, + new_value: new_name + )) end def log_user_suspend(user, reason, opts = {}) @@ -205,50 +231,96 @@ class StaffActionLogger details: details ) args[:post_id] = opts[:post_id] if opts[:post_id] - UserHistory.create(args) + UserHistory.create!(args) end def log_user_unsuspend(user, opts = {}) raise Discourse::InvalidParameters.new(:user) unless user - UserHistory.create(params(opts).merge(action: UserHistory.actions[:unsuspend_user], - target_user_id: user.id)) + UserHistory.create!(params(opts).merge( + action: UserHistory.actions[:unsuspend_user], + target_user_id: user.id + )) + end + + BADGE_FIELDS ||= %i{id name description long_description icon image badge_type_id + badge_grouping_id query allow_title multiple_grant listable target_posts + enabled auto_revoke show_posts system} + + def log_badge_creation(badge) + raise Discourse::InvalidParameters.new(:badge) unless badge + details = BADGE_FIELDS.map { |f| [f, badge.send(f)] }.select { |f, v| v.present? }.map { |f, v| "#{f}: #{v}" } + UserHistory.create!(params.merge( + action: UserHistory.actions[:create_badge], + details: details.join("\n") + )) + end + + def log_badge_change(badge) + raise Discourse::InvalidParameters.new(:badge) unless badge + details = ["id: #{badge.id}"] + badge.previous_changes.each { |f, values| details << "#{f}: #{values[1]}" if BADGE_FIELDS.include?(f.to_sym) } + UserHistory.create!(params.merge( + action: UserHistory.actions[:change_badge], + details: details.join("\n") + )) + end + + def log_badge_deletion(badge) + raise Discourse::InvalidParameters.new(:badge) unless badge + details = BADGE_FIELDS.map { |f| [f, badge.send(f)] }.select { |f, v| v.present? }.map { |f, v| "#{f}: #{v}" } + UserHistory.create!(params.merge( + action: UserHistory.actions[:delete_badge], + details: details.join("\n") + )) end def log_badge_grant(user_badge, opts = {}) raise Discourse::InvalidParameters.new(:user_badge) unless user_badge - UserHistory.create(params(opts).merge(action: UserHistory.actions[:grant_badge], - target_user_id: user_badge.user_id, - details: user_badge.badge.name)) + UserHistory.create!(params(opts).merge( + action: UserHistory.actions[:grant_badge], + target_user_id: user_badge.user_id, + details: user_badge.badge.name + )) end def log_badge_revoke(user_badge, opts = {}) raise Discourse::InvalidParameters.new(:user_badge) unless user_badge - UserHistory.create(params(opts).merge(action: UserHistory.actions[:revoke_badge], - target_user_id: user_badge.user_id, - details: user_badge.badge.name)) + UserHistory.create!(params(opts).merge( + action: UserHistory.actions[:revoke_badge], + target_user_id: user_badge.user_id, + details: user_badge.badge.name + )) end def log_check_email(user, opts = {}) raise Discourse::InvalidParameters.new(:user) unless user - UserHistory.create(params(opts).merge(action: UserHistory.actions[:check_email], - target_user_id: user.id)) + UserHistory.create!(params(opts).merge( + action: UserHistory.actions[:check_email], + target_user_id: user.id + )) end def log_show_emails(users, opts = {}) return if users.blank? - UserHistory.create(params(opts).merge(action: UserHistory.actions[:check_email], - details: users.map { |u| "[#{u.id}] #{u.username}" }.join("\n"))) + UserHistory.create!(params(opts).merge( + action: UserHistory.actions[:check_email], + details: users.map { |u| "[#{u.id}] #{u.username}" }.join("\n") + )) end def log_impersonate(user, opts = {}) raise Discourse::InvalidParameters.new(:user) unless user - UserHistory.create(params(opts).merge(action: UserHistory.actions[:impersonate], - target_user_id: user.id)) + UserHistory.create!(params(opts).merge( + action: UserHistory.actions[:impersonate], + target_user_id: user.id + )) end def log_roll_up(subnets, opts = {}) - UserHistory.create(params(opts).merge(action: UserHistory.actions[:roll_up], - details: subnets.join(", "))) + UserHistory.create!(params(opts).merge( + action: UserHistory.actions[:roll_up], + details: subnets.join(", ") + )) end def log_category_settings_change(category, category_params, old_permissions = nil) @@ -261,12 +333,14 @@ class StaffActionLogger end changed_attributes.each do |key, value| - UserHistory.create(params.merge(action: UserHistory.actions[:change_category_settings], - category_id: category.id, - context: category.url, - subject: key, - previous_value: value[0], - new_value: value[1])) + UserHistory.create!(params.merge( + action: UserHistory.actions[:change_category_settings], + category_id: category.id, + context: category.url, + subject: key, + previous_value: value[0], + new_value: value[1] + )) end end @@ -283,10 +357,12 @@ class StaffActionLogger details << "parent_category: #{parent_category.name}" end - UserHistory.create(params.merge(action: UserHistory.actions[:delete_category], - category_id: category.id, - details: details.join("\n"), - context: category.url)) + UserHistory.create!(params.merge( + action: UserHistory.actions[:delete_category], + category_id: category.id, + details: details.join("\n"), + context: category.url + )) end def log_category_creation(category) @@ -297,10 +373,12 @@ class StaffActionLogger "name: #{category.name}" ] - UserHistory.create(params.merge(action: UserHistory.actions[:create_category], - details: details.join("\n"), - category_id: category.id, - context: category.url)) + UserHistory.create!(params.merge( + action: UserHistory.actions[:create_category], + details: details.join("\n"), + category_id: category.id, + context: category.url + )) end def log_silence_user(user, opts = {}) @@ -313,109 +391,139 @@ class StaffActionLogger ) create_args[:post_id] = opts[:post_id] if opts[:post_id] - UserHistory.create(create_args) + UserHistory.create!(create_args) end def log_unsilence_user(user, opts = {}) raise Discourse::InvalidParameters.new(:user) unless user - UserHistory.create(params(opts).merge(action: UserHistory.actions[:unsilence_user], - target_user_id: user.id)) + UserHistory.create!(params(opts).merge( + action: UserHistory.actions[:unsilence_user], + target_user_id: user.id + )) end def log_disable_second_factor_auth(user, opts = {}) raise Discourse::InvalidParameters.new(:user) unless user - UserHistory.create(params(opts).merge(action: UserHistory.actions[:disabled_second_factor], - target_user_id: user.id)) + UserHistory.create!(params(opts).merge( + action: UserHistory.actions[:disabled_second_factor], + target_user_id: user.id + )) end def log_grant_admin(user, opts = {}) raise Discourse::InvalidParameters.new(:user) unless user - UserHistory.create(params(opts).merge(action: UserHistory.actions[:grant_admin], - target_user_id: user.id)) + UserHistory.create!(params(opts).merge( + action: UserHistory.actions[:grant_admin], + target_user_id: user.id + )) end def log_revoke_admin(user, opts = {}) raise Discourse::InvalidParameters.new(:user) unless user - UserHistory.create(params(opts).merge(action: UserHistory.actions[:revoke_admin], - target_user_id: user.id)) + UserHistory.create!(params(opts).merge( + action: UserHistory.actions[:revoke_admin], + target_user_id: user.id + )) end def log_grant_moderation(user, opts = {}) raise Discourse::InvalidParameters.new(:user) unless user - UserHistory.create(params(opts).merge(action: UserHistory.actions[:grant_moderation], - target_user_id: user.id)) + UserHistory.create!(params(opts).merge( + action: UserHistory.actions[:grant_moderation], + target_user_id: user.id + )) end def log_revoke_moderation(user, opts = {}) raise Discourse::InvalidParameters.new(:user) unless user - UserHistory.create(params(opts).merge(action: UserHistory.actions[:revoke_moderation], - target_user_id: user.id)) + UserHistory.create!(params(opts).merge( + action: UserHistory.actions[:revoke_moderation], + target_user_id: user.id + )) end def log_backup_create(opts = {}) - UserHistory.create(params(opts).merge(action: UserHistory.actions[:backup_create], - ip_address: @admin.ip_address.to_s)) + UserHistory.create!(params(opts).merge( + action: UserHistory.actions[:backup_create], + ip_address: @admin.ip_address.to_s + )) end def log_backup_download(backup, opts = {}) raise Discourse::InvalidParameters.new(:backup) unless backup - UserHistory.create(params(opts).merge(action: UserHistory.actions[:backup_download], - ip_address: @admin.ip_address.to_s, - details: backup.filename)) + UserHistory.create!(params(opts).merge( + action: UserHistory.actions[:backup_download], + ip_address: @admin.ip_address.to_s, + details: backup.filename + )) end def log_backup_destroy(backup, opts = {}) raise Discourse::InvalidParameters.new(:backup) unless backup - UserHistory.create(params(opts).merge(action: UserHistory.actions[:backup_destroy], - ip_address: @admin.ip_address.to_s, - details: backup.filename)) + UserHistory.create!(params(opts).merge( + action: UserHistory.actions[:backup_destroy], + ip_address: @admin.ip_address.to_s, + details: backup.filename + )) end def log_revoke_email(user, reason, opts = {}) - UserHistory.create(params(opts).merge(action: UserHistory.actions[:revoke_email], - target_user_id: user.id, - details: reason)) + UserHistory.create!(params(opts).merge( + action: UserHistory.actions[:revoke_email], + target_user_id: user.id, + details: reason + )) end def log_user_deactivate(user, reason, opts = {}) raise Discourse::InvalidParameters.new(:user) unless user - UserHistory.create(params(opts).merge(action: UserHistory.actions[:deactivate_user], - target_user_id: user.id, - details: reason)) + UserHistory.create!(params(opts).merge( + action: UserHistory.actions[:deactivate_user], + target_user_id: user.id, + details: reason + )) end def log_user_activate(user, reason, opts = {}) raise Discourse::InvalidParameters.new(:user) unless user - UserHistory.create(params(opts).merge(action: UserHistory.actions[:activate_user], - target_user_id: user.id, - details: reason)) + UserHistory.create!(params(opts).merge( + action: UserHistory.actions[:activate_user], + target_user_id: user.id, + details: reason + )) end def log_wizard_step(step, opts = {}) raise Discourse::InvalidParameters.new(:step) unless step - UserHistory.create(params(opts).merge(action: UserHistory.actions[:wizard_step], - context: step.id)) + UserHistory.create!(params(opts).merge( + action: UserHistory.actions[:wizard_step], + context: step.id + )) end def log_change_readonly_mode(state) - UserHistory.create(params.merge(action: UserHistory.actions[:change_readonly_mode], - previous_value: !state, - new_value: state)) + UserHistory.create!(params.merge( + action: UserHistory.actions[:change_readonly_mode], + previous_value: !state, + new_value: state + )) end def log_check_personal_message(topic, opts = {}) raise Discourse::InvalidParameters.new(:topic) unless topic && topic.is_a?(Topic) - UserHistory.create(params(opts).merge(action: UserHistory.actions[:check_personal_message], - topic_id: topic.id, - context: topic.relative_url)) + UserHistory.create!(params(opts).merge( + action: UserHistory.actions[:check_personal_message], + topic_id: topic.id, + context: topic.relative_url + )) end def log_post_approved(post, opts = {}) raise Discourse::InvalidParameters.new(:post) unless post && post.is_a?(Post) UserHistory.create!(params(opts).merge( action: UserHistory.actions[:post_approved], - post_id: post.id) - ) + post_id: post.id + )) end private diff --git a/app/services/user_authenticator.rb b/app/services/user_authenticator.rb index cd75e93122..b53c5de8b9 100644 --- a/app/services/user_authenticator.rb +++ b/app/services/user_authenticator.rb @@ -21,7 +21,10 @@ class UserAuthenticator end def finish - authenticator.after_create_account(@user, @session) if authenticator + if authenticator + authenticator.after_create_account(@user, @session) + confirm_email + end @session = nil end @@ -30,11 +33,18 @@ class UserAuthenticator end def authenticated? - @session && @session[:email] == @user.email && @session[:email_valid] + @session && @session[:email]&.downcase == @user.email.downcase && @session[:email_valid].to_s == "true" end private + def confirm_email + if authenticated? + EmailToken.confirm(@user.email_tokens.first.token) + @user.set_automatic_groups + end + end + def authenticator if authenticator_name @authenticator ||= @authenticator_finder.find_authenticator(authenticator_name) diff --git a/config/application.rb b/config/application.rb index ca68d22681..93efe88702 100644 --- a/config/application.rb +++ b/config/application.rb @@ -1,5 +1,16 @@ # frozen_string_literal: true +begin + if !RUBY_VERSION.match?(/^2\.[456]/) + STDERR.puts "Discourse requires Ruby 2.4.0 or up" + exit 1 + end +rescue + # no String#match? + STDERR.puts "Discourse requires Ruby 2.4.0 or up" + exit 1 +end + require File.expand_path('../boot', __FILE__) require 'rails/all' diff --git a/config/environments/test.rb b/config/environments/test.rb index 8a0fc8c6c9..7a6f94612a 100644 --- a/config/environments/test.rb +++ b/config/environments/test.rb @@ -50,6 +50,10 @@ Discourse::Application.configure do config.log_level = :fatal end + if defined? RspecErrorTracker + config.middleware.insert_after ActionDispatch::Flash, RspecErrorTracker + end + config.after_initialize do SiteSetting.defaults.tap do |s| s.set_regardless_of_locale(:s3_upload_bucket, 'bucket') diff --git a/config/initializers/012-web_hook_events.rb b/config/initializers/012-web_hook_events.rb index 17ab7ad0dd..671fbd56b7 100644 --- a/config/initializers/012-web_hook_events.rb +++ b/config/initializers/012-web_hook_events.rb @@ -1,6 +1,9 @@ -%i(topic_destroyed topic_recovered).each do |event| - DiscourseEvent.on(event) do |topic, user| - WebHook.enqueue_topic_hooks(event, topic, user) +%i( + topic_destroyed + topic_recovered +).each do |event| + DiscourseEvent.on(event) do |topic, _| + WebHook.enqueue_topic_hooks(event, topic) end end @@ -8,16 +11,17 @@ DiscourseEvent.on(:topic_status_updated) do |topic, status| WebHook.enqueue_topic_hooks("topic_#{status}_status_updated", topic) end -DiscourseEvent.on(:topic_created) do |topic, _, user| - WebHook.enqueue_topic_hooks(:topic_created, topic, user) +DiscourseEvent.on(:topic_created) do |topic, _, _| + WebHook.enqueue_topic_hooks(:topic_created, topic) end -%i(post_created - post_destroyed - post_recovered).each do |event| - - DiscourseEvent.on(event) do |post, _, user| - WebHook.enqueue_post_hooks(event, post, user) +%i( + post_created + post_destroyed + post_recovered +).each do |event| + DiscourseEvent.on(event) do |post, _, _| + WebHook.enqueue_post_hooks(event, post) end end @@ -39,7 +43,7 @@ end user_updated ).each do |event| DiscourseEvent.on(event) do |user| - WebHook.enqueue_hooks(:user, user_id: user.id, event_name: event.to_s) + WebHook.enqueue_object_hooks(:user, user, event) end end @@ -49,7 +53,7 @@ end group_destroyed ).each do |event| DiscourseEvent.on(event) do |group| - WebHook.enqueue_hooks(:group, group_id: group.id, event_name: event.to_s) + WebHook.enqueue_object_hooks(:group, group, event) end end @@ -59,7 +63,7 @@ end category_destroyed ).each do |event| DiscourseEvent.on(event) do |category| - WebHook.enqueue_hooks(:category, category_id: category.id, event_name: event.to_s) + WebHook.enqueue_object_hooks(:category, category, event) end end @@ -69,7 +73,7 @@ end tag_destroyed ).each do |event| DiscourseEvent.on(event) do |tag| - WebHook.enqueue_hooks(:tag, tag_id: tag.id, event_name: event.to_s) + WebHook.enqueue_object_hooks(:tag, tag, event, TagSerializer) end end @@ -80,6 +84,6 @@ end flag_deferred ).each do |event| DiscourseEvent.on(event) do |flag| - WebHook.enqueue_hooks(:flag, flag_id: flag.id, event_name: event.to_s) + WebHook.enqueue_object_hooks(:flag, flag, event) end end diff --git a/config/initializers/100-push-notifications.rb b/config/initializers/100-push-notifications.rb index 8cb0542cab..50f580c388 100644 --- a/config/initializers/100-push-notifications.rb +++ b/config/initializers/100-push-notifications.rb @@ -8,10 +8,6 @@ end SiteSetting.vapid_public_key_bytes = Base64.urlsafe_decode64(SiteSetting.vapid_public_key).bytes.join("|") -DiscourseEvent.on(:post_notification_alert) do |user, payload| - Jobs.enqueue(:send_push_notification, user_id: user.id, payload: payload) -end - DiscourseEvent.on(:user_logged_out) do |user| PushNotificationPusher.clear_subscriptions(user) end diff --git a/config/initializers/100-sidekiq.rb b/config/initializers/100-sidekiq.rb index a45ec085f7..f361c9fdee 100644 --- a/config/initializers/100-sidekiq.rb +++ b/config/initializers/100-sidekiq.rb @@ -13,6 +13,9 @@ Sidekiq.configure_server do |config| end if Sidekiq.server? + # defer queue should simply run in sidekiq + Scheduler::Defer.async = false + # warm up AR RailsMultisite::ConnectionManagement.each_connection do (ActiveRecord::Base.connection.tables - %w[schema_migrations]).each do |table| diff --git a/config/locales/client.ar.yml b/config/locales/client.ar.yml index bf8a5f4e85..dc6b70b185 100644 --- a/config/locales/client.ar.yml +++ b/config/locales/client.ar.yml @@ -2887,7 +2887,6 @@ ar: label: "أجرِ نسخ احتياطي" title: "أنشئ نسخة احتياطية" confirm: "أتريد إجراء نسخة احتياطية جديدة؟" - without_uploads: "نعم (لا تضمن الملفات)" download: label: "حمل" title: "أرسل بريدًا إلكترونيا فيه رابط التحميل" @@ -3571,7 +3570,6 @@ ar: enabled: تفعيل الشارة icon: أيقونة image: صورة - icon_help: "استخدم اسم ايقونة منFont Awesome أو عنوانًا URL إلى صورة" query: إستعلام عن شارة (SQL) target_posts: إستعلام عن المنشورات auto_revoke: إلغاء الاستعلام اليومي diff --git a/config/locales/client.bg.yml b/config/locales/client.bg.yml new file mode 100644 index 0000000000..4b98759095 --- /dev/null +++ b/config/locales/client.bg.yml @@ -0,0 +1,2730 @@ +# 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/ + +bg: + js: + number: + format: + separator: "." + delimiter: ", " + human: + storage_units: + format: '%n %u' + units: + byte: + one: Байт + other: Байта + gb: ГБ + kb: КБ + mb: МБ + tb: ТБ + short: + thousands: "{{number}}k " + millions: "{{number}}M " + dates: + time: "h:mm a" + timeline_date: "MMM YYYY" + 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: "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" + wrap_ago: "преди %{date}" + tiny: + half_a_minute: "< 1 мин." + less_than_x_seconds: + one: < 1сек + other: < %{count}сек + x_seconds: + one: 1сек + other: '%{count}сек' + x_minutes: + one: 1мин + other: '%{count}мин' + about_x_hours: + one: 1ч + other: '%{count}ч' + x_days: + one: 1д + other: '%{count}д' + about_x_years: + one: 1г + other: '%{count}г' + over_x_years: + one: '> 1г' + other: '> %{count}г' + almost_x_years: + one: 1г + other: '%{count}г' + date_month: "MMM D" + date_year: "MMM 'YY" + medium: + x_minutes: + one: 1 минута + other: '%{count} минути' + x_hours: + one: 1 час + other: '%{count} часа' + x_days: + one: 1 ден + other: '%{count} дни' + date_year: "MMM D, 'YY" + medium_with_ago: + x_minutes: + one: преди 1 минута + other: преди %{count} минути + x_hours: + one: преди 1 час + other: преди %{count} часа + x_days: + one: преди 1 ден + other: преди %{count} дни + later: + x_days: + one: 1 ден по-късно + other: '%{count} дни по-късно' + x_months: + one: 1 месец по-късно + other: '%{count} месеца по-късно' + x_years: + one: 1 година по-късно + other: '%{count} години по-късно' + previous_month: 'Предишен месец' + next_month: 'Следващ месец' + placeholder: дата + share: + topic: 'споделете връзка към тази тема' + post: 'публикации #%{postNumber}' + close: 'затвори' + twitter: 'споделете тази връзка в Twitter' + facebook: 'споделете тази връзка във Facebook' + google+: 'споделете тази връзка в Google+' + email: 'изпратете тази връзка с имейл' + action_codes: + public_topic: "направи тази тема публична на %{when}" + private_topic: "направи тази тема персонално съобщение%{when}" + split_topic: "раздели тази тема %{when}" + invited_user: "покани %{who} %{when}" + invited_group: "покани %{who} на %{when}" + user_left: "%{who}напусна чата %{when}" + removed_user: "изтри %{who} %{when}" + removed_group: "изтри %{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: "Всички изходящи имейли са изцяло забранени от администратора. Няма да бъдат изпращани никакви имейл известия." + bootstrap_mode_enabled: "За да помогнем със стартирането на вашия нов сайт по-лесно поставихме сайта в \"стартиращо режим\". Всички нови потребители ще получат ниво на доверие 1 и ще имат активирани дневни известия за активноста във форума. Този режим ще бъде автоматично спрян когато бройката регистрирани потребители стигне %{min_users} ." + themes: + default_description: "По подразбиране" + s3: + regions: + ap_northeast_1: "Азия (Токио)" + ap_northeast_2: "Азия (Сеул)" + ap_south_1: "Азия (Мумбай)" + ap_southeast_1: "Азия (Сингапур)" + ap_southeast_2: "Океания (Сидни)" + cn_north_1: "Китай (Пекин)" + eu_central_1: "EU (Франкфурт)" + eu_west_1: "EU (Ирландия)" + sa_east_1: "Южна Америка (Сао Паоло)" + us_east_1: "US East (Из. Вирджиния)" + us_gov_west_1: "AWS GovCloud (САЩ)" + us_west_1: "US West (С. Калифорния)" + us_west_2: "US West (Орегон)" + edit: 'редактирайте заглавието и категорията на тази тема' + not_implemented: "Тази функционалност все още не е добавена." + no_value: "Не" + yes_value: "Да" + submit: "Изпрати" + generic_error: "Съжаляваме, възникна грешка." + generic_error_with_reason: "Грешка: %{error}" + sign_up: "Регистрация" + log_in: "Вход" + age: "Години" + joined: "Присъединен" + admin_title: "Админ" + flags_title: "Сигнали" + show_more: "покажи повече" + show_help: "опции" + links: "Връзки" + links_lowercase: + one: Линк + other: Линкове + faq: "FAQ" + guidelines: "Насоки" + privacy_policy: "Декларация за поверителност" + privacy: "Поверителност" + terms_of_service: "Правила за ползване" + mobile_view: "Мобилен изглед" + desktop_view: "Десктоп изглед" + you: "Вие" + or: "или" + now: "преди малко" + read_more: 'прочетете повече' + more: "Повече" + less: "По-малко" + never: "никога" + every_30_minutes: "на всеки 30 минути" + every_hour: "на всеки час" + daily: "ежедневно" + weekly: "седмично" + every_two_weeks: "на всеки две седмици" + every_three_days: "На всеки три дни" + max_of_count: "максимално от {{count}}" + alternation: "или" + character_count: + one: '{{count}} символ' + other: '{{count}} символа' + suggested_topics: + title: "Подобни теми" + pm_title: "Предложени съобщения" + about: + simple_title: "Относно" + title: "За %{title}" + stats: "Статистика на сайта" + our_admins: "Нашите админи" + our_moderators: "Нашите модератори" + stat: + all_time: "От началото" + like_count: "Харесвания" + topic_count: "Теми" + post_count: "Публикации" + user_count: "Потребители" + active_user_count: "Активни потребители" + contact: "Свържете се с нас" + contact_info: "В случай на критичен или спешен въпрос засягащ този сайт, моля свържете се с нас на адрес %{contact_email}." + bookmarked: + title: "Отметка" + clear_bookmarks: "Изчисти отметките" + help: + bookmark: "Щракнете за да добавите в отметки първата публикация в тази тема" + unbookmark: "Щракнете тук за да изтриите всички отметки в тази тема" + bookmarks: + not_logged_in: "съжаляваме, трябва да сте логнат, за да добавяте отметки" + created: "Вие добавихте тази публикация в отметки" + not_bookmarked: "тази публикация е прочетена, добавете я в отметки" + last_read: "това е последната публикация която прочетохте, добавете я в отметки" + remove: "Премахнете отметката" + confirm_clear: "Сигурен ли сте, че искате да премахните всичките отметки от тази тема ?" + preview: "преглед" + cancel: "прекрати" + save: "Запазете промените" + saving: "Запазва се..." + saved: "Запазено!" + upload: "Качване" + uploading: "Качва се..." + uploading_filename: "Качва се {{filename}}..." + uploaded: "Качено!" + enable: "Позволи" + disable: "Деактивиране" + continue: "Напред" + undo: "Отмени" + revert: "Върни" + failed: "Провалени" + switch_to_anon: "Влез в Анонимен режим. " + switch_from_anon: "Излез от Анонимен режим." + banner: + close: "Премахнете банера" + edit: "Редактирай този банер >>" + choose_topic: + none_found: "Няма нови теми." + title: + search: "Търсене на тема по име, url адрес или id номер:" + placeholder: "Въведете заглавието на темата тук" + queue: + topic: "Тема:" + approve: 'Одобри' + reject: 'Отхвърли' + delete_user: 'Изтрий потребител' + title: "Чакащи одобрение" + none: "Няма публикации за преглед" + edit: "Редактирай" + cancel: "Прекрати" + view_pending: "Покажи предстоящите публикации" + has_pending_posts: + one: Тази тема има 1 публикация чакаща одобрение + other: Тази тема има {{count}} публикации които чакат одобрение + confirm: "Запази промените" + delete_prompt: "Сигурни ли сте, че искате да изтриете %{username}? Така ще бъдат изтрити всички постове асоциирани с потребителя и ще бъде блокиран email адреса и IP адреса му." + approval: + title: "Публикацията изисква одобрение" + description: "Ние получихме вашата публикация, но тя трябва да бъде одобрена от модератора преди да бъде показана. Моля, проявете търпение." + pending_posts: + one: Вие имате 1 чакаща публикация + other: Вие имате {{count}} чакащи публикации + ok: "ОК" + user_action: + 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_mentioned_user: "{{user}} спомена {{another_user}}" + user_mentioned_you: "{{user}} Ви спомена" + you_mentioned_user: "Вие споменахте {{another_user}}" + posted_by_user: "Публикувано от {{user}}" + posted_by_you: "Публикувано от вас" + sent_by_user: "Изпратено от {{user}}" + sent_by_you: "Изпратено от Вас" + directory: + filter_name: "филтър по потребитилско име" + title: "Потребители" + likes_given: "Дадени" + likes_received: "Получени" + topics_entered: "Видяни" + topics_entered_long: "Видяни теми" + time_read: "Време за прочитане" + topic_count: "Теми" + topic_count_long: "Създадени теми" + post_count: "Отговори" + post_count_long: "Публикувани отговори" + no_results: "Няма намерени резултати." + days_visited: "Посещения" + days_visited_long: "Посетени дни" + posts_read: "Прочетени" + posts_read_long: "Прочетени публикации" + total_rows: + one: 1 потребител + other: '%{count} потребители' + group_histories: + actions: + change_group_setting: "Промени настройки" + add_user_to_group: "Добави потребител" + remove_user_from_group: "Премахни потребител" + make_user_group_owner: "Превърни в собственик" + remove_user_as_group_owner: "Премахни като собственик" + groups: + add_members: + title: "Добавете потребители" + usernames: "Потебителско име" + manage: + title: 'Управление' + name: 'Име' + full_name: 'Пълно име' + add_members: "Добавете потребители" + delete_member_confirm: "Премахнете '%{username}' от група '%{group}' ?" + profile: + title: Профил + interaction: + posting: Публикуване + notification: Известие + membership: + title: Членство + access: Достъп + logs: + title: "Логове" + when: "Кога" + action: "Действие" + from: "От" + to: "До" + public_admission: "Разрешено е на потребителите да се присъединяват към групата свободно (Изисква се публично видима група)" + public_exit: "Разрешено е на потребителите да напуската групата свободно" + empty: + posts: "Няма публикации от членове на тази група." + members: "Няма членове в тази група." + mentions: "Няма споменавания на тази група." + messages: "Няма съобщения за тази група." + topics: "Няма теми от членове на тази група." + logs: "Няма журнал за тази група." + add: "Добави" + join: "Влизане" + leave: "Напусни" + request: "Заявка" + message: "Съобщение" + membership: "Членство" + name: "Име" + user_count: "Потребители" + bio: "Относно групата" + owner: "собственик" + index: + title: "Групи" + all: "Всички групи" + empty: "Няма видими групи." + close_groups: "Затворени групи" + closed: "Затворена" + public: "Публични" + private: "Затворени" + is_group_owner: "Собественик" + activity: "Активност" + topics: "Теми" + posts: "Публикации" + mentions: "Споменавания" + messages: "Съобщения" + notification_level: "Nиво на уведомяване по подразбиране за груповите съобщения" + alias_levels: + mentionable: "Кой може да @mention (споменава) тази група?" + messageable: "Кой може да изпраща съобщения към тази група?" + nobody: "Никой" + only_admins: "Само администратори" + mods_and_admins: "Само модератори и администратори" + members_mods_and_admins: "Само членове, модератори и администратори" + everyone: "Всички" + notifications: + watching: + title: "Наблюдава" + description: "Вие бъдете уведомени за всеки нов пост във всяко съобщение, както и за броя на новите съобщения." + watching_first_post: + title: "Следейки за първа публикация" + description: "Вие ще бъдете уведомявани само за първата публикация във всяка нова тема в тази група." + tracking: + title: "Проследяване" + description: "Ще бъдете уведомени, ако някой ви спомене чрез @name или ви отговори, както и на броя на новите ви съобщения ще бъдат показани." + regular: + title: "Нормален" + description: "Ще бъдете уведомени, ако някой ви споменава чрез @name или ви отговори." + muted: + title: "Заглушен" + description: "Вие никога няма да бъде уведомен за нито една нова тема в тази група." + flair_url: "Добавка към аватара" + flair_url_placeholder: "(По желание) Адрес към снимка или Font Awesome клас" + flair_bg_color: "Фон на добавка към аватара" + flair_bg_color_placeholder: "(По желание) Шестнадесетична стойност на цвят" + flair_color: "Цвят на добавка към аватар" + flair_color_placeholder: "(По желание) Шестнадесетична стойност на цвят" + flair_preview_icon: "Икона за прегледа" + flair_preview_image: "Снимка за преглед" + user_action_groups: + "1": "Дадени харесвания" + "2": "Получени харесвания" + "3": "Отметки" + "4": "Теми" + "5": "Отговори" + "6": "Отговори" + "7": "Споменавания" + "9": "Цитати" + "11": "Редакции" + "12": "Изпратени" + "13": "Кутия" + "14": "Чакащи" + categories: + all: "всички категории" + all_subcategories: "всички %{categoryName}" + 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_sentence: + one: 1 тема + other: '%{count} теми' + topic_stat_sentence: + one: '%{count} нова тема в последните %{unit}.' + other: '%{count} нови теми в последните %{unit}.' + ip_lookup: + title: Търсене по IP адрес + hostname: Хост + location: Локация + location_not_found: (неизвестно) + organisation: Организация + phone: Телефон + other_accounts: "Други профили с този IP адрес:" + delete_other_accounts: "Изтрий %{count}" + username: "Потребителско име" + trust_level: "TL" + read_time: "Време за прочитане" + topics_entered: "добавени теми" + post_count: "# публикации" + confirm_delete_other_accounts: "Сигурни ли сте, че искате да изтриете тези профили?" + user_fields: + none: "(изберете опция)" + user: + said: "{{username}}:" + profile: "Профил" + mute: "Заглуши" + edit: "Редактирай настройките" + download_archive: + confirm: "Сигурни ли сте, че искате да свалите своите публикации?" + success: "Свалянето е инициирано, ще бъдете уведомени чрез съобщение когато процесът е завършен." + rate_limit_error: "Публикации могат да бъдат сваляни веднъж дневно, моля опитайте отново утре." + new_private_message: "Ново Съобщение" + private_message: "Съобщение" + 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: "Вие сте забранили известията. Моля разрешете ги чрез настройките на браузъра си." + disable: "Деактивиране на Известията" + enable: "Активиране на Известията" + each_browser_note: "Забележка: Трябва да промените тази настройка при всички браузъри, които използвате." + consent_prompt: "Искате ли известявания в реално време, когато хората отговарят на вашите публикации?" + dismiss_notifications: "Отмени всички" + dismiss_notifications_tooltip: "Маркирайте всички непрочетени известия, като прочетени" + first_notification: "Вашето първо известие! Изберете го за да започнете." + disable_jump_reply: "Не отивай към моята публикация след като отговоря" + dynamic_favicon: "Покажи броя на новите / обновени теми в иконата на брузъра" + external_links_in_new_tab: "Отваряй всички външни връзки в нов раздел." + enable_quoting: "Включи отговор с цитат при маркиран текст." + change: "промени" + moderator: "{{user}} е модератор" + admin: "{{user}} е админ" + moderator_tooltip: "Този потребител е модератор" + admin_tooltip: "Този потребител е админ" + suspended_notice: "Този потребител е отстранен до {{date}}." + suspended_reason: "Причина:" + github_profile: "Github" + email_activity_summary: "Сумарна активност" + mailing_list_mode: + label: "Режим Бюлетин" + enabled: "Включи режим Бюлетин" + individual: "Изпращане на email за всяка нова публикация" + individual_no_echo: "Пращай имейл за всяка нова публикация освен моите собствени" + many_per_day: "Пращай имейл за всяка нова публикация (около {{dailyEmailEstimate}} на ден)" + few_per_day: "Изпратете ми имейл за всяка нова публикация (около 2 на ден)" + tag_settings: "Етикети" + watched_tags: "Наблюдавани" + watched_tags_instructions: "Вие автоматично ще наблюдавате всички теми с този етикет. Ще бъдете информиран за всички нови публикации и теми, и броят на непрочетените и новите публикации ще се появява до съответната тема. " + tracked_tags: "Следени" + tracked_tags_instructions: "Вие автоматично ще следите всички нови теми с този етикет. Броят новите публикации ще се появява до съответната тема. " + muted_tags: "Заглушени" + muted_tags_instructions: "Вие няма да бъдете уведомяван за нищо свързано с нови теми с тези етикети, и те няма да се показват в \"последни\"." + watched_categories: "Наблюдавани" + watched_categories_instructions: "Вие автоматично ще наблюдавате всички нови теми в тази категория. Ще бъдете информиран за всички нови публикации и теми, и броят на непрочетените и новите публикации ще се появява до съответната тема. " + tracked_categories: "Следени" + tracked_categories_instructions: "Вие автоматично ще следите всички нови теми в тези категории. Броят новите публикации ще се появява до съответната тема. " + watched_first_post_categories: "Наблюдаване на Първа Публикация" + watched_first_post_categories_instructions: "Ще бъдете уведомени за първата публикация във всяка нова тема в тези категории" + watched_first_post_tags: "Наблюдавайки Първа Публикация" + watched_first_post_tags_instructions: "Ще бъдете уведомени за първата публикация във всяка нова тема с тези етикети." + muted_categories: "Заглушен" + muted_categories_instructions: "Вие няма да бъдете уведомен за нови теми в тези категории, и те няма да се показват в \"последни\"." + no_category_access: "Като модератор имате ограничен достъп до категориите, запазването е изключено." + delete_account: "Изтрий моя профил" + delete_account_confirm: "Сигурни ли сте, че искате да изтриете вашия акаунт? Акаунтът не може да бъде възстановен !" + deleted_yourself: "Вашият профил беше изтрит успешно." + delete_yourself_not_allowed: "Моля, свържете се с член на персонала, ако искате профилът Ви да бъде изтрит." + unread_message_count: "Съобщения" + admin_delete: "Изтрий" + users: "Потребители" + muted_users: "Заглушен" + muted_users_instructions: "Забрани всички съобщения от тези потребители" + muted_topics_link: "Покажете заглушените теми" + watched_topics_link: "Покажи наблюдаваните теми" + tracked_topics_link: "Покажи следените теми" + automatically_unpin_topics: "Автоматично отключете темите когато стигнете най-долу на форума." + apps: "Приложения" + revoke_access: "Прекратяване на достъпа" + undo_revoke_access: "Отмяна прекратяване на достъпа" + api_approved: "Одобрени:" + staff_counters: + flags_given: "полезни сигнали" + flagged_posts: "публикации със сигнали" + deleted_posts: "изтрити публикации" + suspensions: "отстранявания" + warnings_received: "предупреждения" + messages: + all: "Всички" + inbox: "Входяща кутия" + sent: "Изпратени" + archive: "Архив" + groups: "Моите групи" + bulk_select: "Изберете съобщения" + move_to_inbox: "Премести във входящи" + move_to_archive: "Архив" + failed_to_move: "Грешка при преместването на съобщенията (може би интернета ви спря?)" + select_all: "Избери всички" + tags: "Етикети" + preferences_nav: + account: "Профил" + notifications: "Известия" + tags: "Етикети" + apps: "Апликации" + change_password: + success: "(имейлът е изпратен)" + in_progress: "(изпраща се имейл)" + error: "(грешка)" + action: "Изпратете имейл за смяна на паролата" + set_password: "Задайте парола" + choose_new: "Избери нова парола" + choose: "Избери парола" + second_factor: + title: "Двуфакторно удостоверяване" + disable: "Деактивирайте двуфакторното удостоверяване" + confirm_password_description: "Моля, потвърдете паролата за да продължите" + label: "Код" + change_about: + title: "Смяна на За мен" + error: "Имаше грешка при промяна на тази стойност." + change_username: + title: "Смяна на потребителското име." + confirm: "Ако смените вашето потребителско име, всички предишни цитати и @име споменавания ще бъдат повредени . Сигурни ли сте, че искате да продължите?" + taken: "Съжаляваме, това потребителско име е заето." + invalid: "Потребителското име не е валидно. Трябва да включва само цифри и букви" + change_email: + title: "Смяна на Имейла" + taken: "Съжаляваме, този имейл адрес не е свободен." + error: "Получи се грешка при смяната на адреса. Вероятно адресът вече е зает?" + success: "Изпратихме съобщение на този адрес. Моля, следвайте инструкциите за потвърждаване." + success_staff: "Изпратихме съобщение на този адрес. Моля, следвайте инструкциите за потвърждаване." + change_avatar: + title: "Сменете аватара на вашия профил " + gravatar: "Gravatar, базиран на" + gravatar_title: "Промени вашият аватар на сайта на Граватар" + refresh_gravatar_title: "Опреснете Gravatar" + letter_based: "Системен аватар" + uploaded_avatar: "Собствено изображение" + uploaded_avatar_empty: "Добавете собствено изображение" + upload_title: "Качете изображение" + upload_picture: "Качи изображение" + image_is_not_a_square: "Внимание: изрязахмеИзрязахме вашата снимка,снимка защото не е с квадратна форма." + cache_notice: "Вие успешно сменихте снимката на вашия профил, но ще отнеме известно време докато се актуализира." + change_profile_background: + title: "Фон на профила" + instructions: "Фонът на профила ще бъде центриран и ще има ширина по подразбиране 850 пиксела." + change_card_background: + title: "Потребителски фон" + instructions: "Фонът ще бъде центриран и ще има дължина 590 пиксела." + email: + title: "Имейл" + instructions: "не се показва публично" + ok: "Ще Ви изпратим имейл за потвърждение." + invalid: "Моля, въведете валиден имейл адрес" + authenticated: "Вашият имейл беше потвърден от {{provider}}." + frequency_immediately: "Ще ви изпратим мейл веднага, ако не сте прочели поста за който сме ви писали." + frequency: + one: Ние ще ви изпратим имейл само ако не сме ви виждали през последната минута. + other: Ние ще ви изпратим имейл само ако не сме ви виждали през последните {{count}} минути. + name: + title: "Име" + instructions: "вашето пълно име (опционално)" + instructions_required: "Вашето пълно име" + too_short: "Името е твърде кратко." + ok: "Вашето име изглежда добре" + username: + title: "Потребителско име" + instructions: "уникално, без интервали" + short_instructions: "Хора могат да Ви споменават като @{{username}}" + available: "Вашето потребителско име е свободно" + not_available: "Не е налично. Пробвайте с {{suggestion}}?" + not_available_no_suggestion: "Не е наличен!" + too_short: "Потребителското име е твърде кратко" + too_long: "Потребителското име е твърде дълго" + checking: "Проверяваме дали потребителското име е свободно..." + prefilled: "Имейлът съвпада с това потребителско име" + locale: + title: "Език на интерфейса" + instructions: "Езикът на потребителския интерфейс, ще бъде променен, след като презаредите страницата." + default: "(по подразбиране)" + password_confirmation: + title: "Паролата отново" + last_posted: "Последна публикация" + last_emailed: "Последен имейл" + last_seen: "Видян" + created: "Присъединен" + log_out: "Изход" + location: "Локация" + 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: "На всеки две седмици" + include_tl0_in_digests: "Включи мненията от нови потребители в обобщените имейли" + email_in_reply_to: "Включи откъс от отговора на поста в мейлите" + email_direct: "Изпращайте ми имейл, когато някой ме цитира, отговаря на моите публикации, цитира моето @потребителско_име или ме кани да се присъединя към тема." + email_private_messages: "Изпращай ми имейл, когато някой ми изпрати съобщение" + email_always: "Изпращай ми имейл известия, дори когато съм активен на сайта" + other_settings: "Други" + categories_settings: "Категории" + 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: "Автоматично следи темите които съм въвел" + 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: "Поканени потребители" + sent: "Изпрати" + truncated: + one: Показване на първата покана. + 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: "Тази покана е изтекла." + rescind: "Премахване" + rescinded: "Поканата е премахната" + reinvite: "Изпратете отново" + reinvite_all: "Препрати всички покани" + reinvited: "Поканата е изпратена отново" + reinvited_all: "Всички покани са препратени!" + time_read: "Време за прочитане" + days_visited: "Дни Посетена" + account_age_days: "Период на акаунта в дни" + create: "Изпрати покана" + generate_link: "Копирай Връзката-Покана" + bulk_invite: + text: "Групова покана чрез файл" + success: "Файлът е качен успешно. Ще бъдете информирани чрез съобщение, когато процесът завърши." + password: + title: "Парола" + too_short: "Вашата парола е твърде кратка." + common: "Вашата парола е твърде разпространена." + same_as_username: "Вашата парола е същата като вашето потребителско име." + same_as_email: "Вашата парола е същата като вашия email." + ok: "Вашата парола изглежда добре." + instructions: "поне %{count}знака" + summary: + title: "Сумарно" + stats: "Статистика" + time_read: "Време за прочитане" + topic_count: + one: Създадена тема + other: Създадени теми + post_count: + one: Създадена публикация + other: 'Създадени публикации ' + days_visited: + one: Посетен ден + other: Посетени дни + posts_read: + one: Прочетена публикация + other: 'Прочетени публикации ' + bookmark_count: + one: маркер + other: маркери + top_replies: "Най-отговаряни" + no_replies: "Все още няма отговори." + more_replies: "Още отговори" + top_topics: "Най-добри теми" + no_topics: "Все още няма теми." + more_topics: "Още теми" + top_badges: "С най-много значки" + no_badges: "Все още няма значки." + more_badges: "Още значки" + top_links: "Най-добри връзки" + no_links: "Все още няма линкове." + most_liked_by: "По най-харесвани" + most_liked_users: "Най-харесвани" + most_replied_to_users: "По най-отговаряни" + no_likes: "Все още няма харесвания." + associated_accounts: "Логвания" + ip_address: + title: "Последен IP адрес." + registration_ip_address: + title: "IP адрес при регистрацията." + avatar: + title: "Аватар" + header_title: "профил, съобщения, отметки и предпочитания" + title: + title: "Заглавие" + filters: + all: "Всички" + stream: + posted_by: "Публикувано от" + sent_by: "Изпратено от" + private_message: "Съобщение" + the_topic: "темата" + loading: "Зарежда се..." + errors: + prev_page: "докато се зареждаше" + reasons: + network: "Грешка при свързване" + server: "Грешка в сървъра" + forbidden: "Достъпът е ограничен" + unknown: "Грешка" + not_found: "Страницата не е намерена" + desc: + network: "Моля проверете вашата връзка" + network_fixed: "Изглежда се е върнала." + server: "Грешка: {{status}}" + forbidden: "Няматe права да виждате това." + not_found: "Опаа, приложението опита да зареди URL, който не съществува." + unknown: "Нещо се обърка." + buttons: + back: "Назад" + again: "Опитайте отново" + fixed: "Заредете страницата" + close: "Затвори" + assets_changed_confirm: "Страницата беше обновена. Презаредете, за да видите последната версия." + logout: "Вие бяхте отписан." + refresh: "Опресни" + read_only_mode: + 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: + rate: + one: 1 грешка/%{duration} + other: '%{count} грешки/%{duration}' + learn_more: "научете повече..." + all_time: 'общо' + all_time_desc: 'общо създадени теми' + year: 'година' + year_desc: 'теми създадени през последните 365 дни' + month: 'месец' + month_desc: 'теми създадени през последните 30 дни' + week: 'седмица' + week_desc: 'теми създадени през последните 7 дни' + day: 'ден' + first_post: Първа публикация + mute: Заглушаване + unmute: Премахване на заглушаване + last_reply_lowercase: последен отговор + 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: "Има {{replyCount}} отговора." + description_time: "В момента има {{replyCount}} отговора прочетени за {{readingTime}} минути." + enable: 'Обобщи Тази Тема' + disable: 'Покажи всички публикации' + deleted_filter: + enabled_description: "Тази тема има изтрити публикации, които са скрити." + disabled_description: "Изтритите публикации в тази тема са показани." + enable: "Скрий изтритите публикации" + disable: "Покажи изтритите публикации" + private_message_info: + title: "Съобщение" + invite: "Поканете други..." + remove_allowed_user: "Сигурни ли сте, че искате да премахнете {{name}} от това съобщение?" + remove_allowed_group: "Сигурни ли сте, че искате да премахнете {{name}} от това съобщение?" + email: 'Имейл' + username: 'Потребителско име' + last_seen: 'Видяно' + created: 'Създадено' + created_lowercase: 'създадено' + trust_level: 'Ниво на доверие' + search_hint: 'потребителско име, имейл или IP адрес' + create_account: + disclaimer: "С регистрацията си се съгласявате с политиката за повелителност и условията за ползване." + title: "Създай нов профил" + failed: "Нещо се случи, вероятно вече има регистрация с този имейл адрес, опитайте с линка за забравена парола." + forgot_password: + title: "Възстановяване на парола" + action: "Забравих си паролата" + invite: "Въведете вашето потребителско име или имейл и ние ще Ви изпратим имейл за смяна на паролата." + reset: "Смяна на паролата" + complete_username: "Ако профилът съвпада с потребителското име %{username}, трябва да получите имейл с инструкции, как да си смените паролата. " + complete_email: "Ако профилът съвпада с %{email}, трябва да получите имейл с инструкции, как да си смените паролата. " + complete_username_found: "Намерихме профил който съвпада с потребителското име %{username}, трябва да получите имейл с инструкции как да смените паролата." + complete_email_found: "Намерихме профил който съвпада с %{email}, трябва да получите имейл с инструкции как да смените паролата." + complete_username_not_found: "Няма профил, който да съвпада с потребителскоto име %{username}" + complete_email_not_found: "Няма акаунт който да съвпада с %{email}" + login: + title: "Вход" + username: "Потребител" + password: "Парола" + email_placeholder: "имейл или потребителско име" + caps_lock_warning: "Включен е Caps Lock" + error: "Непозната грешка" + rate_limit: "Моля, изчакайте, преди да се опитате да влезете отново." + blank_username_or_password: "Моля, въведете Вашия имейл или потребителско име и парола." + reset_password: 'Смяна на парола' + logging_in: "Влизане..." + or: "Или" + authenticating: "Оторизация..." + awaiting_approval: "Вашия акаунт все още не е одобрен от администратора. Ще получите известие, когато това се случи." + requires_invite: "Съжаляваме, този форум е достъпен само с покани." + not_activated: "Не може да влезете. Изпратихме имейл за активация на {{sentTo}}. Моля, следвайте инструкциите в имейла, за да активирате профила." + not_allowed_from_ip_address: "Не може да влезете от този IP адрес." + admin_not_allowed_from_ip_address: "Не може да влезете като админ от този IP адрес." + resend_activation_email: "Натиснете тук, за да изпратите повторен имейл за активация." + omniauth_disallow_totp: "Профилът ви има активирано удостоверяване с два фактора. Моля, влезте с паролата си." + sent_activation_email_again: "Изпратихме имейл за активация на {{currentEmail}}. Може да изминат няколко минути докато пристигне. Не забравяйте да проверите Вашата спам папка." + to_continue: "Моля влезте" + preferences: "Трябва да сте влезли, за да можете да променяте потребителските си настройки." + forgot: "Не си спомням подробности за профила ми" + google: + title: "с Google" + message: "Удостоверяване с Google (проверете за блокирани на поп-ъп прозорци) " + google_oauth2: + title: "с Google" + message: "Удостоверяване с Google (проверете за блокирани на поп-ъп прозорци)" + twitter: + title: "с Twitter" + message: "Удостоверяване с Twitter (уверете се, pop up блокерите не са разрешени)" + instagram: + title: "чрез Instagram" + message: "Удостоверява се връзка с Instagram (уверете се, че поп-блокерите не са включени)" + facebook: + title: "със Facebook" + message: "Удостоверяване със Facebook (проверете за блокирани на поп-ъп прозорци)" + yahoo: + title: "с Yahoo" + message: "Удостоверяване с Yahoo (уверете се, pop up блокерите не са разрешени)" + github: + title: " с Github" + message: "Удостоверяване с Github (уверете се, pop up блокерите не са разрешени)" + invites: + success: "Профилът ви е създаден и вече сте влезли в него." + name_label: "Име" + emoji_set: + google: "Google" + twitter: "Twitter" + win10: "Win10" + shortcut_modifier_key: + shift: 'Shift' + ctrl: 'Ctrl' + alt: 'Alt' + select_kit: + default_header_text: Изберете... + filter_placeholder: "Търсене ... " + emoji_picker: + filter_placeholder: Търсене на имотикони + composer: + emoji: "Емошънка :)" + more_emoji: "още..." + options: "Опции" + whisper: "шепот" + unlist: "скрити" + add_warning: "Това е официално предупреждение." + toggle_whisper: "Включи шепот" + posting_not_on_topic: "На коя тема искате да отговорите ?" + saving_draft_tip: "записване..." + saved_draft_tip: "запазено" + saved_local_draft_tip: "запазено локално" + similar_topics: "Вашата тема е подобна на..." + drafts_offline: "чернови офлайн" + error: + title_missing: "Заглавието е задължително" + title_too_short: "Заглавието трябва да е минимум {{min}} символа" + title_too_long: "Заглавието не може да е повече от {{max}} символа" + post_missing: "Публикацията не може да е празна" + post_length: "Публикацията трябва да е най-малко {{min}} символа." + try_like: 'Опитвали ли сте бутона?' + category_missing: "Трябва да изберете категория" + tags_missing: "Трябва да изберете поне %{count} етикети." + save_edit: "Запази редакцията" + reply_original: "Отговори на Оригинална Тема" + reply_here: "Отговори тук" + reply: "Отговорете" + cancel: "Прекрати" + create_topic: "Създай тема" + create_pm: "Съобщение" + title: "Или натиснете Ctrl+Enter" + users_placeholder: "Добави потребител" + title_placeholder: "За какво става дума в дискусията с едно изречение?" + title_or_link_placeholder: "Напишете заглавие или поставете линк тук" + edit_reason_placeholder: "защо редактирате ?" + show_edit_reason: "(причина за редакцията)" + reply_placeholder: "Пиши тук. Използвай Markdown, BBCode, или HTML за форматиране. Издърпайте или поставете изображенията." + view_new_post: "Вижте публикацията." + saving: "Запаметяване" + saved: "Запазено!" + saved_draft: "Публикацията е налична като чернова. Изберете, за да продължите." + uploading: "Качва се..." + show_preview: 'покажи прегледa »' + hide_preview: '« скрий прегледa' + quote_post_title: "Цитирай цялата публикация" + bold_title: "Удебелен" + bold_text: "удебелен текст" + italic_title: "Италик" + italic_text: "Подчертан текст" + link_title: "Хипервръзка" + link_description: "добави описание на връзката тук" + link_dialog_title: "Добави хипервръзка" + link_optional_text: "заглавие по избор" + link_url_placeholder: "http://example.com" + quote_title: "Текстов блок" + quote_text: "Текстов блок" + code_title: "Форматиран текст" + code_text: "Избутай текста с 4 интервала" + paste_code_text: "въведете или поставете кода тук" + upload_title: "Качване" + upload_description: "причина за качването" + olist_title: "Номериран списък" + ulist_title: "Списък с водещи символи" + list_item: "Списък" + help: "Помощ с Markdown" + modal_ok: "Ок" + modal_cancel: "Отмени" + cant_send_pm: "Съжеляваме, но неможете да изпращате съобщения до %{username}." + admin_options_title: "Допълнителни настройки за тази тема" + notifications: + title: "уведомления за @name споменавания, отговори на вашите публикации и теми, лични съобщения, и т.н." + none: "В момента не могат да бъдат заредени уведомленията." + empty: "Няма намерени нотификации." + more: "виж стари известия" + total_flagged: "всички публикации със сигнал" + 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}}' + linked: '{{username}} прикачи вашата публикация от "{{topic}}" - {{site_title}}' + confirm_title: 'Включени известявания - %{site_title}' + confirm_body: 'Успех! Известяването е включено.' + upload_selector: + title: "Добавете изображение" + title_with_attachments: "Добавете изображение или файл" + from_my_computer: "От моето устройство" + from_the_web: "От мрежата" + remote_tip: "линк към изображение" + 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: "Изчисти Всички" + too_short: "Думата за търсене е твърде кратка." + title: "търсете по тема, пост, потребител или категория" + full_page_title: "търсене на теми или публикации" + no_results: "Няма резултати " + no_more_results: "Не са намерени резултати." + searching: "Търсене ... " + post_format: "#{{post_number}} от {{username}} " + results_page: "Резултати от търсенето на '{{term}}'" + more_results: "Има повече резултати. Моля, прецизирайте търсенето си." + or_search_google: "Или вместо това опитайте търсене с Гугъл:" + search_google: "Опитайте вместо това търсене с Гугъл:" + search_google_title: "Търсене в този сайт" + context: + user: "Търсете публикация от @{{username}}" + category: "Търсене за категория #{{category}}" + topic: "Търсете тази тема" + private_messages: "Търси съобщения" + advanced: + title: Разширено търсене + posted_by: + label: Публикувано от + in_group: + label: В група + with_badge: + label: Със значка + filters: + likes: Аз харесах + posted: Аз публикувах в + watching: Аз наблюдавам + tracking: Аз следя + first: е първата публикация + pinned: са закачени + unpinned: не са закачени + all_tags: Всички по-горни етикети + post: + time: + label: Публикувано + before: преди + after: след + hamburger_menu: "Отиди към друг списък с теми или друга категория " + new_item: "нови" + go_back: 'Назад ' + not_logged_in_user: 'Потребителска страница с история на текущата дейност и предпочитания' + current_user: 'Отиди към потребителската страница ' + topics: + new_messages_marker: "последно посещение" + bulk: + select_all: "Селектирай всички" + clear_all: "Изчисти всички" + unlist_topics: "Непоказани теми" + reset_read: "Изчисти прочетеното " + delete: "Изтрий темите" + dismiss: "Отмени" + dismiss_read: "Отхвърли всички непрочетени" + dismiss_button: "Отмени..." + dismiss_tooltip: "Отхвърляне само новите мнения или спрете да следите теми" + also_dismiss_topics: "Спрете проследяване тези теми, така че те никога да не се появяват като непрочетени отново" + dismiss_new: "Премахни новите " + toggle: "Включв./Изкл. избор на няколко теми" + actions: "Групови действия " + close_topics: "Затвори темите" + archive_topics: "Архивирай темите" + notification_level: "Известия" + choose_new_category: "Избери нова категория за тези теми:" + selected: + one: Вие сте избрали 1 тема. + other: Вие сте избрали {{count}} теми. + change_tags: "Замени етикетите" + append_tags: "Добави етикетите" + choose_new_tags: "Избери нови етикети за тези теми:" + choose_append_tags: "Избери нови етикети, които да се добавят към тези теми:" + changed_tags: "Етикетите на тези теми бяха сменени." + none: + unread: "Нямате непрочетени теми." + new: "Нямате нови теми." + read: "Все още не сте прочели нито една тема." + posted: "Все още не сте публикували нито една тема." + latest: "Няма повече теми в Последни. Това е тъжно." + hot: "Няма горещи теми." + bookmarks: "Все още нямате теми в Отметки." + category: "Няма теми в категория {{category}}." + top: "Няма топ теми." + search: "Няма резултати от търсенето." + educate: + new: '

    Непрочетените теми се появяват тук.

    По подразбиране темите се считат за непрочетени и ще показват бройката нови ако са създадени през последните 2 дни.

    Моля посетете вашите настройки за да промените това.

    ' + unread: '

    Вашите непрочетени теми са тук.

    По подразбиране, темите се считат за непрочетени и ще им се показва брояч 1 ако вие:

    • Сте създали тема
    • Отговорили на тема
    • Прочели темата преди повече от 4 минути

    Или ако са изрично определени в темата да бъдат проследявани и гледани чрез контрол на уведомление в долната част на всяка тема. + +

    За да промените това, влезте във вашите настройки от тук.

    ' + bottom: + latest: "Няма повече теми в Последни." + hot: "Няма повече теми в горещи." + posted: "Няма повече публикувани теми." + read: "Няма повече прочетени теми." + new: "Няма повече нови теми." + unread: "Няма повече непрочетени теми." + category: "Няма повече теми в {{category}}" + top: "Няма повече топ теми." + bookmarks: "Няма теми в Отметки" + search: "Няма повече резултати от търсенето" + topic: + create: 'Нова тема' + create_long: 'Създайте нова тема' + open_draft: "Довърши ревизия" + private_message: 'Започни съобщение' + archive_message: + help: 'Преместете съобщението в архив' + title: 'Архив' + move_to_inbox: + title: 'Премести във входящи' + help: 'Премести съобщението обратно във входящи' + list: 'Теми' + new: 'нова тема' + unread: 'непрочетено' + new_topics: + one: 1 нова тема + other: '{{count}} нови теми' + unread_topics: + one: 1 непрочетена тема + other: '{{count}} непрочетени теми' + title: 'Тема' + invalid_access: + title: "Темата е частна" + description: "Съжаляваме, нямате достъп до тази тема !" + login_required: "Трябва да се логнат, за да видите темата." + server_error: + title: "Темата не може да бъде заредена." + description: "Съжаляваме, темата не може да бъде заредена, вероятно се дължи на проблеми с връзката. Моля, опитайте отново. Ако проблемът все още съществува, моля да ни уведомите." + not_found: + title: "Темата не е намерена" + description: "Темата не може да бъде открита. Възможно ли е да е премахната от модератор?" + total_unread_posts: + one: имате 1 непрочетено мнение в тази тема + other: ' Вие имате {{count}} непрочетени мнения в тази тема' + unread_posts: + one: Вие имате 1 непрочетено старо мнение в тази тема + other: Вие имате {{count}} непрочетени стари мнения в тази тема + new_posts: + one: има 1 нова публикация в темата от последното Ви посещение на темата + other: от последното Ви посещение в темата до сега има {{count}} нови публикации + likes: + one: има 1 харесване в тази тема + 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 { 1 непрочетено } other { # непрочетено } } { NEW, plural, =0 {} one { {BOTH, select, true{and } false {is } other{}} 1 нова тема} other { {BOTH, select, true{and } false {are } other{}} # теми } } напомняне, или {CATEGORY, select, true {потърски други теми в {catLink}} погрешен {{latestLink}} other {}}" + browse_all_categories: Прегледай всички категории + view_latest_topics: виж последните теми + suggest_create_topic: "Защо не създадете тема ?" + jump_reply_up: към по ранен отговор + jump_reply_down: към по-късен отговор + deleted: "Темата беше изтрита" + auto_update_input: + none: "Избери времева рамка" + later_today: "По-късно днес" + tomorrow: "Утре" + later_this_week: "По-късно тази седмица" + this_weekend: "Този уикенд" + next_week: "Следваща седмица" + two_weeks: "Две седмиц" + next_month: "Следващия месец" + three_months: "Три месеца" + six_months: "Шест месеца" + one_year: "Една година" + forever: "Завинаги" + auto_close_title: 'Настройки за автоматично затваряне' + timeline: + back: "Назад" + progress: + title: прогрес на темата + go_top: "горе" + go_bottom: "долу" + go: "go" + jump_bottom: "към последната публикация" + jump_bottom_with_number: "отиди на публикация %{post_number}" + total: всички публикации + current: текуща публикация + notifications: + reasons: + "3_10": 'Ще получавате известия, защото наблюдавате таг на тази тема.' + "3_6": 'Ще получавате известия, защото наблюдавате тази категория' + "3_5": 'Ще получавате известия, защото започнахте да наблюдавате тази тема автоматично.' + "3_2": 'Ще получавате известия, защото наблюдавате тази тема.' + "3_1": 'Ще получавате известия, защото създадохте тази тема.' + "3": 'Ще получавате известия, защото наблюдавате тази тема.' + "1_2": 'Ще ви уведобим, ако някой ви отговори или спомене вашето @име' + "1": 'Ще ви уведобим, ако някой ви отговори или спомене вашето @име' + "0_7": 'Вие игнорирате всички известия в тази категория.' + "0_2": 'Вие игнорирате всички известия за тази тема.' + "0": 'Вие игнорирате всички известия за тази тема.' + watching_pm: + title: "Наблюдавай" + description: "Вие ще бъдете информиран за всеки нов отговор на това съобщение, също така ще се показва и броя на новите отговори" + watching: + title: "Наблюдаване" + description: "Вие ще бъдете информиран за всеки нов отговор в тази тема, също така ще се показва и броя на новите отговори" + tracking_pm: + title: "Следене" + description: "Броят на новите отговори ще присъства в това съобщение. Вие ще бъдете информиран ако някой ви отговори или спомене вашето @име." + tracking: + title: "Следене" + description: "Броя на новите отговори ще присъства в тази тема. Вие ще бъдете информиран ако някой ви отговори или спомене вашето @име." + regular: + title: "Нормален" + description: "Ще ви уведобим, ако някой ви отговори или спомене вашето @име" + regular_pm: + title: "Нормален" + description: "Вие ще бъдете информиран ако някой ви отговори или спомене вашето @име" + muted_pm: + title: "Заглуши" + description: "Няма да бъдете уведомени за нищо свързано с това съобщение." + muted: + title: "Заглушен" + description: "Вие никога няма да бъде уведомен за нещо по тази тема, и то няма да се появи в най-новата." + actions: + recover: "Възстанови темата" + delete: "Изтрий темата" + open: "Отвори темата" + close: "Изчисти темата" + multi_select: "Избери публикации..." + pin: "Закови темата..." + unpin: "Откови темата..." + unarchive: "Разархивирай темата" + archive: "Архивирай темата" + invisible: "Премахни от списъците" + visible: "Включи в списъците" + reset_read: "Изчисти прочетените данни " + make_public: "Направи темата публична" + feature: + pin: "Закови темата" + unpin: "Отгови темата" + pin_globally: "Закови темата глобално" + make_banner: "Банер тема" + remove_banner: "Премахни банер тема" + clear_pin: + title: "Изчисти пин " + help: "Изчисти пиннатия статус на тази тема така, че тя повече да не се появява в горната част на Вашият списък с теми." + share: + title: 'Споделяне' + help: 'споделете връзка към тази тема' + flag_topic: + title: 'Сигнал' + help: 'скрито сигнализирайте за публикацията, за да ѝ бъде обърнато внимание или изпратете скрито известие за нея' + 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: + one: 'Темата е закачена в {{categoryLink}}: е 1' + other: 'Темите закачени в {{categoryLink}}: са {{count}}' + pin_globally: "Тази тема да се появява в горната част на всички списъци докато" + confirm_pin_globally: "Вие вече имате {{count}} глобално заковани теми. Прекалено много заковани теми може да объркат новите и анонимни потребители. Сигурни ли сте че искате да заковете още една тема глобално към тази категория ?" + unpin_globally: "Премахни тази тема от началото на списъците с теми." + unpin_globally_until: "Премахни тази тема от горната част на списъка с теми или изчакай докато %{until}." + global_pin_note: "Потребителите могат да отговат темата индивидуално само за тях." + not_pinned_globally: "Няма никакви закачени теми." + already_pinned_globally: + one: 'Темата закачена глобално е: 1' + other: 'Темите закачени глобално: {{count}}' + make_banner: "Направете тази тема на банер който ще присъства в началото на всички страници" + remove_banner: "Премахнете този банер който се появява в началото на всички страници" + banner_note: "Потребителите могат да откажат банера като го затворят. Само една тема може да бъде банер в едно и също време." + no_banner_exists: "Няма блокирани теми." + banner_exists: " е тема за банер." + inviting: "Покана..." + invite_private: + title: 'Покани за съобщение' + email_or_username: "Имейл адрес или Потребителско име" + email_or_username_placeholder: "имейл адрес или потребителско име" + action: "Покана" + success: "Поканихте този потребител да се включи в това съобщение." + error: "Получи се грешка при поканата на този потребител." + group_name: "име на групата" + controls: "Контрол на темата" + invite_reply: + title: 'Покана' + username_placeholder: "потребителско име" + action: 'Изпрати покана' + help: 'поканете другите да се присъединят към тази тема чрез имейл или уведомление' + to_forum: "Изпратихме кратък имейл, който позволява на Вашия приятел, да се включи в разговора, само с едно натискане върху връзката. Не се изисква вход в системата." + sso_enabled: "Въведете потребителското име на човека който желаете да поканите към в тема." + to_topic_blank: "Въведете потребителско име или имейл адрес на човека който желаете да поканите към тази тема." + to_topic_email: "Вие въведохте имейл адрес. Ние ще изпратим имейл чрез която вашият приятел може да отговори веднака на тази тема." + to_topic_username: "Въведохте потребителско име. Ние ще изпратим напомняне с връзка която го кани в тази тема." + to_username: "Въведете потребителското име на човека който искате да поканите. Ние ще му изпратим напомняне с връзка която го кани в тази тема." + email_placeholder: 'name@example.com' + success_email: "Изпратихте покана на {{emailOrUsername}}. Ще Ви уведомим, когато поканата е използвана. Проверявайте раздела с покани на Вашата потребителска страница, за да следите на Вашите покани." + success_username: "Ние поканихме този потребител да се присъедини темата." + error: "Съжаляваме, не можем да поканим този човек. Вероятно вече е потребител? ( Поканите са ограничени)" + login_reply: 'Влезте, за да отговорите ' + filters: + n_posts: + one: 1 публикация + other: '{{count}} публикации' + cancel: "Премахни филтъра" + split_topic: + title: "Премести в нова тема" + action: "премести в нова тема" + topic_name: "Име на новата тема" + error: "Възникна грешка при преместването на публикацията в нова тема." + instructions: + one: На път сте да създадете нова тема и да я запълните с публикацията която избрахте. + other: На път сте да създадете нова тема и да я запълните с {{count}} избрани публикации. + merge_topic: + title: "Преместете в съществуваща тема." + action: "преместете в съществуваща тема." + error: "Възникна грешка при преместване мнения в тази тема." + instructions: + one: 'Моля изберете тема в която искате да преместите тази публикация. ' + other: 'Моля, изберете тема, в която искате да преместите тези {{count}} публикации. ' + change_owner: + title: "Смени собственика на публикацията." + action: "смени собственика" + error: "Възникна грешка при смяната на собственика" + label: "Нов собственик на публикациите" + placeholder: "име на новия собственик" + instructions: + one: Моля изберете нов собственик на публикацията от {{old_user}}. + other: 'Моля, изберете новият собственик на {{count}} публикации от {{old_user}}. ' + instructions_warn: "Имайте предвид, че известията към тази публикация няма да бъдат прехвърлени със задна дата към новия потребител." + change_timestamp: + action: "смени времевия показател" + invalid_timestamp: "Времевия показател неможе да бъде в бъдещето." + error: "Грешка при смяната на времевия показател." + instructions: "Моля, изберете ново заглавие на темата. Публикациите в темата ще бъдат актуализирани, за да имат една и съща времева разлика." + multi_select: + select: 'избери' + selected: 'избрани ({{count}})' + delete: "изтрий избраните " + cancel: прекрати избирането + select_all: "избери всички " + deselect_all: "премахване на всички " + description: + one: Вие избрахте 1 публикация. + other: 'Вие избрахте {{count}} публикации. ' + post: + edit_reason: "Причина: " + post_number: "публикация {{number}} " + last_edited_on: "публикацията последно е редактирана на " + reply_as_new_topic: "Отговори като свързана тема" + continue_discussion: "Продължаване на дискусията от {{postLink}}: " + follow_quote: "отиди на цитираната публикация " + show_full: "Покажи цялата публикация" + show_hidden: 'Виж скритото съдържание.' + deleted_by_author: + one: (публикация оттеглена от автора, ще бъде автоматично изтрита след %{count} час, освен, ако не бъде сигнализирана) + other: '(публикация оттеглена от автора, ще бъде автоматично изтрита след %{count} часа, освен, ако не бъде сигнализирана) ' + expand_collapse: "разшири/намали " + gap: + one: покажи 1 скрит отговор + other: покажи {{count}} скрити отговора + unread: "Публикацията е непрочетена" + has_replies: + one: '{{count}} Отговор' + other: '{{count}} Отговори' + has_likes: + one: '{{count}} Харесване' + other: '{{count}} Харесвания' + has_likes_title: + one: 1 човек харесва тази публикация + other: '{{count}} човека харесват тази публикация' + has_likes_title_only_you: "вие харесахте този пост" + has_likes_title_you: + one: вие и още 1 човек сте харесали този пост + other: вие и {{count}} човека сте харесали този пост + errors: + create: "При създаването на Вашата публикация се получи грешка. Моля, опитайте отново." + edit: "Съжаляваме, възникна грешка при редактирането на публикацията. Моля, опитайте отново. " + upload: "Съжаляваме, възникна грешка при качването на този файл. Моля, опитайте отново." + too_many_uploads: "Съжаляваме, не можете да качвате повече от един файл наведнъж." + image_upload_not_allowed_for_new_user: "Съжаляваме, новите потребители не могат да качват снимки." + attachment_upload_not_allowed_for_new_user: "Съжаляваме, новите потребители не могат да прикачват файлове." + attachment_download_requires_login: "Съжаляваме, трябва да сте логнат, за да може да сваляте прикачените файлове." + abandon: + confirm: "Сигурни ли сте, че искате да напуснете тази публикация?" + no_value: "Не, запази" + yes_value: "Да, напусни" + via_email: "тази публикация пристига чрез имейл" + whisper: "този пост е отбелязан като таен за модераторите" + archetypes: + save: 'Запазете опциите' + few_likes_left: "Благодарим за споделянето на любовта Ви! Вие имате право на само още няколко харесвания за днес." + controls: + reply: "започни отговор на тази публикация" + like: "харесай тази публикация" + has_liked: "Вие харесахте тази публикация" + undo_like: "премахни харесването" + edit: "редактирай тази публикация" + edit_anonymous: "Съжаляваме, но трябва да сте логнат, за да редактирате. " + flag: "скрито сигнализирайте за публикацията, за да ѝ бъде обърнато внимание или изпратете скрито известие за нея" + delete: "изтрий тази публикация" + undelete: "възстановете тази публикация" + share: "сподели връзка към публикацията" + more: "Повече" + admin: "действия на админа на публикации" + wiki: "Направи Wiki съобщение" + unwiki: "Премахни Wiki съобщение" + convert_to_moderator: "Добави цвят за екипа " + revert_to_regular: "Премахни цвета на екипа " + rebake: "Прегенерирай HTML " + unhide: "Покажи " + change_owner: "Смени Правомощията" + actions: + flag: 'Сигнал' + undo: + off_topic: "Отмени сигнала" + spam: "Отмени сигнала " + inappropriate: "Отмени сигнала" + bookmark: "Отмени отметката" + like: "Отмен харесването " + vote: "Отмени гласуването " + people: + off_topic: "отбелязан като оф-топик" + spam: "отбелязан като спам" + inappropriate: "отбелязан като неприемлив" + notify_moderators: "съобщено на модераторите" + notify_user: "изпрати съобщение" + bookmark: "маркирай това" + like: "хареса това" + vote: "гласува за това" + by_you: + off_topic: "Маркирахте това като извън темата" + spam: "Маркирахте това като спам" + inappropriate: "Маркирахте това като неприлично" + notify_moderators: "Маркирахте това за модерация" + notify_user: "Изпратихте лично съобщение на този потребител" + bookmark: "Сложихте тази публикация в Отметки" + like: "Вие харесахте това" + vote: "Гласувахте за тази публикация" + by_you_and_others: + off_topic: + one: Вие и още 1 човек маркирахте това извън темата + other: Вие и още {{count}} човека маркирахте това извън темата + spam: + one: Вие и още 1 човек маркирахте това като спам + other: Вие и още {{count}} човека маркирахте това като спам + inappropriate: + one: Вие и още 1 човек маркирахте това като неприлично + other: Вие и още {{count}} човека маркирахте това като неприлично + notify_moderators: + one: Вие и още 1 човек маркирахте това за модерация + other: Вие и още {{count}} човека маркирахте това за модерация + notify_user: + one: Вие и още 1 човек изпратихте лично съобщение на този потребител + other: Вие и още {{count}} човека изпратихте лично съобщение на този потребител + bookmark: + one: Вие и още 1 човек сложихте тази публикация отметки + other: Вие и още {{count}} човека сложихте тази публикация в Отметки + like: + one: Вие и още 1 човек харесвате това + other: Вие и още {{count}} човека харесахте това + vote: + one: Вие и още 1 човек гласувахте за тази публикация + other: Вие и още {{count}} човека гласувахте за тази публикация + by_others: + off_topic: + one: 1 човек маркира това като извън темата + other: '{{count}} човека маркираха това като извън темата' + spam: + one: 1 човек маркира това като спам + other: '{{count}} човека маркираха това като спам' + inappropriate: + one: 1 човек маркира това като неприлично + other: '{{count}} човека маркираха това като неприлично' + notify_moderators: + one: 1 човек маркира това за модерация + other: '{{count}} човека маркираха това за модерация' + notify_user: + one: 1 човек изпрати съобщение на този потребител + other: '{{count}} човека изпратиха лично съобщение на този потребител' + bookmark: + one: 1 човек сложи този публикация в отметки + other: '{{count}} човека сложиха този публикация в отметки' + like: + one: 1 човек харесва тази публикация + other: '{{count}} човека харесват тази публикация' + vote: + one: 1 човек гласува за тази публикация + other: '{{count}} човека гласуваха за тази публикация' + revisions: + controls: + first: "Първа ревизия" + previous: "Предишна ревизия" + next: "Следваща ревизия" + last: "Последна ревизия" + hide: "Скрий ревизията" + show: "Покажи ревизията" + revert: "Връщане към тази редакция" + comparing_previous_to_current_out_of_total: "{{previous}} {{current}} / {{total}}" + displays: + inline: + title: "Покажи съобщение с включени допълнения и заличавания. " + side_by_side: + title: "Покажи разликите side-by-side " + side_by_side_markdown: + title: "Покажи разликите на неподправения източник side-by-side " + category: + can: 'can…' + none: '(без категория)' + all: 'Всички категории' + choose: 'Изберете категория… ' + edit: 'редкация ' + edit_long: "Редакция" + view: 'Покажи темите в категория ' + general: 'Основни' + settings: 'Настройки' + topic_template: "Шаблон на темата" + tags: "Етикети" + tags_allowed_tags: "Само тези етикети са позволени да се използват в тази категория:" + tags_allowed_tag_groups: "Само етикети от тези групи да се използват в тази категория:" + tags_placeholder: "(По желание) списък на позволените етикети" + delete: 'Изтрий категорията' + create: 'Нова категория' + create_long: 'Създай нова категория' + save: 'Запази категорията' + slug: 'Описателно име за URL ' + slug_placeholder: '(Опционално) пунктирани думи за url ' + creation_error: Възникна грешка при създаването на категория. + save_error: Възникна грешка при запазването на категорията. + name: "Име на категорията" + description: "Описание" + topic: "предмет на категорията" + logo: "Изображение за категория " + background_image: "Изображение за фон на категорията " + badge_colors: "Цветове на значките" + background_color: "Цвят на фона" + foreground_color: "Цвят на преден план" + name_placeholder: "Максимум една или две думи" + color_placeholder: "Някакъв уеб цвят " + delete_confirm: "Сигурни ли сте, че искате да изтриете тази категория? " + delete_error: "Възникна грешка по време на изтриването на категорията. " + list: "Списък Категории " + no_description: "Моля, добавете описание за тази категория. " + change_in_category_topic: "Редактирай Описанието " + already_used: 'Този цвят вече е използван за друга категория. ' + security: "Сигурност" + special_warning: "Внимание: Тази категория е предварително семена категория и настройките й за сигурност не могат да се променят. Ако не искате да използвате тази категория, изтрийте темата си, вместо да я местите в категорията по предназначение." + images: "Изображения" + email_in: "Персонализиран входящ имейл адрес: " + email_in_allow_strangers: "Приемай имейли от анонимни потребители, които нямат регистрация" + email_in_disabled: "Публикуването на нови теми чрез имейл е забранено от настройките на сайта. За да разрешите публикуването на нови теми чрез имейл," + email_in_disabled_click: 'разрешете "email in" настройката ' + allow_badges_label: "Разрешете използването на значки в тази категория. " + edit_permissions: "Редакция на достъпа" + add_permission: "Добави позволение " + this_year: "тази година " + position: "позиция " + default_position: "Позиция по подразбиране " + position_disabled: "Категорията ще се показва в ред на активност. За да контролирате реда на категориите в списъците, " + position_disabled_click: 'Разреши "fixed category positions" настройка ' + minimum_required_tags: 'Минимален брой етикети на тема' + parent: "Главна категория" + notifications: + watching: + title: "Наблюдаване" + description: "Вие ще наблюдавате всички нови теми в тези категории. Ще бъдете информирани за всеки нов пост във всяка тема, и броят на отговорите ще ви бъде показан." + watching_first_post: + title: "Наблюдаване на Първа Публикация" + tracking: + title: "Следене" + regular: + title: "Нормален" + description: "Ще ви уведобим, ако някой ви отговори или спомене вашето @име" + muted: + title: "Заглушени" + description: "Вие никога няма да бъде уведомен за нови теми в тези категории, и те няма да се появят в най-нови." + sort_options: + likes: "Харесвания" + views: "Преглеждания" + posts: "Публикации" + activity: "Активност" + posters: "Автори" + category: "Категория" + created: "Създадени" + sort_ascending: 'В възходящ ред' + sort_descending: 'В низходящ ред' + subcategory_list_styles: + rows: "Редове" + rows_with_featured_topics: "Редове с представени теми" + boxes: "Кутии" + boxes_with_featured_topics: "Кутии с представени теми" + flagging: + title: 'Благодарим ви, че помагате да поддържаме дискусията цивилизована!' + action: 'Сигнализирай публикацията ' + take_action: "Предприеми действие " + notify_action: 'Съобщение' + official_warning: 'Официално предупреждение' + delete_spammer: "Изтрий спамера " + yes_delete_spammer: "Да, изтрий спамера" + ip_address_missing: "(N/A)" + hidden_email_address: "(скрит)" + submit_tooltip: "Пусни скрит сигнал" + take_action_tooltip: "Достигнете границата от сигнали веднага, вместо да чакате за още сигнали от общността" + cant: "Не може да сигнализирате за тази публикация в момента." + notify_staff: 'Съобщи лично на екипа' + formatted_name: + off_topic: "Не е по темата" + inappropriate: "Неподходяща е" + spam: "Съдържа спам" + custom_placeholder_notify_user: "Бъдете точни, конструктивни и учтиви." + custom_placeholder_notify_moderators: "Споделете ни какви точно са Вашите притеснения и ако е възможно ни дайте съответните връзки или примери, които имат отношение по темата." + flagging_topic: + title: "Благодарим ви, че помагате да поддържаме дискусията цивилизована." + action: "Сигнализирай темата" + notify_action: "Съобщение" + topic_map: + title: "Резюме на темата" + participants_title: "Чести автори" + links_title: "Популярни връзки" + links_shown: "покажи повече адреси..." + clicks: + one: 1 кликване + other: '%{count} кликвания' + topic_statuses: + warning: + help: "Това е официално предупреждение." + bookmarked: + help: "Сложихте тази публикация в Отметки" + locked: + help: "Тази тема е затворена; в нея не може да бъде публикувано." + archived: + help: "Тази тема е архивирана; не може да бъде променяна." + locked_and_archived: + help: "Тази тема е затворена и архивирана; тя вече не приема нови отговори и не може да се променя" + unpinned: + title: "Откована" + help: "Тази тема е откована за Вас, тя ще се показва в стандартен ред " + pinned_globally: + title: "Закована глобално" + help: "Тази тема е глобално закована; тя ще се покаже в горната част на най-новите и в нейната категория" + pinned: + title: "Закована" + help: "Тази тема е закована за Вас, тя ще се показва в началото на категорията " + invisible: + help: "Тази тема е скрита; не се появява в списъка с теми и може да бъде достъпна само с директен линк." + posts: "Публикации" + posts_long: "има {{number}} публикации в тази тема" + posts_likes_MF: | + Тази тема има {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: + one: преглед + other: прегледи + replies: "Отговори" + activity: "Активност" + likes: "Харесвания" + likes_lowercase: + one: харесване + other: харесвания + likes_long: "има {{number}} харесвания в тази тема" + users: "Потребители" + users_lowercase: + one: потребител + other: потребители + category_title: "Категория" + history: "История" + changed_by: "от {{author}}" + raw_email: + title: "Входяща поща" + not_available: "Не е наличен!" + categories_list: "Списък с категории" + filters: + with_topics: "%{filter} теми" + with_category: "%{filter} %{category} теми" + latest: + title: "Последни" + title_with_count: + one: Последен (1) + other: Последни ({{count}}) + help: "теми със скорошни публикации" + hot: + title: "Горещи" + help: "Селекция от най-горещите теми" + read: + title: "Прочети" + help: "прочетени теми по реда на прочитане" + search: + title: "Търсене" + help: "търси във всички теми" + categories: + title: "Категории" + title_in: "Категория - {{categoryName}}" + help: "всички теми групирани по категория" + unread: + title: "Непрочетени" + title_with_count: + 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: "Нов" + title_with_count: + one: Нов (1) + other: Нови ({{count}}) + help: "теми създадени през последните няколко дни" + posted: + title: "Моите публикации" + help: "теми в които сте публикували" + bookmarks: + title: "Отметки" + help: "теми, които сте отбелязали в Отметки" + category: + title: "{{categoryName}}" + title_with_count: + one: '{{categoryName}} (1)' + other: '{{categoryName}} ({{count}})' + help: "последни теми в категория {{categoryName}}" + top: + title: "Топ" + help: "Най-активни теми в последната година, месец, седмица или ден" + all: + title: "От началото" + yearly: + title: "Годишно" + quarterly: + title: "Тримесечно" + monthly: + title: "Месечно" + weekly: + title: "Седмично" + daily: + title: "Дневно" + all_time: "От началото" + this_year: "Година" + this_quarter: "Тримесечие" + this_month: "Месец" + this_week: "Седмица" + today: "Днес" + other_periods: "виж отгоре" + browser_update: 'За съжаление, вашият браузър е твърде стар, за да работи с този сайт. Моля, обновете вашия браузър.' + permission_types: + full: "Създай / Отговори / Виж" + create_post: "Отговари / Виж" + readonly: "Виж" + lightbox: + download: "изтегли" + keyboard_shortcuts_help: + title: 'Бързи клавиши' + jump_to: + title: 'Премини към' + navigation: + title: 'Навигация' + up_down: 'k/j Преместване на селекцията ↑ ↓' + open: 'o or Enter Отворяне на избраната тема' + next_prev: 'shift+j/shift+k Следваща/Предишна секция ' + application: + title: 'Приложение' + create: 'c Създайте нова тема' + notifications: 'n Отворяне на известията' + hamburger_menu: '= Отворяне на хамбургерното менюто' + user_profile_menu: 'p Отваряне на потребителското меню' + show_incoming_updated_topics: '. Показване на обновените теми' + search: 'shift+z shift+z Отписване' + help: '? Помощ с клавиатурата ' + dismiss_new_posts: 'x, r Отхвърляне на Нова/Публикации' + dismiss_topics: 'x, t Отхвърляне на темите' + log_out: 'shift+z shift+z Отписване' + composing: + title: 'Съставяне' + return: 'shift+c Връщане към редактора' + actions: + title: 'Действия' + share_post: 's Споделете публикация' + reply_topic: 'shift+r Отговорете на тема' + reply_post: 'r Отговорете на публикация' + mark_watching: 'm, w Наблюдаване на темата' + badges: + title: Значки + allow_title: "Може да използвате тази значка като титла." + successfully_granted: "Успешно дадохте %{badge}на %{username}" + badge_grouping: + trust_level: + name: Ниво на Доверие + tagging: + all_tags: "Всички тагове" + other_tags: "Други тагове" + selector_all_tags: "всички тагове" + selector_no_tags: "няма тагове" + changed: "променени тагове:" + tags: "Тагове" + choose_for_topic: "етикети по желание" + delete_tag: "Изтрийте таг" + manage_groups_description: "Дефинирай групи за организране на етикетите" + notifications: + watching: + title: "Наблюдаване" + description: "Вие автоматично ще следите всички теми с този таг. Ще бъдете информиран за всички нови публикации и теми, и броят на непрочетените и новите публикации ще бъде показан до съответната тема. " + watching_first_post: + title: "Наблюдаване на първа публикация" + description: "Ще бъдете уведомени за първата публикация във всяка нова тема с този етикет." + tracking: + title: "Следене" + description: "Автоматично ще следите всички теми с този етикет. Броя на непрочетените и новите публикации ще се появява до темата." + regular: + title: "Редовен" + description: "Ще бъдете уведомен, ако някой спомене вашето @име или отговори на Ваша публикация." + muted: + title: "Заглушен" + description: "Няма да бъдете уведомявани относно нови теми с този етикет и те няма да се появяват в 'непрочетени'. " + groups: + title: "Групи етикети" + about: "Добавете етикетите към групи за да управлявате по-лесно." + tags_label: "Етикети в тази група:" + parent_tag_description: "Етикетите от тази група не могат да бъдат използвани, освен ако го има родителският етикет" + everyone_can_use: "Етикетите могат да се използват от всички" + usable_only_by_staff: "Етикетите са видими за всички, но само персонал може да ги използва" + visible_only_to_staff: "Етикетите са видими само за персонала" + topics: + none: + search: "Няма резултати от търсенето." + bottom: + read: "Няма повече прочетени теми." + new: "Няма повече нови теми." + unread: "Няма повече непрочетени теми." + top: "Няма повече топ теми." + bookmarks: "Няма теми в Отметки." + search: "Няма повече резултати от търсенето." + invite: + custom_message: "Направете поканата си малко по-лична, като напишете " + custom_message_link: "персонализирано съобщение" + custom_message_placeholder: "Въведете вашето персонализирано съобщение" + custom_message_template_forum: "Хей, трябва да се присъединиш към този форум!" + custom_message_template_topic: "Хей, мисля си, че ще се насладиш на тази тема!" + admin_js: + type_to_filter: "филтрирай..." + admin: + title: 'Discourse Админ' + moderator: 'Модератор' + dashboard: + title: "Работен плот" + last_updated: "Последно обновяване на плота" + version: "Версия" + up_to_date: "Вие сте с последна версия!" + critical_available: "Налична е важна актуализация." + updates_available: "Налична е актуализация." + please_upgrade: "Моля, обновете!" + no_check_performed: "Не е направена проверка за нова версия. Убедете се, че sidekiq работи." + stale_data: "Скоро не е правена проверка за нова версия. Убедете се, че sidekiq работи." + version_check_pending: "Изглежда, че скоро сте обновили версията. Това е чудесно!" + installed_version: "Инсталирани" + latest_version: "Последни" + problems_found: " Открити са някои проблеми при Вашата инсталация на Discourse:" + last_checked: "Последна проверка" + refresh_problems: "Обнови" + no_problems: "Не бяха открити проблеми." + moderators: 'Модератори:' + admins: 'Админи:' + suspended: 'Отстранени:' + private_messages_short: "Съобщения" + private_messages_title: "Съобщения" + mobile_title: "Мобилен" + space_free: "{{size}} свободни" + uploads: "качвания" + backups: "бекъпи" + traffic_short: "Трафик" + traffic: "Приложение уеб заявки" + show_traffic_report: "Покажи детайлен репорт на трафика" + reports: + today: "Днес" + yesterday: "Вчера" + all_time: "От началото" + 7_days_ago: "Преди 7 дни" + 30_days_ago: "Преди 30 дни" + all: "Всички" + view_table: "таблица" + refresh_report: "Обнови доклада" + start_date: "Начална дата" + end_date: "Крайна дата" + groups: "Всички групи" + commits: + latest_changes: "Последни промени: моля обновявайте често! " + by: "от" + flags: + title: "Сигнали" + agree: "Съгласен" + agree_title: "Потвърдете този сигнал като валиден и коректен" + agree_flag_hide_post_title: "Скрий тази публикация и автоматично изпрати съобщение към потребителия спешно да я редактира." + agree_flag_restore_post: "Съгласен (възстанови публикацията) " + agree_flag_restore_post_title: "Възстанови тази публикация така че всички потребители да могат да я виждат." + agree_flag_suspend: "Преустанови потребител" + delete: "Изтрий" + delete_title: "Изтрий публикацията, за която се отнася този сигнал." + delete_post_defer_flag_title: "Изтрий публикацията; ако е първа, изтрий темата" + 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: "Отхвърли този сигнал като неправилен и невалиден" + clear_topic_flags: "Готово" + clear_topic_flags_title: "Темата е проверена и проблемите са разрешени. Натиснете Готово, за да премахнете сигнала. " + more: "(още отговори...) " + dispositions: + agreed: "съгласен" + disagreed: "не съм съгласен" + flagged_by: "Сигнализирано от" + resolved_by: "Разрешено от " + took_action: "Предприеми действие " + system: "Система " + error: "Нещо се обърка" + reply_message: "Отговори" + topic_flagged: "Има сигнал за тази тема/strong>." + visit_topic: "Посети темата за предприемане на действия " + was_edited: "Публикацията беше редактирана след първия сигнал" + previous_flags_count: "За тази публикация беше сигнализирано {{count}} пъти" + groups: + manage: + interaction: + visibility: Видимост + visibility_levels: + public: "Всички" + membership: + trust_level: Ниво на Доверие + trust_levels_title: "Нивото на доверие, което се предоставя автоматично на членовете, когато бъдат добавени:" + primary: "Главна група" + no_primary: "(няма главна група)" + title: "Групи" + edit: "Редакция на групи" + refresh: "Обнови" + about: "Редактирайте членството в групата и имената. " + group_members: "Членове на групата" + delete: "Изтрий" + delete_confirm: "Изтрий тази група?" + delete_failed: "Не можете да изтриете група. Ако това е автоматична група, тя не може да бъде премахната." + delete_owner_confirm: "Махни шефските права на '%{username}'?" + add: "Добави " + custom: "По избор" + automatic: "Автоматично" + group_owners: Собственици + add_owners: Добави собственик + api: + generate_master: "Генерирай главен API ключ" + none: "Няма активни API ключове в момента." + user: "Потребител" + title: "API" + key: "API ключ" + generate: "Генраирай" + regenerate: "Регенерирай" + revoke: "Анулирай" + confirm_regen: "Сигурни ли сте, че искате да замените текущия API ключ с нов ? " + confirm_revoke: "Сигурни ли сте, че искате да анулирате този ключ? " + info_html: "Вашият API ключ ще ви разреши да създавате и обновявате темите чрез JSON извиквания. " + all_users: "Всички потребители" + note_html: "Запазете този ключ secret, всички потребители които го имат ще може да правят публикации от всеки потребител. " + web_hooks: + save: "Запази" + destroy: "Изтрий" + description: "Описание" + post_event: + details: "Когато има нов отговор, редакция, изтриване или възстановяване." + plugins: + title: "Приставки" + installed: "Инсталирани приставки" + name: "Име" + none_installed: "Нямате инсталирани приставки." + version: "Версия" + enabled: "Да е включен?" + is_enabled: "Y " + not_enabled: "N " + change_settings: "Промени Настройките" + change_settings_short: "Настройки" + howto: "Как да инсталирам софтуерни приставки?" + backups: + title: "Бекъп" + menu: + backups: "Бекъпи" + logs: "Логове" + none: "Не е наличен бекъп." + read_only: + enable: + title: "Включване на read-only режим" + label: "Включване на read-only" + confirm: "Сигурни ли сте, че искате да включите режим read-only" + disable: + title: "Изключване на read-only режим" + label: "Изключване на read-only" + logs: + none: "Все още няма логове..." + columns: + filename: "Име на файла" + size: "Размер" + upload: + label: "Качи" + title: "Качи бекъп за тази инстанция" + uploading: "Качва се..." + error: "Появи се грешка при качването на '{{filename}}': {{message}}" + operations: + is_running: "В момента се изпълнява задача..." + failed: "Задачата се провали. Моля проверете логовете." + cancel: + label: "Прекрати" + title: "Прекрати моментната задача" + confirm: "Сигурни ли сте, че искате да прекратите моментната задача?" + backup: + label: "Бекъп" + title: "Създай бекъп" + confirm: "Искате ли да започнете нов бекъп?" + download: + label: "Изтегли" + destroy: + title: "Премахни бекъпа" + confirm: "Сигурни ли сте, че искате да унищожите бекъпа?" + restore: + is_disabled: "Възстановяването е забранено от настройките на сайта. " + label: "Възстанови " + title: "Възстанови бекъпа" + confirm: "Вигурен ли си, че искаш да възтановиш този бекъп?" + rollback: + label: "Върни старата " + title: "Върни базата към последното ѝ работещо състояние" + confirm: "Сигурен ли си, че искаш да върнеш базата до предишното и работещо състояние?" + export_csv: + success: "Експорта е стартиран, Вие ще бъдете информирани чрез лично съобщение когато процесът завърши." + failed: "Експорта се провали. Моля, проверете логовете. " + button_text: "Експорт " + button_title: + user: "Експортирайте списъка с потребители в CSV файл. " + staff_action: "Експортирайте пълния списък с действия на екипа в CSV файл. " + screened_email: "Експортирайте пълния прегледан имейл лист в CSV файл." + screened_ip: "Експортирайте пълния прегледан IP лист в CSV файл. " + screened_url: "Експортирайте пълният прегледан URL лист в CSV файл. " + export_json: + button_text: "Експорт" + invite: + button_text: "Изпрати поканите" + button_title: "Изпрати поканите" + customize: + title: "Персонализация" + long_title: "Персонализация на сайта" + preview: "преглед" + save: "Запази" + new: "Нов" + new_style: "Нов стил" + import: "Импорт" + delete: "Изтрий" + about: "Променете CSS стиловете и HTML хедърите на сайта. Добавете нова настройка за да започнете." + color: "Цвят" + opacity: "Прозрачност" + copy: "Копирай" + email_templates: + title: "Мейл шаблони" + subject: "Тема" + multiple_subjects: "Този мейл шаблон има няколко теми." + body: "Тяло" + none_selected: "Избери мейл шаблон за да започнеш редактирането." + revert: "Върни промените" + revert_confirm: "Сигурен ли си, че искаш да върнеш промените?" + colors: + title: "Цветове" + long_title: "Цветови схеми" + new_name: "Нова цветова схема" + copy_name_prefix: "Копие на" + delete_confirm: "Изтриване на тази цветова схема?" + undo: "отмени" + undo_title: "Върнете промените направени на този цвят до последно запазените." + revert: "върни" + revert_title: "Върни този цвят до стандартните настройки." + primary: + name: 'главен' + description: 'Повече от текстовете, икони и граници ' + secondary: + name: 'второстепенен' + description: 'Основен цвят на фона и цвят на някой бутони.' + tertiary: + name: 'трети' + description: 'Връзки, някои бутони, известия и цветове за акцентиране.' + quaternary: + name: "четвърти" + description: "Връзки за навигация." + header_background: + name: "Фон на хедъра" + description: "Цвят на фона на хедъра на сайта." + header_primary: + name: "главен хедър" + description: "Текстове и икони в хедъра на сайта." + highlight: + name: 'подчертаване' + description: 'Фонов цвят на подчертани елементи на страницата, като публикации и теми.' + danger: + name: 'опасност' + description: 'Цвят за подчертаване на действия, като изтриване на темата.' + success: + name: 'успех' + description: 'Използва се за индикация при успешно действие.' + love: + name: 'любов' + description: "Цвят на бутона харесвам. " + email: + title: "Имейли" + settings: "Настройки" + templates: "Шаблони" + preview_digest: "Преглед на справочника" + sending_test: "Изпраща се тестов имейл..." + error: "ГРЕШКА - %{server_error}" + test_error: "Проблем при изпращането на пробния имейл. Моля, проверете настройките на имейла, вижте дали хостът не блокира имейл връзката и пробвайте отново." + sent: "Изпрати" + skipped: "Пропусни" + received: "Получени" + rejected: "Отхвърлени" + sent_at: "Изпратен в " + time: "Време " + user: "Потребител " + email_type: "Тип Имейл" + to_address: "До адрес " + test_email_address: "имейл адрес за тест " + send_test: "Изпрати тестов имейл " + sent_test: "изпратено!" + delivery_method: "Метод за доставяне " + preview_digest_desc: "Преглед на съдържанието на имейлите, изпратени до неактивните потребители." + refresh: "Опресни" + format: "Формат" + html: "html" + text: "текст" + last_seen_user: "Последно видян потребител: " + no_result: "Не са намерени резултати за резюмиране." + reply_key: "Ключов отговор " + skipped_reason: "Пропусни причина " + incoming_emails: + from_address: "От" + to_addresses: "До" + cc_addresses: "Cc" + 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: + title: "Филтер" + user_placeholder: "потребителско име " + address_placeholder: "name@example.com" + type_placeholder: "дайджест, регистрация" + reply_key_placeholder: "reply key " + skipped_reason_placeholder: "причина" + logs: + title: "Логове" + action: "Действия" + created_at: "Създадени" + last_match_at: "Последно съвпадение" + match_count: "Съвпадения" + ip_address: "IP " + topic_id: "Тема ID " + post_id: "Публикация ID " + category_id: "ID на категорията" + delete: 'Изтрий' + edit: 'Редактирай' + save: 'Запази ' + screened_actions: + block: "Блокирай " + do_nothing: "Не прави нищо " + staff_actions: + title: "Действия на персонала" + clear_filters: "Покажи всичко " + staff_user: "Член на персонала" + target_user: "Целеви потребител " + subject: "Тема " + when: "Кога " + context: "Контекст " + details: "Детайли " + previous_value: "Предишни" + new_value: "Нови " + diff: "Разлика " + show: "Покажи " + modal_title: "Детайли" + no_previous: "Няма предишна стойност. " + deleted: "Няма нова стойност. Записът беше изтрит. " + actions: + delete_user: "изтрий потребител " + change_trust_level: "променете нивото на доверие " + change_username: "Смяна на потребителкото име" + change_site_setting: "промени настройките на сайта " + change_site_text: "промени текста на сайта" + suspend_user: "отстрани потребител " + unsuspend_user: "Върни отстранения потребител " + grant_badge: "присъедини значка " + revoke_badge: "премахни значка " + check_email: "провери имейл " + delete_topic: "изтрий темата " + recover_topic: "възстанови темата" + delete_post: "изтрий публикацията " + impersonate: "представи " + anonymize_user: "анинимизирай потребител" + roll_up: "върнете IP blocks" + change_category_settings: "промени настройките на категорията" + delete_category: "изтрий категория" + create_category: "създай директория" + silence_user: "заглуши потребителя" + grant_admin: "направи админ" + revoke_admin: "премахни админ" + grant_moderation: "позволи модерация" + revoke_moderation: "отмени модерация" + backup_create: "Създай бекъп" + deleted_tag: "изтрит таг" + renamed_tag: "преименуван таг" + lock_trust_level: "заключи нивото на доверие" + unlock_trust_level: "отключи нивото на доверие" + activate_user: "активиране на потребителя" + deactivate_user: "деактивиране на потребителя" + backup_download: "сваляне на архивираното копие" + reviewed_post: "прегледал поста" + post_locked: "публикацията е заключена" + post_unlocked: "публикацията е отключена" + check_personal_message: "провери лично съобщение" + disabled_second_factor: "деактивиране на двуфакторното удостоверяване" + topic_published: "темата е пубикувана" + post_approved: "публикацията е одобрена" + create_badge: "създай значка" + change_badge: "промени значката" + delete_badge: "изтрий значката" + screened_emails: + title: "Проверени имейли" + description: "Когато някой се опита да създаде нов профил, следните имейл адреси ще бъдат проверени и регистрацията ще бъде отказана или ще бъде предприето друго действие." + email: "Имейл адрес" + actions: + allow: "Позволи" + screened_urls: + title: "Проверени URL-та" + description: "Адресите тук са използвани от потребители, идентифицирани като спамери." + url: "URL" + domain: "Домейн" + screened_ips: + title: "Проверени IP-та" + description: 'IP-та, които са наблюдавани. Използвайте "Позволи", за да ги сложите в списъка с разрешени. ' + delete_confirm: "Сигурни ли сте, че искате да премахнете правилото за %{ip_address}? " + roll_up_confirm: "Сигурни ли сте, че искате да обедените често проверените IP адреси в подмрежи?" + rolled_up_some_subnets: "Успешно групирани IP бан записи към следните подмрежи: %{subnets}. " + rolled_up_no_subnet: "Няма нищо за обединяване. " + actions: + block: "Блокирай" + do_nothing: "Позволи" + allow_admin: "Разреши Админ " + form: + label: "Нов:" + ip_address: "IP адрес" + add: "Добави" + filter: "Търсене" + roll_up: + text: "Свиване" + title: "Създава нов бан на подмрежа ако има най-малко 'min_ban_entries_for_roll_up' записи. " + search_logs: + title: "Търсене в логовете" + term: "Термин" + searches: "Търсения" + click_through: "Посещения" + unique: "Уникални" + unique_title: "уникални потребители извършващи търсенето" + types: + full_page: "Пълна страница" + logster: + title: "Логове с грешки" + watched_words: + title: "Наблюдавани думи" + search: "търсене" + clear_filter: "Изчисти" + show_words: "покажи думите" + actions: + block: 'Блокирай ' + censor: 'Цензуриране' + require_approval: 'Изисквай одобрение' + flag: 'Сигнализиране' + impersonate: + title: "Представи" + help: "Използвайте този инструмент, за да предоставите потребителски профили за отстраняване на грешките. Трябва да излезете когато приключите." + not_found: "Този потребител не може да бъде намерен." + invalid: "Съжаляваме, не може да се представяте като този потребител." + users: + title: 'Потребители' + create: 'Добави админ' + last_emailed: "Последен имейл" + not_found: "Съжаляваме, това потребителско име не съществува при нас." + id_not_found: "Съжаляваме, това потребителско име не съществува при нас. " + active: "Активен" + show_emails: "Покажи имейла" + nav: + new: "Нови" + active: "Активни" + pending: "Чакащи" + staff: 'Персонал' + suspended: 'Отстранени' + suspect: 'Съмнителен ' + approved: "Одобрен?" + approved_selected: + one: одобрен потребител + other: одобрени потребители ({{count}}) + reject_selected: + one: отхвърлен потребител + other: отхвърлени потребители ({{count}}) + titles: + active: 'Активни потребители' + new: 'Нови потребители' + pending: 'Чакащи потребители' + newuser: 'Потребители с Ниво на доверие 0 (нов)' + basic: 'Потребители с Ниво на доверие 1 (основен)' + member: 'Потребители с Ниво за сигурност 2 (Членове)' + regular: 'Потребители с Ниво за сигурност 3 (Редовни)' + leader: 'Потребители с Ниво на доверие 4 (лидер)' + staff: "Персонал " + admins: 'Админи' + moderators: 'Модератори' + suspended: 'Отстранени' + suspect: 'Съмнителни потребители ' + reject_successful: + one: Отхвърлите 1 потребител. + other: Успешно отхвърлите %{count} потребителя. + reject_failures: + one: Не успяхте да отхвърлите 1 потребител. + other: Не успяхте да отхвърлите %{count} юзъра + not_verified: "Непроверен " + check_email: + title: "Разкрий имейла на този потребител" + text: "Покажи" + user: + suspend_failed: "Нещо се обърка при отстраняването на този потребител {{error}}" + unsuspend_failed: "Нещо се обърка при отстраняването на този потребител {{error}} " + suspend_duration: "За колко време потребителят ще бъде отстранен?" + suspend_reason_label: "Защо отстранявате? Този текст ще бъде видим за всички на профилната страница на потребителя и ще се показва на потребителя, когато направи опит да се логне. Бъдете кратки." + suspend_reason: "Причина" + suspended_by: "Отстранен от" + delete_all_posts: "Изтрий всички публикации. " + moderator: "Модератор? " + admin: "Админ? " + suspended: "Отстранен? " + staged: "Поставен?" + show_admin_profile: "Админ" + refresh_browsers: "Принудително опресняване на браузъра " + refresh_browsers_message: "Съобщението е изпратено до всички клиенти! " + show_public_profile: "Покажи публичния профил " + impersonate: 'Представени ' + ip_lookup: "IP търсене " + log_out: "Изход " + logged_out: "Потребителя беше разлогнат от всички устройства " + revoke_admin: 'Анулирай Админ ' + grant_admin: 'Грант Админ ' + revoke_moderation: 'Отстрани модерирането ' + grant_moderation: 'Грант Модерация' + unsuspend: 'Върнат' + suspend: 'Отстрани ' + reputation: Репутация + permissions: "Позволения " + activity: Активност + like_count: "Харесвания Дадени / Получени " + last_100_days: 'В последните 100 дни ' + private_topics_count: Частни теми + posts_read_count: "Прочетени публикации " + post_count: "Създадени публикации " + topics_entered: "Прегледани теми " + flags_given_count: "Дадени сигнали " + flags_received_count: "Получени сигнали " + warnings_received_count: "Получени предупреждения " + flags_given_received_count: 'Сигнали Дадени / Получени ' + approve: 'Одобри ' + approved_by: "одобрено от " + approve_success: "Потребителят е одобрен и е изпратен имейл с инструкции за активиране. " + approve_bulk_success: "Готово! Всички избрани потребители бяха одобрени и информирани. " + time_read: "Време за прочитане " + anonymize: "Анинимизирай потребител" + anonymize_confirm: "Сигурни ли сте че искате да анонимизирате този акаунт? Това ще промени потребителското име, имейл адреса и информацията в профила." + anonymize_yes: "Да, анонимизирай този профил" + anonymize_failed: "Възникна грешка по време на анонимизирането на профила." + delete: "Изтрий потребител " + delete_forbidden_because_staff: "Админите и модераторите не могат да бъдат изтрити." + delete_posts_forbidden_because_staff: "Не могат да бъдат изтрити всички постове на администратори и модератори." + delete_forbidden: + one: Не може да изтривате потребители които имат публикации. Първо изтрийте всички публикации на този потребител и опитайте отново. (Публикации по стари от %{count} ден не може да бъдат изтривани) + other: 'Не може да изтривате потребители, които имат публикации. Първо изтрийте всички публикации на този потребител и опитайте отново. (Публикации по стари от %{count} дни не могат да бъдат изтрити.) ' + cant_delete_all_posts: + one: Не може да изтриете всички публикации. Някои публикации са по стари от %{count} ден. (delete_user_max_post_age настройката) + other: 'Не може да изтриете всички публикации. Някои публикации са по стари от %{count} дни. (delete_user_max_post_age настройката) ' + cant_delete_all_too_many_posts: + one: Не може да изтриете всички публикации защото този потребител има 1 публикация. (delete_all_posts_max) + other: 'Не може да изтриете всички публикации, защото този потребител има повече от %{count} публикации.(delete_all_posts_max) ' + delete_confirm: "Сигурни ли сте, че искате да изтриете този потребител. Това е необратимо!" + delete_and_block: "Изтрийте и блокирайте този имейл и IP адрес " + delete_dont_block: "Изтрий само " + deleted: "Потребителя беше изтрит. " + delete_failed: "Възникна грешка при изтриването на този потребител. Първо се уверете, че всички негови публикации са изтрити и опитайте отново." + send_activation_email: "Изпрати активационен имейл " + activation_email_sent: "Изпратен е активационен имейл. " + send_activation_email_failed: "Възникна проблем при изпращането на друг активационен имейл. %{error} " + activate: "Активирай профила" + activate_failed: "Възникна проблем с активирането на потребителя. " + deactivate_account: "Деактивирай профила" + deactivate_failed: "Възникна проблем при деактивирането на потребителя. " + deactivate_explanation: "Деактивирания потребител трябва повторно да валидира неговия имейл. " + suspended_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" + value_heading: "Стойност" + 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: "Получени харесвания: уникални потребители " + 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: "Нивото на доверие е заключено. Никога няма да се понижават. " + sso: + title: "Single Sign On" + external_id: "Външно ID " + external_username: "Потребителско име" + external_name: "Име " + external_email: "Имейл " + external_avatar_url: "URL до аватара" + user_fields: + title: "User Fields" + help: "Добавете поле, което потребителите ще могат да попълват." + create: "Създай поле" + untitled: "Untitled" + name: "Име на полето" + type: "Вид на полето" + description: "Описание на полето" + save: "Запази" + edit: "Редактирай" + delete: "Изтрий" + cancel: "Прекрати" + delete_confirm: "Сигурни ли сте, че искате да изтриете това потребителско поле?" + options: "Опции" + required: + title: "Да се изисква при регистрация?" + enabled: "задължително" + disabled: "по желание" + editable: + title: "Да се редактира след регистрация?" + enabled: "може да се редактира" + disabled: "Текстово поле" + show_on_profile: + title: "Покажи на публичния профил?" + enabled: "показано на профила" + disabled: "не се показва на профила" + show_on_user_card: + title: "Показване в потребителската карта?" + enabled: "показано в потребителската карта" + disabled: "не е показано в потребителската карта" + field_types: + text: 'Текстово поле' + confirm: 'Потвърждение' + dropdown: "Падащо" + site_text: + description: "Можете да персонализирате всеки текст от вашия форум. Моля, започнете, като търсите по-долу:" + search: "Търсене на текст които искате да редактирате" + title: 'Текстово съдържание. ' + edit: 'промени' + revert: "Върни промените" + revert_confirm: "Сигурен ли си, че искаш да върнеш промените?" + go_back: "Към търсачката" + recommended: "За вашите нужди, Ви препоръчваме да редактирате следният текст:" + show_overriden: 'Избери само презаписаните' + settings: + show_overriden: 'Показване само на презаписаните' + reset: 'изчисти' + site_settings: + title: 'Настройки' + no_results: "Няма резултати" + more_than_30_results: "Има повече от 30 резултата. Моля, прецизирайте търсенето си или изберете категория." + clear_filter: "Изчисти" + add_url: "добавяне на URL" + add_host: "добави хост" + categories: + all_results: 'Всички' + required: 'Задъжителни' + basic: 'Основни' + users: 'Потребители' + posting: 'Публикуване' + email: 'Имейл' + files: 'Файлове' + trust: 'Нива на доверие' + security: 'Сигурност' + onebox: "Onebox" + seo: 'SEO' + spam: 'Спам' + rate_limits: 'Лимити' + developer: 'Разработчик' + embedding: "Ембедване" + legal: "Правни" + uncategorized: 'Други' + backups: "Бекъп" + login: "Логване" + plugins: "Приставки" + user_preferences: "Потребителски Настройки" + tags: "Етикети" + search: "Търсене" + groups: "Групи" + badges: + title: Значки + new_badge: Нова значка + new: Нова + name: Име + badge: Значка + display_name: Име + description: Описание + long_description: Дълго описание + badge_type: Тип на значката + badge_grouping: Група + badge_groupings: + modal_title: Групи значки + granted_by: Присъдена от + granted_at: Присъдена на + reason_help: (Връзка към публикация или тема) + save: Запази + delete: Изтрий + delete_confirm: "Искате ли да изтриете тази значка?" + revoke: Анулирай + reason: Причина + expand: Разширяване … + revoke_confirm: "Сигурни ли сте, че искате да анулирате значката?" + edit_badges: Редактирай значката + grant_badge: Присъдени значка + granted_badges: Присъединени значки + grant: Присъдете + no_user_badges: "%{name} няма присъдени значки." + no_badges: Няма значки които биха могли да се присъдят. + none_selected: "Изберете значка за да започнете." + allow_title: Позволете значките да бъдат ползвани като титли. + multiple_grant: Може да бъде присъдена няколко пъти + listable: Показвай значката на страницата със значки + enabled: Разрешете значката + icon: Икона + image: Изображение + query: Badge Query (SQL) + target_posts: "Запитване за насочени публикации " + auto_revoke: Пусни заявката за отмяна ежедневно + show_posts: " Покажи съобщението, заради което е дадена значката, на страницата със значките " + trigger: "Тригер " + trigger_type: + none: "Обнови дневно " + post_action: "Когато потребителят въздейства върху публикация" + post_revision: "Когато потребителят редактира или създава публикация" + trust_level_change: "Когато потребителят променя Нивото на доверие" + user_change: "Когато потребителят е редактиран или създаден " + post_processed: "След като публикацията се преработи" + preview: + link_text: "Покажи спечелените значки " + plan_text: "Преглед с query plan " + modal_title: "Преглед на заявките за значки" + sql_error_header: "Възникна грешка със заявката. " + error_help: "Покажи следните линкове за помощ със заявките за значки. " + bad_count_warning: + header: "ВНИМАНИЕ!" + text: "Открити са примери за несъществуващи награди. Това може да се случи когато заявката за бадж се връща при несъществуващо потребителско име или съобщение. Това може да доведе до неочаквани резултати - моля проверете вашата заявка отново." + no_grant_count: "Няма значки за закачане." + grant_count: + one: 1 значка за закачане. + other: %{count} значки за закачане. + sample: "Образец: " + grant: + with: "%{username} " + with_post: "%{username} за публикации в %{link} " + with_post_time: "%{username} за публикация %{link} в %{time} " + with_time: "%{username} в %{time} " + emoji: + title: "Емотикони " + help: "Добави нови емотикони, които ще бъдат достъпни до всички. (Съвет: Може да дръпнете и пуснете много файлове наведнъж). " + add: "Добави нова емотикона " + 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 настройки" + feed_description: "Чрез RSS/ATOM вие може да подобрите възможностите на Discourse да внедри вашето съдържание." + crawling_settings: "Crawler настройки" + crawling_description: "Когато Discourse създаде теми за вашите мнения и ако RSS / ATOM емисия не присъства, тя ще се опита да направи разбор на съдържанието от вашия HTML. Понякога това може да бъде предизвикателство за извличане на съдържанието ви, така че ние предоставяме възможността да се определи като CSS правила и да се направи екстракцията по-лесно." + embed_by_username: "Потребител за създаване на темата" + embed_post_limit: "Максимален брой публикации за вграждане." + embed_username_key_from_feed: "Ключ за изтегляне на discourse потребителя от feed-а" + embed_truncate: "Изтрий вградените постове" + embed_whitelist_selector: "Избор на CSS елементи които са разрешени за вграждане" + embed_blacklist_selector: "Избор на CSS елементи които не са разрешени за вграждане" + feed_polling_enabled: "Внеси постове чреч RSS/ATOM" + feed_polling_url: "URL адрес на RSS/ATOM връзката" + save: "Запамети настройките за вграждане" + permalink: + title: "Постоянни адреси" + url: "URL" + topic_id: "Тема ID " + topic_title: "Тема" + post_id: "Публикация ID " + post_title: "Публикация" + category_id: "Категория ID" + category_title: "Категория" + external_url: "Външен URL" + delete_confirm: "Сигурни ли сте, че искате да изриете този постоянен адрес?" + form: + label: "Нов:" + add: "Добави" + filter: "Търсене (URL или външно URL)" + wizard_js: + wizard: + done: "Готово" + back: "Назад" + next: "Напред" + upload: "Качване" + uploading: "Качва се..." + quit: "Може би по-късно" + invites: + add_user: "добавяне" + roles: + admin: "Администратор" + moderator: "Модератор" + regular: "Обикновен потребител" diff --git a/config/locales/client.bs_BA.yml b/config/locales/client.bs_BA.yml index 3423337eee..e1f8f0737e 100644 --- a/config/locales/client.bs_BA.yml +++ b/config/locales/client.bs_BA.yml @@ -1710,7 +1710,6 @@ bs_BA: backup: title: "Create a backup" confirm: "Do you want to start a new backup?" - without_uploads: "Yes (do not include files)" destroy: title: "Remove the backup" confirm: "Are you sure you want to destroy this backup?" diff --git a/config/locales/client.ca.yml b/config/locales/client.ca.yml index 1ae48f76ef..6727ff03da 100644 --- a/config/locales/client.ca.yml +++ b/config/locales/client.ca.yml @@ -2292,7 +2292,6 @@ ca: label: "Còpia de seguretat" title: "Crea una còpia de seguretat" confirm: "Vols iniciar una nova còpia de seguretat?" - without_uploads: "Sí (no hi incloguis fitxers)" download: label: "Descarrega" destroy: @@ -2834,7 +2833,6 @@ ca: enabled: Activa distintiu icon: Icona image: Imatge - icon_help: "Fes servir la classe Font Awesome o una URL a una imatge" query: Consulta distintius (SQL) target_posts: La consulta apunta les publicacions auto_revoke: Executa la consulta diària de revocacions diff --git a/config/locales/client.cs.yml b/config/locales/client.cs.yml index c3e64e8e42..67e5c43984 100644 --- a/config/locales/client.cs.yml +++ b/config/locales/client.cs.yml @@ -454,7 +454,6 @@ cs: all: "Všechny skupiny" empty: "Žádné viditelné skupiny." filter: "Filtrovat podle typu skupiny" - all_groups: "Všechny skupiny" owner_groups: "Skupiny, jejichž jsem majitelem" close_groups: "Uzavřené skupiny" automatic_groups: "Automatické skupiny" @@ -2962,7 +2961,6 @@ cs: label: "Záloha" title: "Vytvořit zálohu" confirm: "Chcete začít novou zálohu?" - without_uploads: "Ano (nepřikládej soubory)" download: label: "Stáhnout" title: "Poslat e-mail s odkazem ke stažení" @@ -3708,7 +3706,6 @@ cs: enabled: Povolit odznaky icon: Ikona image: Obrázek - icon_help: "Použijte buď Font Awesome nebo URL k obrázku." query: Dotaz na odznak (SQL) target_posts: Zeptat se na cílový příspěvek auto_revoke: Denně spouštět zrušení dotazu diff --git a/config/locales/client.da.yml b/config/locales/client.da.yml index ea85c57961..15d5ac6282 100644 --- a/config/locales/client.da.yml +++ b/config/locales/client.da.yml @@ -2328,7 +2328,6 @@ da: label: "Backup" title: "Start backup" confirm: "Vil du starte en ny backup?" - without_uploads: "Ja (inkluder ikke filer)" download: label: "Download" title: "Send e-mail med downloadlink" @@ -2938,7 +2937,6 @@ da: enabled: Aktiver badge icon: Icon image: Billede - icon_help: "Bruge enten en \"Font Awesome\" klasse eller URL til et billede" query: Badge Forespørgesel (SQL) target_posts: Forespørg mål indlæg auto_revoke: Kør tilbagekaldelses forespørgsel hver dag diff --git a/config/locales/client.de.yml b/config/locales/client.de.yml index b17c633b38..f44debdd79 100644 --- a/config/locales/client.de.yml +++ b/config/locales/client.de.yml @@ -62,7 +62,7 @@ de: other: '%{count}d' x_months: one: 1 Monat - other: '%{count}Monate' + other: '%{count}m' about_x_years: one: 1a other: '%{count}a' @@ -225,6 +225,8 @@ de: our_moderators: "Unsere Moderatoren" stat: all_time: "Gesamt" + last_7_days: "Letzte 7" + last_30_days: "Letzte 30" like_count: "Likes" topic_count: "Themen" post_count: "Beiträge" @@ -405,7 +407,6 @@ de: all: "Alle Gruppen" empty: "Es gibt keine sichtbaren Gruppen." filter: "Filtern nach Art der Gruppe" - all_groups: "Alle Gruppen" owner_groups: "Gruppen, deren Eigentümer ich bin" close_groups: "Geschlossene Gruppe" automatic_groups: "Automatische Gruppen" @@ -560,7 +561,7 @@ de: perm_denied_expl: "Du hast das Anzeigen von Benachrichtigungen verboten. Aktiviere die Benachrichtigungen über deine Browser-Einstellungen." disable: "Benachrichtigungen deaktivieren" enable: "Benachrichtigungen aktivieren" - each_browser_note: "Hinweis: Du musst diese Einstellung in jedem von dir verwendeten Browser ändern." + each_browser_note: "Hinweis: Du musst diese Einstellung in jedem Browser einzeln ändern." consent_prompt: "Möchtest du Live-Benachrichtigungen erhalten, wenn jemand auf deine Beiträge antwortet?" dismiss: 'Alles gelesen' dismiss_notifications: "Alles gelesen" @@ -593,9 +594,10 @@ de: individual_no_echo: "Sende für alle fremden Beträge eine Email" many_per_day: "Sende mir für jeden neuen Beitrag eine E-Mail (etwa {{dailyEmailEstimate}} pro Tag)" few_per_day: "Sende mir für jeden neuen Beitrag eine E-Mail (etwa 2 pro Tag)" + warning: "Mailinglisten-Modus aktiviert. Einstellungen zur Benachrichtigung per E-Mail werden nicht berücksichtigt." tag_settings: "Schlagwörter" watched_tags: "Beobachtet" - watched_tags_instructions: "Du wirst automatisch alle neuen Themen imit diesen Schlagwörtern beobachten. Du wirst über alle neuen Beiträge und Themen benachrichtigt und die Anzahl der neuen Antworten wird bei den betroffenen Themen angezeigt." + watched_tags_instructions: "Du wirst automatisch alle neuen Themen mit diesen Schlagwörtern beobachten. Du wirst über alle neuen Beiträge und Themen benachrichtigt und die Anzahl der neuen Antworten wird bei den betroffenen Themen angezeigt." tracked_tags: "Verfolgt" tracked_tags_instructions: "Du wirst automatisch alle Themen mit diesen Schlagwörtern verfolgen. Die Anzahl der neuen Antworten wird bei den betroffenen Themen angezeigt." muted_tags: "Stummgeschaltet" @@ -619,7 +621,7 @@ de: admin_delete: "Löschen" users: "Benutzer" muted_users: "Stummgeschaltet" - muted_users_instructions: "Alle Benachrichtigungen von diesem Benutzer unterdrücken." + muted_users_instructions: "Benachrichtigungen von diesen Benutzern werden unterdrückt." muted_topics_link: "Zeige stummgeschaltete Themen" watched_topics_link: "Zeige beobachtete Themen" tracked_topics_link: "Zeige verfolgte Themen" @@ -667,9 +669,9 @@ de: choose_new: "Wähle ein neues Passwort" choose: "Wähle ein Passwort" second_factor: - title: "Zwei-Faktor Authentifizierung" + title: "Zwei-Faktor-Authentifizierung" disable: "Zwei-Faktor-Authentifizierung deaktivieren" - enable: "für verstärkte Konto-Sicherheit" + enable: "Zwei-Faktor-Authentifizierung aktivieren, um das Benutzerkonto besser zu schützen" confirm_password_description: "Bitte bestätige dein Passwort um fortzufahren" label: "Code" enable_description: | @@ -757,8 +759,8 @@ de: 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" + first_time_and_daily: "für den ersten Like sowie maximal täglich" + first_time: "nur für den ersten Like eines Beitrags" never: "nie" email_previous_replies: title: "Füge vorherige Beiträge ans Ende von E-Mails an" @@ -781,14 +783,14 @@ de: other_settings: "Andere" categories_settings: "Kategorien" new_topic_duration: - label: "Themen als neu ansehen, wenn" + label: "Themen als neu anzeigen, wenn" not_viewed: "ich diese noch nicht betrachtet habe" last_here: "seit meinem letzten Besuch erstellt" after_1_day: "innerhalb des letzten Tages erstellt" after_2_days: "in den letzten 2 Tagen erstellt" after_1_week: "in der letzten Woche erstellt" after_2_weeks: "in den letzten 2 Wochen erstellt" - auto_track_topics: "Betrachteten Themen automatisch folgen" + auto_track_topics: "Betrachtete Themen automatisch folgen" auto_track_options: never: "nie" immediately: "sofort" @@ -1217,9 +1219,9 @@ de: italic_label: "K" italic_title: "Betonung" italic_text: "Betonter Text" - link_title: "Hyperlink" + link_title: "Link" link_description: "gib hier eine Link-Beschreibung ein" - link_dialog_title: "Hyperlink einfügen" + link_dialog_title: "Link einfügen" link_optional_text: "Optionaler Titel" link_url_placeholder: "http://example.com" quote_title: "Zitat" @@ -1230,7 +1232,7 @@ de: upload_title: "Upload" upload_description: "gib hier eine Beschreibung des Uploads ein" olist_title: "Nummerierte Liste" - ulist_title: "Liste mit Aufzählungszeichen" + ulist_title: "Liste" list_item: "Listenelement" toggle_direction: "Schreibrichtung wechseln" help: "Hilfe zur Markdown-Formatierung" @@ -1371,6 +1373,7 @@ de: label: Mit dem Schlagwort filters: label: "Themen/Beiträge einschränken:" + title: mit Treffer im Titel likes: "Themen/Beiträge, die mir gefallen" posted: Themen mit Beiträgen von mir watching: "Themen, die ich beobachte" @@ -1758,6 +1761,7 @@ de: instructions: one: Bitte wähle den neuen Eigentümer für den Beitrag von {{old_user}}. other: Bitte wähle den neuen Eigentümer für {{count}} Beiträge von {{old_user}}. + instructions_warn: "Bitte beachte, dass alle Benachrichtigungen für diesen Beitrag nicht rückwirkend auf den neuen Benutzer übertragen werden." change_timestamp: title: "Zeitstempel ändern…" action: "Erstelldatum ändern" @@ -2478,6 +2482,8 @@ de: dashboard: title: "Übersicht" last_updated: "Übersicht zuletzt aktualisiert:" + find_old: "Suchst du das alte Dashboard?" + old_link: "besuche es hier" version: "Version" up_to_date: "Du verwendest die neueste Version!" critical_available: "Ein kritisches Update ist verfügbar." @@ -2515,6 +2521,8 @@ de: trend_title: "%{percent} Veränderung. Aktuell %{current}, war %{prev} in vorherigem Zeitraum." today: "Heute" yesterday: "Gestern" + last_7_days: "Letzte 7" + last_30_days: "Letzte 30" all_time: "Gesamt" 7_days_ago: "vor 7 Tagen" 30_days_ago: "vor 30 Tagen" @@ -2525,6 +2533,10 @@ de: start_date: "Startdatum" end_date: "Enddatum" groups: "Alle Gruppen" + disabled: "Dieser Bericht ist deaktiviert" + trending_search: + more: 'Suchprotokoll' + disabled: 'Der Bericht über beliebte Suchen ist deaktiviert. Aktiviere Suchanfragen protokollieren, um die Daten zu erheben.' commits: latest_changes: "Letzte Änderungen: bitte häufig updaten!" by: "von" @@ -3100,6 +3112,8 @@ de: change_site_text: "Text ändern" suspend_user: "Benutzer sperren" unsuspend_user: "Benutzer entsperren" + removed_suspend_user: "Benutzer sperren (entfernt)" + removed_unsuspend_user: "Benutzer entsperren (entfernt)" grant_badge: "Abzeichen verleihen" revoke_badge: "Abzeichen entziehen" check_email: "E-Mail abrufen" @@ -3114,6 +3128,8 @@ de: create_category: "Kategorie erstellen" silence_user: "Benutzer stummschalten" unsilence_user: "Benutzer nicht mehr stummschalten" + removed_silence_user: "Benutzer stummschalten (entfernt)" + removed_unsilence_user: "Benutzer nicht mehr stummschalten (entfernt)" grant_admin: "Administration gewähren" revoke_admin: "Administration entziehen" grant_moderation: "Moderation gewähren" @@ -3138,6 +3154,9 @@ de: disabled_second_factor: "Zwei-Faktor-Authentifizierung deaktiviert" topic_published: "Thema veröffentlicht" post_approved: "Beitrag genehmigt" + create_badge: "Abzeichen erstellen" + change_badge: "Abzeichen ändern" + delete_badge: "Abzeichen löschen" 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." @@ -3207,6 +3226,7 @@ de: placeholder_regexp: "regulärer Ausdruck" add: 'Hinzufügen' success: 'Erfolg' + exists: 'Existiert bereits' upload: "Hochladen" upload_successful: "Hochladen erfolgreich. Wörter wurden hinzugefügt." impersonate: @@ -3230,6 +3250,7 @@ de: suspended: 'Gesperrt' silenced: 'Stummgeschaltet' suspect: 'Verdächtig' + staged: 'Vorbereitet' approved: "Genehmigt?" approved_selected: one: Benutzer genehmigen @@ -3252,6 +3273,7 @@ de: silenced: 'Stummgeschaltete Benutzer' suspended: 'Gesperrte Benutzer' suspect: 'Verdächtige Benutzer' + staged: 'Vorbereite Benutzer' reject_successful: one: Erfolgreich 1 Benutzer abgelehnt. other: Erfolgreich %{count} Benutzer abgelehnt. @@ -3288,6 +3310,10 @@ de: penalty_post_delete: "Beitrag löschen" penalty_post_edit: "Beitrag bearbeiten" penalty_post_none: "Nichts tun" + penalty_count: "Anzahl der Strafen" + clear_penalty_history: + title: "Lösche die Strafenhistorie" + description: "Benutzer mit Strafen können TL3 nicht erreichen" delete_all_posts_confirm_MF: "Du wirst {POSTS, plural, one {einen Beitrag} other {# Beiträge}} und {TOPICS, plural, one {ein Thema} other {# Themen}} löschen. Bist du dir sicher?" silence: "Stummschalten" unsilence: "Stummschaltung aufheben" @@ -3475,6 +3501,7 @@ de: site_settings: title: 'Einstellungen' no_results: "Keine Ergebnisse gefunden." + more_than_30_results: "Es gibt mehr als 30 Ergebnisse. Bitte grenze deine Suche weiter ein oder wähle eine Kategorie aus." clear_filter: "Filter zurücksetzen" add_url: "URL hinzufügen" add_host: "Host hinzufügen" @@ -3541,7 +3568,8 @@ de: enabled: Abzeichen aktivieren icon: Symbol image: Bild - icon_help: "Benutze eine Font Awesome class oder die URL eines Bildes" + icon_help: "Benutze eine Font Awesome class" + image_help: "Gebe die URL eines Bildes ein (überschreibt Symbol Feld wenn beide aktiv sind)" query: Abzeichen-Abfrage (SQL) target_posts: Abfrage betrifft Beiträge auto_revoke: Führe die Abfrage zum Widerruf täglich aus diff --git a/config/locales/client.el.yml b/config/locales/client.el.yml index cea5b7fdd0..4a71ab2ec8 100644 --- a/config/locales/client.el.yml +++ b/config/locales/client.el.yml @@ -2490,7 +2490,6 @@ el: label: "Αντίγραφο ασφαλείας" title: "Δημιουργία αντίγραφου ασφαλείας" confirm: "Θέλεις να ξεκινήσεις τη δημιουργία ενός νέου αντίγραφου ασφαλείας;" - without_uploads: "Ναι (χωρίς τα αρχεία)" download: label: "Κατέβασμα" title: "Αποστολή email με σύνδεσμο λήψης" @@ -3173,7 +3172,6 @@ el: enabled: Ενεργοποίηση παράσημου icon: Σύμβολο image: Εικόνα - icon_help: "Χρησιμοποίησε είτε μια κλάση Font Awesome ή το URL μιας εικόνας" query: Ερώτηση παράσημου (SQL) target_posts: Το ερώτημα αφορά αναρτήσεις auto_revoke: Τρέξε καθημερινά το ερώτημα για την ανάκληση diff --git a/config/locales/client.en.yml b/config/locales/client.en.yml index 44e4b4c18e..e433e46f12 100644 --- a/config/locales/client.en.yml +++ b/config/locales/client.en.yml @@ -464,7 +464,6 @@ en: all: "All Groups" empty: "There are no visible groups." filter: "Filter by group type" - all_groups: "All Groups" owner_groups: "Groups I am an owner of" close_groups: "Closed Groups" automatic_groups: "Automatic Groups" @@ -659,6 +658,7 @@ en: individual_no_echo: "Send an email for every new post except my own" many_per_day: "Send me an email for every new post (about {{dailyEmailEstimate}} per day)" few_per_day: "Send me an email for every new post (about 2 per day)" + warning: "Mailing list mode enabled. Email notification settings are overridden." tag_settings: "Tags" watched_tags: "Watched" watched_tags_instructions: "You will automatically watch all topics with these tags. You will be notified of all new posts and topics, and a count of new posts will also appear next to the topic." @@ -741,7 +741,7 @@ en: second_factor: title: "Two Factor Authentication" disable: "Disable two factor authentication" - enable: "for enhanced account security" + enable: "Enable two factor authentication for enhanced account security" confirm_password_description: "Please confirm your password to continue" label: "Code" enable_description: | @@ -1507,6 +1507,7 @@ en: label: Tagged filters: label: Only return topics/posts... + title: Matching in title only likes: I liked posted: I posted in watching: I'm watching @@ -3061,7 +3062,7 @@ en: label: "Backup" title: "Create a backup" confirm: "Do you want to start a new backup?" - without_uploads: "Yes (do not include files)" + without_uploads: "Yes (do not include uploads)" download: label: "Download" title: "Send email with download link" @@ -3363,6 +3364,8 @@ en: change_site_text: "change site text" suspend_user: "suspend user" unsuspend_user: "unsuspend user" + removed_suspend_user: "suspend user (removed)" + removed_unsuspend_user: "unsuspend user (removed)" grant_badge: "grant badge" revoke_badge: "revoke badge" check_email: "check email" @@ -3377,6 +3380,8 @@ en: create_category: "create category" silence_user: "silence user" unsilence_user: "unsilence user" + removed_silence_user: "silence user (removed)" + removed_unsilence_user: "unsilence user (removed)" grant_admin: "grant admin" revoke_admin: "revoke admin" grant_moderation: "grant moderation" @@ -3401,6 +3406,9 @@ en: disabled_second_factor: "disable Two Factor Authentication" topic_published: "topic published" post_approved: "post approved" + create_badge: "create badge" + change_badge: "change badge" + delete_badge: "delete badge" 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." @@ -3471,6 +3479,7 @@ en: placeholder_regexp: "regular expression" add: 'Add' success: 'Success' + exists: 'Already exists' upload: "Upload" upload_successful: "Upload successful. Words have been added." @@ -3557,6 +3566,10 @@ en: penalty_post_delete: "Delete the post" penalty_post_edit: "Edit the post" penalty_post_none: "Do nothing" + penalty_count: "Penalty Count" + clear_penalty_history: + title: "Clear Penalty History" + description: "users with penalties cannot reach TL3" # keys ending with _MF use message format, see https://meta.discourse.org/t/message-format-support-for-localization/7035 for details delete_all_posts_confirm_MF: "You are about to delete {POSTS, plural, one {1 post} other {# posts}} and {TOPICS, plural, one {1 topic} other {# topics}}. Are you sure?" @@ -3819,7 +3832,8 @@ en: enabled: Enable badge icon: Icon image: Image - icon_help: "Use either a Font Awesome class or URL to an image" + icon_help: "Use a Font Awesome class" + image_help: "Enter the URL of the image (overrides icon field if both are set)" query: Badge Query (SQL) target_posts: Query targets posts auto_revoke: Run revocation query daily diff --git a/config/locales/client.es.yml b/config/locales/client.es.yml index 5dc4d47c4e..c3d635e8fd 100644 --- a/config/locales/client.es.yml +++ b/config/locales/client.es.yml @@ -106,7 +106,7 @@ es: one: '%{count} año después' other: '%{count} años después' previous_month: 'Mes anterior' - next_month: 'Mes siguiente' + next_month: 'Próximo mes' placeholder: fecha share: topic: 'comparte un enlace a este tema' @@ -122,7 +122,7 @@ es: split_topic: "separó este tema %{when}" invited_user: "invitó a %{who} %{when}" invited_group: "invitó a %{who} %{when}" - user_left: "%{who} se ha eliminado de este mensaje %{when}" + user_left: "%{who} se eliminó a sí mismo de este mensaje %{when}" removed_user: "eliminó a %{who} %{when}" removed_group: "eliminó a %{who} %{when}" autoclosed: @@ -144,13 +144,13 @@ es: enabled: 'listado %{when}' disabled: 'quitado de la lista, invisible %{when}' banner: - enabled: 'hizo este tema un banner %{when}. Aparecerá arriba en cada página hasta que el usuario lo deje de destacar.' + enabled: 'hazlo un banner %{when}. Aparecerá arriba en cada página hasta que el usuario lo deje de destacar.' disabled: 'eliminar este banner %{when}. Ya no aparecerá en la parte superior de cada página.' topic_admin_menu: "acciones de administrador para el tema" wizard_required: "¡Bienvenido a tu nuevo Discourse! Empezaremos con el asistente de configuración ✨" emails_are_disabled: "Todos los emails salientes han sido desactivados por un administrador. No se enviará ninguna notificación por email." - bootstrap_mode_enabled: "Para facilitar el lanzamiento de tu nueva página, se ha activado el modo arranque. Todos los nuevos usuarios tendrán nivel de confianza 1 y se ha activado el email de resumen diario. Este modo se desactivará automáticamente cuando haya al menos %{min_users} usuarios registrados." - bootstrap_mode_disabled: "El modo de arranque se desactivará en las próximas 24 horas." + bootstrap_mode_enabled: "Para lanzar tu nuevo sitio más fácilmente, estás en modo Bootstrap. A todos los nuevos usuarios se les concederá el nivel 1 de confianza y recibirán resúmenes diarios por email. Esto se desactivará automáticamente cuando el número total de usuarios exceda los %{min_users}." + bootstrap_mode_disabled: "El modo Bootstrap se inhabilitará en 24 horas." themes: default_description: "Por defecto" s3: @@ -215,7 +215,7 @@ es: one: '{{count}} carácter' other: '{{count}} caracteres' suggested_topics: - title: "Temas sugeridos" + title: "Temas Sugeridos" pm_title: "Mensajes sugeridos" about: simple_title: "Acerca de" @@ -225,9 +225,11 @@ es: our_moderators: "Nuestros Moderadores" stat: all_time: "Todo el tiempo" + last_7_days: "Últimos 7" + last_30_days: "Últimos 30" like_count: "Me gusta" topic_count: "Temas" - post_count: "Mensajes" + post_count: "Posts" user_count: "Usuarios" active_user_count: "Usuarios activos" contact: "Contáctanos" @@ -236,11 +238,11 @@ es: title: "Marcador" clear_bookmarks: "Quitar Marcadores" help: - bookmark: "Haz clic para guardar en marcadores el primer mensaje de este tema" + bookmark: "Haz clic para guardar en marcadores el primer post de este tema" unbookmark: "Haz clic para quitar todos los marcadores de este tema" bookmarks: - not_logged_in: "lo sentimos, debes iniciar sesión para guardar mensajes en tus marcadores" - created: "has guardado este mensaje en marcadores" + not_logged_in: "Lo sentimos, debes iniciar sesión para guardar posts en marcadores." + created: "has guardado este post en marcadores" not_bookmarked: "has leído este post, haz clic para guardarlo en marcadores" last_read: "este es el último post que has leído; haz clic para guardarlo en marcadores" remove: "Eliminar marcador" @@ -249,7 +251,7 @@ es: one: Ver {{count}} tema nuevo o actualizado other: Ver {{count}} temas nuevos o actualizados topic_count_unread: - one: Ver {{count}} tema sin leer + one: Ver {{count}} tema sin leer other: Ver {{count}} temas sin leer topic_count_new: one: Ver {{count}} tema nuevo @@ -263,7 +265,7 @@ es: uploading: "Subiendo..." uploading_filename: "Subiendo {{filename}}..." uploaded: "¡Subido!" - pasting: "Copiando..." + pasting: "Pegando..." enable: "Activar" disable: "Desactivar" continue: "Continuar" @@ -289,18 +291,18 @@ es: none: "No hay posts para revisar." edit: "Editar" cancel: "Cancelar" - view_pending: "ver mensajes pendientes" + view_pending: "ver posts pendientes" has_pending_posts: one: Este tema tiene 1 post esperando aprobación - other: Este tema tiene {{count}} mensajes esperando aprobación + other: Este tema tiene {{count}} posts esperando aprobación confirm: "Guardar cambios" - delete_prompt: "¿Seguro que quieres eliminar a %{username}? Se eliminarán todos sus mensajes y se 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 mensaje necesita aprobación" - description: "Hemos recibido tu nuevo mensaje pero necesita ser aprobado por un moderador antes de aparecer. Por favor, ten paciencia." + 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." pending_posts: one: Tienes 1 post pendiente. - other: Tienes {{count}} mensajes pendientes. + other: Tienes {{count}} posts pendientes. ok: "OK" user_action: user_posted_topic: "{{user}} publicó el tema" @@ -332,7 +334,7 @@ es: days_visited: "Visitas" days_visited_long: "Días visitados" posts_read: "Leídos" - posts_read_long: "Mensajes leídos" + posts_read_long: "Posts leídos" total_rows: one: 1 usuario other: '%{count} usuarios' @@ -346,19 +348,19 @@ es: groups: add_members: title: "Añadir miembros" - description: "Gestionar los miembros de este grupo" - usernames: "Nombres de usuari" + description: "Administrar la membresía de éste grupo" + usernames: "Nombres de usuario" manage: title: 'Gestionar' name: 'Nombre' - full_name: 'Nombre completo' + full_name: 'Nombre Completo' add_members: "Añadir miembros" delete_member_confirm: "¿Quitar a '%{username}' del grupo '%{group}'?" profile: title: Perfil interaction: title: Interacción - posting: Publicaciones + posting: Publicar notification: Notificación membership: title: Membresía @@ -367,12 +369,12 @@ es: title: "Registros" when: "Cuándo" action: "Acción" - acting_user: "Usuario origen" + acting_user: "Usuario que actuó" target_user: "Usuario objetivo" - subject: "Sujeto" + subject: "Asunto" details: "Detalles" - from: "De" - to: "A" + from: "Desde" + to: "Para" public_admission: "Permitir a los usuarios unirse al grupo cuando quieran (Requiere que el grupo sea visible)" public_exit: "Permitir a los usuarios dejar el grupo libremente" empty: @@ -395,48 +397,47 @@ es: reason: "Permitir a los propietarios del grupo saber por qué perteneces a este grupo" membership: "Membresía" name: "Nombre" - group_name: "Nombre del grupo" + group_name: "Nombre del Grupo" user_count: "Usuarios" bio: "Acerca del grupo" - selector_placeholder: "introducir nombre de usuario" + selector_placeholder: "ingresar username" owner: "propietario" index: title: "Grupos" - all: "Todos los grupos" + all: "Todos los Grupos" empty: "No hay grupos visibles." filter: "Filtrar por tipo de grupo" - all_groups: "Todos los grupos" - owner_groups: "Grupos de los que soy dueño" - close_groups: "Grupos cerrados" - automatic_groups: "Grupos automáticos" - automatic: "Automático" - closed: "Cerrado" - public: "Público" - private: "Privado" - public_groups: "Grupos públicos" - automatic_group: Grupos automáticos - close_group: Cerrar grupo - my_groups: "Mis grupos" - group_type: "Tipo de grupo" + owner_groups: "Grupos en los que soy propietario" + close_groups: "Grupos Cerrados" + automatic_groups: "Grupos Automáticos" + automatic: "Automáticos" + closed: "Cerrados" + public: "Públicos" + private: "Privados" + public_groups: "Grupos Públicos" + automatic_group: Grupo Automático + close_group: Cerrar Grupo + my_groups: "Mis Grupos" + group_type: "Grupo tipo" is_group_user: "Miembro" - is_group_owner: "Dueño" + is_group_owner: "Propietario" title: one: Grupo other: Grupos activity: "Actividad" members: title: "Miembros" - filter_placeholder_admin: "nombre de usuario o email" - filter_placeholder: "nombre de usuario" - remove_member: "Quitar miembro" - remove_member_description: "Quitar a %{username} de este grupo" - make_owner: "Convertir en dueño" - make_owner_description: "Hacer a %{username} un dueño de este grupo" - remove_owner: "Quitar de dueño" - remove_owner_description: "Quitar a %{username} sus poderes de dueño de este grupo" - owner: "Dueño" + filter_placeholder_admin: "usuario o email" + filter_placeholder: "usuario" + remove_member: "Quitar Miembro" + remove_member_description: "Quitar %{username} de este grupo" + make_owner: "Convertir a Propietario" + make_owner_description: "Convertir a %{username} en propietario de este grupo" + remove_owner: "Quitar como Propietario" + remove_owner_description: "Quitar a %{username} como propietario de este grupo" + owner: "Propietario" topics: "Temas" - posts: "Mensajes" + posts: "Posts" mentions: "Menciones" messages: "Mensajes" notification_level: "Nivel de notificación por defecto para mensajes en grupo" @@ -451,7 +452,7 @@ es: notifications: watching: title: "Vigilando" - description: "Se te notificará de cada nuevo mensaje de esta conversación y se mostrará un contador de respuestas sin leer." + description: "Se te notificará de cada nuevo post en este mensaje y se mostrará un contador de nuevos posts." watching_first_post: title: "Vigilar Primer Post" description: "Sólo se te notificará del primer post en cada nuevo tema en este grupo." @@ -536,16 +537,16 @@ es: edit: "Editar Preferencias" download_archive: button_text: "Descargar todos" - confirm: "¿Seguro que quieres descargar tus mensajes?" + confirm: "¿Seguro que quieres descargar tus posts?" success: "Descarga iniciada, se te notificará por mensaje cuando el proceso se haya completado." - rate_limit_error: "Los mensajes pueden ser descargados una vez por día, por favor, inténtalo de nuevo mañana." + rate_limit_error: "Los posts pueden ser descargados una vez por día, por favor, inténtalo de nuevo mañana." new_private_message: "Nuevo mensaje" private_message: "Mensaje" private_messages: "Mensajes" activity_stream: "Actividad" preferences: "Preferencias" expand_profile: "Expandir" - collapse_profile: "Colapsar" + collapse_profile: "Contraer" bookmarks: "Marcadores" bio: "Acerca de mí" invited_by: "Invitado Por" @@ -553,6 +554,7 @@ es: notifications: "Notificaciones" statistics: "Estadísticas" desktop_notifications: + label: "Notificaciones en Vivo" not_supported: "Las notificaciones no están disponibles en este navegador. Lo sentimos." perm_default: "Activar notificaciones" perm_denied_btn: "Permiso denegado" @@ -560,6 +562,7 @@ es: disable: "Desactivar notificaciones" enable: "Activar notificaciones" each_browser_note: "Nota: Tendrás que cambiar esta opción para cada navegador que uses." + consent_prompt: "¿Quieres recibir notificaciones en vivo cuando alguien responde a tus mensajes?" dismiss: 'Descartar' dismiss_notifications: "Descartar todos" dismiss_notifications_tooltip: "Marcar todas las notificaciones no leídas como leídas" @@ -567,7 +570,7 @@ es: disable_jump_reply: "No dirigirme a mi post cuando responda" dynamic_favicon: "Mostrar contador de temas nuevos/actualizados en el favicon" theme_default_on_all_devices: "Hacer éste mi theme por defecto en todos mis dispositivos" - allow_private_messages: "Permitir a otros usuarios enviarme mensajes personales" + allow_private_messages: "Permitir que otros usuarios me envíen mensajes privados" external_links_in_new_tab: "Abrir todos los enlaces externos en una nueva pestaña" enable_quoting: "Activar respuesta citando el texto resaltado" change: "cambio" @@ -587,10 +590,11 @@ es: instructions: | Esta opción sobreescribe el resumen de actividad.
    Los temas y categorías silenciadas no se incluyen en estos emails. - individual: "Enviarme un email por cada nuevo mensaje" + individual: "Enviar un email por cada nuevo post" individual_no_echo: "Envíame un email por cada nuevo post excepto los publicados por mí" many_per_day: "Enviarme un email por cada nuevo post (unos {{dailyEmailEstimate}} por día)" few_per_day: "Enviarme un email por cada nuevo post (unos 2 por día)" + warning: "Modo de lista de correo habilitado. La configuración de notificación de correo electrónico está anulada." tag_settings: "Etiquetas" watched_tags: "Vigiladas" watched_tags_instructions: "Vigilarás automáticamente todos los temas con estas etiquetas. Se te notificará de todos los nuevos posts y temas y aparecerá un contador de nuevos posts al lado del tema." @@ -604,7 +608,7 @@ es: tracked_categories_instructions: "Seguirás automáticamente todos los temas en estas categorías. Aparecerá un contador de nuevos posts al lado del tema." watched_first_post_categories: "Vigilar Primer Post" watched_first_post_categories_instructions: "Se te notificará del primer post de cada nuevo tema en estas categorías." - watched_first_post_tags: "Vigilando primer post" + watched_first_post_tags: "Vigilando Primer Post" watched_first_post_tags_instructions: "Se te notificará del primer post en cada nuevo tema con estas etiquetas." muted_categories: "Silenciado" 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." @@ -612,7 +616,7 @@ es: 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." - delete_yourself_not_allowed: "Por favor, contacta a un miembro del staff si quieres que se elimine tu cuenta." + delete_yourself_not_allowed: "Por favor contactar a un miembro del staff si deseas que tu cuenta sea borrada." unread_message_count: "Mensajes" admin_delete: "Eliminar" users: "Usuarios" @@ -665,18 +669,18 @@ es: choose_new: "Escoge una nueva contraseña" choose: "Escoge una contraseña" second_factor: - title: "Verificación en dos pasos" - disable: "Verificación en dos pasos" - enable: "para mejorar la seguridad de tu cuenta" - confirm_password_description: "Por favor, confirma tu contraseña para continuar" + title: "Autenticación Dos Factores" + disable: "Inhabilitar Autenticación Dos Factores" + enable: "Hablita two factor authentication para mejorar la seguridad de la cuenta" + confirm_password_description: "Por favor confirma tu contraseña para continuar" label: "Código" enable_description: | - Escanea este código QR en una aplicación compatible (AndroidiOS – Windows Phone) e introduce el código de verificación recibido. - disable_description: "Por favor, introduce el código de verificación de tu aplicación" - show_key_description: "Introducir manualmente" + Escanee el siguiente código QR en una aplicación soportada (AndroidiOSWindows Phone) e ingresa tu código de autenticación. + disable_description: "Por favor ingrese el código de autenticación desde su aplicación" + show_key_description: "Ingrese Manualmente" extended_description: | - La verificación en dos pasos añade una capa extra de seguridad a tu cuenta haciendo que, para iniciar sesión, tengas que introducir un código de un solo uso además de tu contraseña. Los códigos se generan en aplicaciones para dispositivos móviles en Android, iOS y Windows Phone. - oauth_enabled_warning: "Ten en cuenta que se desactivarán los inicios de sesión con cuentas sociales cuando actives la verificación en dos pasos en tu cuenta." + La Autenticación de Dos Factores agrega un paso de seguridad adicional en tu cuenta al inicio de sesión al requerir un token de un solo uso además de su contraseña. Estos tokens pueden ser generados en dispositivos Android, iOS, y Windows Phone. + oauth_enabled_warning: "Por favor ten en cuenta que los accesos a través de redes sociales serán inhabilitados si habilitas el factor de autenticación en dos pasos de tu cuenta." change_about: title: "Cambiar 'Acerca de mí'" error: "Hubo un error al cambiar este valor." @@ -708,7 +712,7 @@ es: title: "Fondo de perfil" instructions: "Fondos de perfil serán centrados y tendrán un ancho por default de 850px." change_card_background: - title: "Fondo de la tarjeta de usuario" + title: "Fondo de Tarjeta de Usuario" instructions: "Imágenes de fondo serán centrados y tendrán un ancho por default de 590px." email: title: "E-mail" @@ -750,7 +754,7 @@ es: created: "Creado el" log_out: "Cerrar sesión" location: "Ubicación" - website: "Sitio web" + website: "Sitio Web" email_settings: "E-mail" like_notification_frequency: title: "Notificar cuando me dan Me gusta" @@ -803,7 +807,7 @@ es: title: "Invitaciones" user: "Invitar Usuario" sent: "Enviadas" - none: "Ninguna invitación que mostrar." + none: "Sin invitaciones para mostrar." truncated: one: Mostrando la primera invitación. other: Mostrando las primeras {{count}} invitaciones. @@ -831,7 +835,7 @@ es: days_visited: "Días Visitados" account_age_days: "Antigüedad de la cuenta en días" create: "Enviar una Invitación" - generate_link: "Copiar enlace de invitación" + generate_link: "Copiar Enlace de Invitación" link_generated: "¡Enlace de invitación generado satisfactoriamente!" valid_for: "El enlace de invitación sólo es válido para esta dirección: %{email}" bulk_invite: @@ -901,7 +905,7 @@ es: header_title: "perfil, mensajes, marcadores y preferencias" title: title: "Título" - none: "(ninguno)" + none: "(ninguna)" filters: all: "Todos" stream: @@ -919,15 +923,15 @@ es: unknown: "Error" not_found: "Página no encontrada" desc: - network: "Por favor, revisa tu conexión." + 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" - again: "Intentar de nuevo" + back: "Volver Atrás" + again: "Intentar de Nuevo" fixed: "Cargar Página" close: "Cerrar" assets_changed_confirm: "Este sitio acaba de ser actualizado justo ahora. ¿Quieres recargar la página para ver la última versión?" @@ -1001,7 +1005,7 @@ es: search_hint: 'usuario, email o dirección IP' create_account: disclaimer: "Al registrarte, aceptas la política de privacidad y los términos de servicio." - title: "Crear cuenta nueva" + title: "Crear Cuenta Nueva" failed: "Algo ha salido mal, tal vez este e-mail ya fue registrado, intenta con el enlace 'olvidé la contraseña'" forgot_password: title: "Restablecer contraseña" @@ -1018,26 +1022,26 @@ es: button_ok: "OK" button_help: "Ayuda" email_login: - link_label: "Enviar un enlace para iniciar sesión por email" - button_label: "por email" - complete_username: "Si alguna cuenta coincide con el nombre de usuario %{username} recibirá un email con un enlace para iniciar sesión en unos instantes." - complete_email: "Si coincide alguna cuenta con el email %{email} enviaremos un mensaje con un enlace para iniciar sesión en unos instantes" - complete_username_found: "Hemos encontrado una cuenta que coincide con el nombre de usuario %{username}. Recibirá un email dentro de poco con un enlace para iniciar sesión." - complete_email_found: "Hemos encontrado una cuenta que coincide con %{email}, recibirá un email con un enlace para iniciar sesión en unos instantes." - complete_username_not_found: "Ninguna cuenta coincide con el nombre de usuario %{username}" + link_label: "Enviar me un enlace para ingresar" + button_label: "con email" + complete_username: "Si una cuenta coincide con el nombre de usuario %{username}, deberías recibir un email con un enlace de ingreso muy pronto." + complete_email: "Si una cuenta coincide con %{email}, deberías recibir un email con un enlace de ingreso muy pronto." + complete_username_found: "Encontramos una cuenta que coincide con el nombre de usuario %{username}, deberías recibir un email con un enlace de ingreso muy pronto." + complete_email_found: "Encontramos una cuenta que coincide con %{email}, deberías recibir un email con un enlace de ingreso muy pronto." + complete_username_not_found: "Ninguna cuenta coincide el nombre de usuario %{username}" complete_email_not_found: "Ninguna cuenta coincide con %{email}" login: - title: "Iniciar sesión" + title: "Iniciar Sesión" username: "Usuario" password: "Contraseña" - second_factor_title: "Verificación en dos pasos" - second_factor_description: "Por favor, introduce el código de verificación de tu aplicación:" + second_factor_title: "Autenticación Dos Factores" + second_factor_description: "Por favor ingrese el código de autenticación desde su aplicación:" email_placeholder: "dirección de e-mail o nombre de usuario" caps_lock_warning: "Está activado Bloqueo de Mayúsculas" error: "Error desconocido" rate_limit: "Por favor, espera un poco antes de volver a intentar iniciar sesión." - blank_username: "Por favor, introduce tu email o nombre de usuario." - blank_username_or_password: "Por favor, introduce tu email o usuario, y tu contraseña." + blank_username: "Por favor ingresa tu email o nombre de usuario." + blank_username_or_password: "Por favor, introducir tu e-mail o usuario, y tu contraseña." reset_password: 'Restablecer Contraseña' logging_in: "Iniciando Sesión..." or: "O" @@ -1049,7 +1053,7 @@ es: not_allowed_from_ip_address: "No puedes iniciar sesión desde esa dirección IP." 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." - omniauth_disallow_totp: "Tu cuenta tiene activada la verificación en dos pasos. Por favor, inicia sesión con tu contraseña." + omniauth_disallow_totp: "Tu cuenta tiene habilitado la autenticación de dos factores. Por favor ingresa con tu contraseña." resend_title: "Volver a enviar email de activación" change_email: "Cambiar dirección de email" provide_new_email: "Poner un nuevo email, y te reenviaremos una confirmación de email." @@ -1105,16 +1109,24 @@ es: categories_only: "Sólo categorías" categories_with_featured_topics: "Categorías y temas destacados" categories_and_latest_topics: "Categorías y temas recientes" - categories_and_top_topics: "Categorías y temas top" + categories_and_top_topics: "Categorías y Temas Top" shortcut_modifier_key: shift: 'Shift' ctrl: 'Ctrl' alt: 'Alt' + conditional_loading_section: + loading: Cargando... select_kit: default_header_text: Seleccionar... no_content: Ninguna coincidencia encontrada filter_placeholder: Buscar... - create: "Crear: `{{content}}'" + create: "Crear: '{{content}}'" + max_content_reached: + one: Puedes seleccionar únicamente {{count}} item. + other: Puedes seleccionar únicamente {{count}} items. + min_content_not_reached: + one: Seleccionar al menos {{count}} item. + other: Seleccionar al menos {{count}} items. emoji_picker: filter_placeholder: Buscar emoji people: Personas @@ -1125,7 +1137,7 @@ es: objects: Objetos celebration: Celebraciones custom: Emojis personalizados - recent: Utilizados recientemente + recent: Recientemente usados default_tone: Sin tono de piel light_tone: Tono de piel claro medium_light_tone: Tono de piel medio claro @@ -1133,12 +1145,12 @@ es: medium_dark_tone: Tono de piel medio oscuro dark_tone: Tono de piel oscuro shared_drafts: - title: "Borradores compartidos" - notice: "Este tema es solo visible para los que puedan ver la categoría {{category}}." - destination_category: "Categoría de destino" - publish: "Publicar borrador compartido" - confirm_publish: "¿Seguro de que quieres publicar este borrador?" - publishing: "Publicando tema..." + title: "Borradores Compartidos" + notice: "Este tema es visible solamente por quienes pueden ver la categoría {{category}}." + destination_category: "Categoría de Destino" + publish: "Publicar Borrador Compartido" + confirm_publish: "¿Estás seguro que quieres publicar este borrador?" + publishing: "Publicando Tema..." composer: emoji: "Emoji :)" more_emoji: "más..." @@ -1155,7 +1167,7 @@ es: saved_local_draft_tip: "guardado localmente" similar_topics: "Tu tema es similar a..." drafts_offline: "borradores offline" - group_mentioned_limit: "¡Advertencia! Has mencionado {{group}}, pero este grupo tiene más miembros que el límite de menciones fijado por los administradores, que es de {{max}} usuarios. No se notificará a nadie." + group_mentioned_limit: "¡Advertencia! Has mencionado {{group}}, sin embargo este grupo tiene más miembros que el límite máximo de {{max}} usuarios configurado por el administrador para hacer menciones. Nadie será notificado. " group_mentioned: one: Al mencionar a {{group}}, estás a punto de notificar a 1 persona – ¿seguro que quieres hacerlo? other: Al mencionar a {{group}}, estás a punto de notificar a {{count}} personas – ¿seguro que quieres hacerlo? @@ -1180,8 +1192,8 @@ es: create_topic: "Crear tema" create_pm: "Mensaje" create_whisper: "Susurrar" - create_shared_draft: "Crear borrador compartido" - edit_shared_draft: "Editar borrador compartido" + create_shared_draft: "Crear Borrador Compartido" + edit_shared_draft: "Editar Borrador Compartido" title: "O pulsa Ctrl+Intro" users_placeholder: "Añadir usuario" title_placeholder: "En una frase breve, ¿de qué trata este tema?" @@ -1191,8 +1203,8 @@ es: topic_featured_link_placeholder: "Introduce el enlace mostrado con el título." remove_featured_link: "Eliminar enlace del tema." reply_placeholder: "Escribe aquí. Usa Markdown, BBCode o HTML para darle formato. Arrastra o pega imágenes." - reply_placeholder_no_images: "Escribe aquí. Usa Markdown, BBCode o HTML para dar formato." - reply_placeholder_choose_category: "Debes seleccionar una categoría antes de empezar a escribir aquí." + reply_placeholder_no_images: "Escribe aquí. Usa Markdown, BBCode, o HTML para darle formato al texto." + reply_placeholder_choose_category: "Debe seleccionar una categoría antes de escribir aquí." view_new_post: "Ver tu nuevo post." saving: "Guardando" saved: "¡Guardado!" @@ -1222,7 +1234,7 @@ es: olist_title: "Lista numerada" ulist_title: "Lista con viñetas" list_item: "Lista de ítems" - toggle_direction: "Cambiar dirección" + toggle_direction: "Alternar dirección" help: "Ayuda de Edición con Markdown" collapse: "minimizar el panel de edición" abandon: "cerrar el editor y descartar borrador" @@ -1235,25 +1247,25 @@ es: admin_options_title: "Opciones de moderación para este tema" composer_actions: reply_to_post: - label: "Responder al mensaje %{postNumber} por %{postUsername}" - desc: Responder a un mensaje específico + label: "Responder al post %{postNumber} de %{postUsername}" + desc: Responder a un post específico reply_as_new_topic: label: Responder como tema enlazado - desc: Crear un nuevo tema enlazado a este + desc: Crear un nuevo tema enlazado a este tema reply_as_private_message: label: Nuevo mensaje desc: Crear un nuevo mensaje personal reply_to_topic: label: Responder al tema - desc: "Responder al tema, sin responder a un mensaje en concreto" + desc: "Responder a este tema, no a un mensaje específico" toggle_whisper: - label: Activar/desactivar susurro - desc: Los susurros solo son visibles para miembros del staff + label: Mostrar/Ocultar Susurros + desc: Susurros son solo visibles para miembros del staff create_topic: - label: "Nuevo tema" + label: "Crear tema" shared_draft: - label: "Borrador compartido" - desc: "Empieza un borrador que solo será visible para el staff" + label: "Borrador Compartido" + desc: "Haz borrador al tema que será visible únicamente por el staff" notifications: tooltip: regular: @@ -1284,7 +1296,7 @@ es: invitee_accepted: "{{username}} ha aceptado tu invitación" moved_post: "{{username}} movió {{description}}" linked: "{{username}} {{description}}" - granted_badge: "Ganaste '{{description}}'" + granted_badge: "Ganó '{{description}}'" topic_reminder: "{{username}} {{description}}" watching_first_post: "Nuevo Tema {{description}}" group_message_summary: @@ -1296,8 +1308,10 @@ es: quoted: '{{username}} te citó en "{{topic}}" - {{site_title}}' replied: '{{username}} te respondió en "{{topic}}" - {{site_title}}' posted: '{{username}} publicó en "{{topic}}" - {{site_title}}' - private_message: '{{username}} te ha enviado un mensaje personal en "{{topic}}" - {{site_title}}' + private_message: '{{username}} le envió un mensaje personal en "{{topic}}" - {{site_title}}' linked: '{{username}} enlazó tu publicación desde "{{topic}}" - {{site_title}}' + confirm_title: 'Notificaciones habilitadas - %{site_title}' + confirm_body: '¡Éxito! Las notificaciones han sido habilitadas.' upload_selector: title: "Añadir imagen" title_with_attachments: "Añadir una imagen o archivo" @@ -1307,7 +1321,7 @@ es: 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}}" - hint: "(también puedes arrastrarlas y soltarlas en el editor para subirlas)" + 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" select_file: "Selecciona Archivo" @@ -1325,9 +1339,9 @@ es: too_short: "El término de búsqueda es demasiado corto." result_count: one: 1 resultado para{{term}} - other: {{count}}{{plus}} resultados para{{term}} + other: {{count}}{{plus}} resultados para {{term}} title: "buscar temas, posts, usuarios o categorías" - full_page_title: "busca temas o mensajes" + full_page_title: "buscar temas o posts" no_results: "No se ha encontrado ningún resultado." no_more_results: "No se encontraron más resultados." searching: "Buscando ..." @@ -1359,6 +1373,7 @@ es: label: Etiquetado filters: label: Sólo devolver temas/mensajes... + title: Coincide el título únicamente likes: Me han gustado posted: He publicado en ellos watching: Estoy vigilando @@ -1434,7 +1449,7 @@ es: top: "No hay temas en el top más vistos." search: "No hay resultados de búsqueda." educate: - new: '

    Tus temas nuevos aparecen aquí.

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

    Dirígite a tus preferencias para cambiar esto.

    ' + 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." @@ -1453,7 +1468,7 @@ es: other: '{{count}} posts en el tema' create: 'Crear tema' create_long: 'Crear un nuevo tema' - open_draft: "Abrir borrador" + open_draft: "Abrir Borrador" private_message: 'Empezar un mensaje' archive_message: help: 'Archivar mensaje' @@ -1462,8 +1477,8 @@ es: title: 'Mover a la bandeja de entrada' help: 'Restaurar mensaje a la bandeja de entrada' edit_message: - help: 'Editar el primer mensaje' - title: 'Editar mensaje' + help: 'Editar el primer post del mensaje' + title: 'Editar Mensaje' list: 'Temas' new: 'nuevo tema' unread: 'sin leer' @@ -1511,7 +1526,7 @@ es: deleted: "El tema ha sido borrado" topic_status_update: title: "Temporizador de Temas" - save: "Configurar temporizador" + save: "Configurar Temporizador" num_of_hours: "Número de horas:" remove: "Quitar Temporizador" publish_to: "Publicar el:" @@ -1587,10 +1602,10 @@ es: "3_2": 'Recibirás notificaciones porque estás vigilando este tema.' "3_1": 'Recibirás notificaciones porque creaste este tema.' "3": 'Recibirás notificaciones porque estás vigilando este tema.' - "2_8": 'Verás la cuenta de nuevas respuestas porque estás siguiendo esta categoría.' - "2_4": 'Verás la cuenta de nuevas respuestas porque has publicado una respuesta en este tema.' - "2_2": 'Verás la cuenta de nuevas respuestas porque estás siguiendo este tema.' - "2": 'Verás la cuenta de nuevas respuestas porque has leído este tema.' + "2_8": 'Tú verás la cuenta de nuevas respuestas porque estás siguiendo esta categoría.' + "2_4": 'Tú verás la cuenta de nuevas respuestas porque has publicado una respuesta en este tema.' + "2_2": 'Tú verás la cuenta de nuevas respuestas porque estás siguiendo este tema.' + "2": 'Tú verás la cuenta de nuevas respuestas porque has leído este tema.' "1_2": 'Se te notificará solo si alguien menciona tu @nombre o te responde a un post.' "1": 'Se te notificará si alguien menciona tu @nombre o te responde a un post.' "0_7": 'Estás ignorando todas las notificaciones en esta categoría.' @@ -1626,16 +1641,16 @@ es: open: "Abrir tema" close: "Cerrar tema" multi_select: "Seleccionar posts..." - timed_update: "Configurar temporizador de temas..." + timed_update: "Configurar Temporizador de temas..." pin: "Destacar tema..." unpin: "Dejar de destacar..." - unarchive: "Desarchivar tema" - archive: "Archivar tema" + unarchive: "Desarchivar Tema" + archive: "Archivar Tema" invisible: "Hacer invisible" visible: "Hacer visible" reset_read: "Restablecer datos de lectura" make_public: "Convertir en tema público" - make_private: "Redactar mensaje personal" + make_private: "Crear Mensaje Personal" feature: pin: "Destacar tema" unpin: "Dejar de destacar tema" @@ -1746,27 +1761,28 @@ es: instructions: one: Por favor escoge el nuevo dueño del {{count}} post de {{old_user}}. other: Por favor escoge el nuevo dueño de los {{count}} posts de {{old_user}}. + instructions_warn: "Tenga en cuenta que cualquier notificación sobre esta publicación no se transferirá al nuevo usuario de forma retroactiva." change_timestamp: - title: "Cambiar fecha..." - action: "cambiar fecha" - invalid_timestamp: "La fecha no puede ser futura" - error: "Ha ocurrido un error al cambiar la fecha de este tema." - instructions: "Por favor, selecciona una nueva fecha para el tema. Los mensajes en el tema serán actualizados para mantener la diferencia de tiempo." + title: "Cambiar Timestamp..." + action: "cambiar timestamp" + invalid_timestamp: "El Timestamp no puede ser futuro" + error: "Hubo un error cambiando el timestamp de este tema." + instructions: "Por favor, señecciona el nuevo timestamp del tema. Los posts en el tema serán actualizados para mantener la diferencia de tiempo." multi_select: select: 'seleccionar' selected: 'seleccionado ({{count}})' select_post: label: 'seleccionar' - title: 'Añadir mensaje a la selección' + title: 'Agregar post a la selección' selected_post: label: 'seleccionado' - title: 'Haz clic para quitar el mensaje de la selección' + title: 'Clic para eliminar post de la selección' select_replies: - label: 'seleccionar +respuestas' - title: 'Añadir mensaje y todas sus respuestas a la selección' + label: 'seleccionar más respuestas' + title: 'Agregar post y todas sus respuestas a la selección' select_below: - label: 'Seleccionar +abajo' - title: 'Añdir mensaje y todos los de debajo a la selección' + label: 'seleccionar +debajo' + title: 'Agregar post y todo despues del mismo a la selección' delete: eliminar seleccionado cancel: cancelar selección select_all: seleccionar todo @@ -1776,7 +1792,7 @@ es: other: Has seleccionado {{count}} posts. post: quote_reply: "Citar" - edit: "{{link}} {{replyAvatar}} {{username}} " + edit: " {{link}} {{replyAvatar}} {{username}}" edit_reason: "Motivo:" post_number: "post {{number}}" wiki_last_edited_on: "wiki editada por última vez" @@ -1790,9 +1806,9 @@ es: deleted_by_author: one: (post retirado por el autor. Será borrado automáticamente en %{count} hora si no es reportado) other: (post retirado por el autor. Será borrado automáticamente en %{count} horas si no es reportado) - collapse: "colapsar" + collapse: "contraer" expand_collapse: "expandir/contraer" - locked: "un miembro del staff ha bloqueado este mensaje y no se puede editar" + locked: "un miembro del personal ha bloqueado esta publicación para que no se edite" gap: one: ver 1 post oculto other: ver {{count}} posts ocultos @@ -1847,14 +1863,14 @@ es: share: "comparte un enlace a este post" more: "Más" delete_replies: - confirm: "¿También quieres borrar las respuestas a este mensaje?" + confirm: "¿Quieres eliminar también las respuestas a este post?" direct_replies: - one: Sí, y 1 respuesta direct - other: Sí, y {{count}} respuestas directas + one: Si, y 1 respuesta directa + other: Si, y {{count}} respuestas directas all_replies: one: Sí, y 1 respuesta - other: Sí, y {{count}} respuestas - just_the_post: "No, solo este mensaje" + other: Sí, y todas las {{count}} respuestas + just_the_post: "No, solo este post" admin: "acciones de administrador para el post" wiki: "Formato wiki" unwiki: "Deshacer formato wiki" @@ -1863,11 +1879,11 @@ es: rebake: "Reconstruir HTML" unhide: "Deshacer ocultar" change_owner: "Cambiar dueño" - grant_badge: "Conceder distintivo" - lock_post: "Bloquear mensaje" - lock_post_description: "evitar que el autor edite este mensaje" - unlock_post: "Desbloquear mensaje" - unlock_post_description: "permitir al autor editar este mensaje" + grant_badge: "Condecer distintivo" + lock_post: "Bloquear Post" + lock_post_description: "evitar que el usuario que publicó edite esta publicación" + unlock_post: "Desbloquear Post" + unlock_post_description: "permitir al usuario que publicó, editar este post" actions: flag: 'Reportar' defer_flags: @@ -1953,8 +1969,8 @@ es: other: '{{count}} personas votaron este post' delete: confirm: - one: ¿Seguro que quieres borrar 1 mensaje? - other: ¿Seguro que quieres borrar {{count}} mensajes? + one: ¿Estás seguro que quieres eliminar ese post? + other: ¿Estás seguro que quieres eliminar esos {{count}} posts? merge: confirm: one: Seguro que quieres unir esos posts? @@ -2040,8 +2056,8 @@ es: email_in_allow_strangers: "Aceptar emails de usuarios anónimos sin cuenta" email_in_disabled: "La posibilidad de publicar nuevos temas por email está deshabilitada en los ajustes del sitio. Para habilitar la publicación de nuevos temas por email," email_in_disabled_click: 'activa la opción "email in".' - mailinglist_mirror: "La categoría refleja una lista de correo" - suppress_from_latest: "Ocultar categoría de los temas recientes." + mailinglist_mirror: "Categoría refleja una lista de correo" + suppress_from_latest: "Ocultar la categoría de los últimos temas." show_subcategory_list: "Mostrar la lista de subcategorías arriba de la lista de temas en esta categoría." num_featured_topics: "Número de temas a mostrar en la página de categorías:" subcategory_num_featured_topics: "Número de temas destacados a mostrar en la página superior de categorías:" @@ -2312,8 +2328,8 @@ es: dismiss_topics: 'x, t Descartar temas' log_out: 'shift+z shift+z Cerrar sesión' composing: - title: 'Editor' - return: 'shift+c Volver al editor' + title: 'Redactando' + return: 'shift+c Regresar al editor' actions: title: 'Acciones' bookmark_topic: 'f Guardar/Quitar el tema de marcadores' @@ -2353,8 +2369,8 @@ es: one: 1 concedido other: '%{count} concedidos' select_badge_for_title: Seleccionar una distinción para utilizar como tu título - none: "(ninguno)" - successfully_granted: "%{badge} otorgada con éxito a %{username}" + none: "(ninguna)" + successfully_granted: "Concedido exitosamente %{badge} a %{username}" badge_grouping: getting_started: name: Primeros pasos @@ -2377,12 +2393,12 @@ es:

    tagging: all_tags: "Etiquetas" - other_tags: "Otras etiquetas" + other_tags: "Otras Etiquetas" selector_all_tags: "etiquetas" selector_no_tags: "sin etiquetas" changed: "etiquetas cambiadas:" tags: "Etiquetas" - choose_for_topic: "etiquetas (opcional)" + choose_for_topic: "etiquetas opcionales" delete_tag: "Eliminar etiqueta" delete_confirm: one: ¿Estás seguro de querer borrar esta etiqueta y eliminarla de 1 tema asignado? @@ -2403,19 +2419,19 @@ es: notifications: watching: title: "Vigilar" - description: "Vigilarás automáticamente todos los temas con esta etiqueta. Se te notificará de cada nuevo tema y mensaje, y, además, el contador de mensajes nuevos sin leer aparecerá junto al tema." + description: "Vigilarás automáticamente todos los temas en esta etiqueta. Se te notificará de todos los nuevos temas y posts, y además aparecerá el contador de posts sin leer y nuevos posts al lado del tema." watching_first_post: title: "Vigilar Primer Post" - description: "Solo se te notificará de cada primer mensaje por nuevo tema con esta etiqueta." + description: "Se te notificará únicamente en el primer post de cada nuevo tema con esta etiqueta." tracking: title: "Seguir" - description: "Seguirás automáticamente todos los temas con esta etiqueta. Un contador de nuevos mensajes aparecerá junto a los temas." + description: "Seguirás automáticamente todos los temas con esta etiqueta. Aparecerá un contador de posts sin leer y nuevos posts al lado del tema." regular: title: "Normal" description: "Se te notificará solo si alguien te menciona con tu @usuario o responde a algún post tuyo." muted: title: "Silenciado" - description: "No se te notificará de nada relacionado con nuevos temas con esta etiqueta, y no aparecerán en tu pestaña de sin leer" + description: "No se te notificará de nuevos temas con esta etiqueta, ni aparecerán en tu pestaña de temas no leídos." groups: title: "Grupos de etiquetas" about: "Agregar etiquetas en grupos para administrarlas más fácilmente." @@ -2429,9 +2445,9 @@ es: save: "Guardar" delete: "Eliminar" confirm_delete: "¿Seguro que quieres eliminar este grupo de etiquetas?" - everyone_can_use: "Las etiquetas pueden ser usadas por cualquiera" - usable_only_by_staff: "Las etiquetas son visibles para todo el mundo, pero solo el staff las puede utilizar" - visible_only_to_staff: "Etiquetas solo visibles para staff" + everyone_can_use: "Etiquetas pueden ser usadas por cualquiera" + usable_only_by_staff: "Etiquetas son visibles para todos, pero solo el staff puede usarlas" + visible_only_to_staff: "Etiquetas son visibles únicamente para el staff" topics: none: unread: "No hay temas que sigas y que no hayas leído ya." @@ -2454,12 +2470,12 @@ es: bookmarks: "No hay más temas guardados en marcadores." search: "No hay más resultados de búsqueda." invite: - custom_message: "Dale a tu invitación un toque personal escribiendo un" + custom_message: "Darle a tu invitación un toque personal escribiendo un" custom_message_link: "mensaje personalizado" custom_message_placeholder: "Introducir un mensaje personalizado" custom_message_template_forum: "Hey, ¡quizá deberías unirte a este foro!" custom_message_template_topic: "¡Hey, he pensado que este tema te va a encantar!" - forced_anonymous: "Debido a una carga extrema en el servidor, esto se está mostrando temporalmente a todo el mundo como una persona sin iniciar sesión lo vería." + forced_anonymous: "Debido a la carga extrema, esto se muestra temporalmente a todos, ya que un usuario desconectado lo vería." safe_mode: enabled: "El modo seguro está activado, para salir del modo seguro cierra esta ventana del navegador" admin_js: @@ -2470,6 +2486,8 @@ es: dashboard: title: "Panel" last_updated: "Panel actualizado el:" + find_old: "¿Buscando el antiguo dashboard?" + old_link: "lo visitas aquí" version: "Versión" up_to_date: "¡Estás al día!" critical_available: "Actualización crítica disponible." @@ -2494,17 +2512,21 @@ es: space_free: "{{size}} libre" uploads: "subidas" backups: "backups" - lastest_backup: "Última: %{date}" + lastest_backup: "Recientes: %{date}" traffic_short: "Tráfico" traffic: "Peticiones web de la app" page_views: "Páginas vistas" page_views_short: "Páginas vistas" show_traffic_report: "Mostrar informe detallado del tráfico" - community_health: Salud de la comunidad - whats_new_in_discourse: "¿Qué hay nuevo en Discourse?" + community_health: Salud de la Comunidad + whats_new_in_discourse: "¿Qué hay de nuevo en Discourse?" + activity_metrics: Métricas de Actividad reports: + trend_title: "%{percent} de cambio. Actualmente %{current}, era %{prev} en el periodo previo." today: "Hoy" yesterday: "Ayer" + last_7_days: "Últimos 7" + last_30_days: "Últimos 30" all_time: "Todo el tiempo" 7_days_ago: "Hace 7 días" 30_days_ago: "Hace 30 días" @@ -2515,6 +2537,10 @@ es: start_date: "Desde fecha" end_date: "Hasta fecha" groups: "Todos los grupos" + disabled: "Este reporte está inhabilitado" + trending_search: + more: 'Buscar logs' + disabled: 'El reporte de Tendencias de Búsquedas está inhabilitado. Habilita el log consultas de búsquedas para colectar datos.' commits: latest_changes: "Cambios recientes: ¡actualiza a menudo!" by: "por" @@ -2523,21 +2549,21 @@ es: active_posts: "Posts Reportados" old_posts: "Post reportados antiguos" topics: "Temas Reportados" - moderation_history: "Registro de moderación" + moderation_history: "Historia de Moderación" agree: "De acuerdo" agree_title: "Confirmar esta indicación como válido y correcto." - agree_flag_hide_post: "Ocultar mensaje" + agree_flag_hide_post: "Esconder Post" agree_flag_hide_post_title: "Ocultar este post y enviar automáticamente un mensaje al usuario para que lo edite de forma urgente" agree_flag_restore_post: "Coincidir y Restaurar Mensaje" agree_flag_restore_post_title: "Restaurar el post para que todos los usuarios puedan verlo." - agree_flag_suspend: "Suspender usuario" - agree_flag_suspend_title: "Coincidir con el reporte y suspender al usuario." - agree_flag_silence: "Silenciar usuario" - agree_flag_silence_title: "Coincidir con el reporte y silenciar al usuario." - agree_flag: "Mantener mensaje" + agree_flag_suspend: "Suspender Usuario" + agree_flag_suspend_title: "Estar de acuerdo con el reporte y suspender el usuario." + agree_flag_silence: "Silenciar Usuario" + agree_flag_silence_title: "Estar de acuerdo con el reporte y silenciar el usuario." + agree_flag: "Mantener Post" agree_flag_title: "Estar de acuerdo con el reporte y mantener la publicación intacta." ignore_flag: "Ignorar" - ignore_flag_title: "Quitar este reporte; no requiere tomar medidas en este momento." + ignore_flag_title: "Eliminar este reporte; no requiere ninguna acción en este momento." delete: "Eliminar" delete_title: "Eliminar el post referido por este indicador." delete_post_defer_flag: "Eliminar post e ignorar reporte" @@ -2560,7 +2586,7 @@ es: one: '[1 respuesta]' other: '[%{count} respuestas]' delete_replies: - one: ¿También borrar la respuesta a este post? + one: ¿También borrar %{count} respuesta a este post? other: ¿También borrar las %{count} respuestas a este post? dispositions: agreed: "coincidió" @@ -2585,6 +2611,7 @@ es: type: "Tipo" users: "Usuarios" last_flagged: "Último reporte" + no_results: "No hay temas reportados." short_names: off_topic: "off-topic" inappropriate: "inapropiado" @@ -2593,42 +2620,42 @@ es: notify_moderators: "personalizado" groups: new: - title: "Nuevo grupo" + title: "Grupo Nuevo" create: "Crear" name: - too_short: "El nombre del grupo es muy corto" - too_long: "El nombre del grupo es muy largo" - checking: "Comprobando disponibilidad del nombre del grupo..." - available: "El nombre del grupo está disponible" - not_available: "El nombre del grupo no está disponible" - blank: "El nombre del grupo no puede estar vacío" + too_short: "Nombre del grupo es muy corto" + too_long: "Nombre del grupo es muy largo" + checking: "Verificando disponibilidad del nombre del grupo..." + available: "Nombre del grupo está disponible" + not_available: "Nombre del grupo no está disponible" + blank: "Nombre del grupo no puede estar vacío" bulk_add: - title: "Añadir en masa al grupo" - complete_users_not_added: "Los siguientes usuarios no han sido añadidos (asegúrate de que tengan cuenta):" + title: "Añadir al grupo en masa" + complete_users_not_added: "Estos usuarios no fueron agregados (asegurar que ellos tengan una cuenta):" paste: "Pega una lista de nombres de usuario o emails, uno por línea:" add_members: - as_owner: "Establecer usuario(s) como dueño(s) de este grupo" + as_owner: "Convertir usuario(s) como propietario(s) de este grupo" manage: interaction: email: Email - incoming_email: "Dirección de email entrante personalizada" - incoming_email_placeholder: "introduce un email" + incoming_email: "Emails entrantes personalizados" + incoming_email_placeholder: "introducir dirección de email" visibility: Visibilidad visibility_levels: title: "¿Quién puede ver este grupo?" - public: "Todo el mundo" - members: "Dueños del grupo, miembros y administradores" - staff: "Dueños del grupo y staff" - owners: "Dueños del grupo y administradores" + public: "Todos" + members: "Propietarios del grupo, miembros y administradores" + staff: "Propietarios del grupo, y staff" + owners: "Propietarios del grupo y administradores" membership: automatic: Automático - trust_level: Nivel de confianza - trust_levels_title: "Nivel de confianza asignado automáticamente a los miembros cuando son añadidos:" + trust_level: Nivel de Confianza + trust_levels_title: "Nivel de confianza entregado automáticamente a miembros cuando son añadidos:" trust_levels_none: "Ninguno" - automatic_membership_email_domains: "Los usuarios que se registren con un email cuyo dominio coincida exactamente con uno en esta lista serán añadidos automáticamente a este grupo:" - automatic_membership_retroactive: "Aplicar la misma regla de dominios de email para añadir usuarios ya registrados" - primary_group: "Establecer como grupo primario automáticamente" - name_placeholder: "Nombre del grupo, sin espacios, mismos requisitos que los nombres de usuario" + 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 " + primary_group: "Establecer automáticamente como grupo principal" + name_placeholder: "Nombre del grupo, sin espacios, igual que los nombres de usuarios" primary: "Grupo principal" no_primary: "(ningún grupo principal)" title: "Grupos" @@ -2644,7 +2671,7 @@ es: custom: "Personalizado" automatic: "Automático" default_title: "Título por defecto" - default_title_description: "se aplicará a todos los usuarios en el grupo" + default_title_description: "será aplicado a todos los usuarios en el grupo" group_owners: Propietarios add_owners: Añadir propietarios none_selected: "Selecciona un grupo para empezar" @@ -2703,16 +2730,19 @@ es: details: "Cuando se publique, edite, elimine o recupere una respuesta." user_event: name: "Evento de usuario" - details: "Cuando un usuario inicia sesión, la cierra o es creado, aprobado o actualizado." + details: "Cuando un usuario ingresa, sale, es creado, aprobado o actualizado." group_event: - name: "Evento de grupo" - details: "Cuando se cree, actualice o borre un grupo." + name: "Evento de Grupo" + details: "Cuando un grupo es creado, actualizado o destruido." category_event: - name: "Evento de categoría" - details: "Cuando se cree, actualice o borre una categoría." + name: "Evento de Categoría" + details: "Cuando una categoría es creada, actualizada o destruida." tag_event: - name: "Evento de etiqueta" - details: "Cuando se cree, edite o borre una etiqueta." + name: "Evento de Etiqueta" + details: "Cuando una etiqueta es creada, actualizada o destruida." + flag_event: + name: "Reportar Evento" + details: "Cuando un reporte es creado, de acuerdo, en desacuerdo, o ignorado." delivery_status: title: "Estado de entrega" inactive: "Inactivo" @@ -2754,7 +2784,7 @@ es: change_settings: "Cambiar preferencias" change_settings_short: "Ajustes" howto: "¿Cómo instalo plugins?" - official: "Plugin oficial" + official: "Plugin Oficial" backups: title: "Copia de seguridad" menu: @@ -2778,7 +2808,7 @@ es: label: "Subir" title: "Subir un backup a esta instancia" uploading: "Subiendo..." - success: "'{{filename}}' subido con éxito. El archivo está siendo ahora procesado y tardará hasta un minuto en aparecer en la lista." + success: "'{{filename}}' ha sido exitosamente subido. El archivo se procesará ahora y tomará hasta un minuto para ser mostrado en la lista." error: "Ha ocurrido un error al subir el archivo '{{filename}}': {{message}}" operations: is_running: "Actualmente una operación se está procesando..." @@ -2873,7 +2903,11 @@ es: add_upload: "Agregar Subido" upload_file_tip: "Selecciona un archivo a subir (png, woff2, etc...)" variable_name: "Nombre de variable SCSS:" - variable_name_invalid: "Nombre de variable no válido. Solo se permiten caracteres alfanuméricos. Debe empezar con una letra y ser único." + variable_name_invalid: "Nombre de variable inválido. Alfanuméricos permitidos únicamente. Debe comenzar con una letra. Debe ser único." + variable_name_error: + invalid_syntax: "Nombre de variable inválido. Sólo alfanuméricos permitidos. Debe comenzar con una letra." + no_overwrite: "Nombre de variable inválido. No debe sobrescribir una variable existente. " + must_be_unique: "Nombre de variable inválido. Debe ser único." upload: "Subir" child_themes_check: "Theme incluye otros themes hijos" css_html: "Personalizar CSS/HTML" @@ -2882,8 +2916,8 @@ es: delete_upload_confirm: "Borrar este upload? (El theme CSS puede dejar de funcionar!)" import_web_tip: "Repositorio que contiene el theme" import_file_tip: "archivo .dcstyle.json que contiene el theme" - is_private: "El tema está en un repositorio git privado" - public_key: "Permite el acceso al repositorio a la siguiente clave pública:" + is_private: "El theme está en un repositorio privado de git" + public_key: "Conceda la siguiente clave pública de acceso para el repositorio:" about_theme: "Acerca del Theme" license: "Licencia" component_of: "Theme es un componente de:" @@ -2892,8 +2926,8 @@ es: updating: "Actualizando..." up_to_date: "Theme actualizado, última verificación:" add: "Agregar" - theme_settings: "Ajustes del tema" - no_settings: "Este tema no tiene ajustes" + theme_settings: "Ajustes del Theme" + no_settings: "Este theme no tiene ajustes." commits_behind: one: Theme está 1 commit detrás! other: Theme está {{count}} commits detrás! @@ -2920,7 +2954,7 @@ es: title: "HTML que será insertado antes del tag " yaml: text: "YAML" - title: "Definir ajustes de tema en formato YAML" + title: "Definir ajustes al theme en formato YAML" colors: select_base: title: "Selecciona esquema base de color" @@ -3031,13 +3065,13 @@ es: skipped_reason_placeholder: "motivo" moderation_history: performed_by: "Realizado por" - no_results: "Registro de moderación no disponible." + no_results: "No hay historia de moderación disponible." actions: - delete_user: "Usuario eliminado" - suspend_user: "Usuario suspendido" - silence_user: "Usuario silenciado" - delete_post: "Post eliminado" - delete_topic: "Tema eliminado" + delete_user: "Usuario Borrado" + suspend_user: "Usuario Suspendido" + silence_user: "Usuario Silenciado" + delete_post: "Post Borrado" + delete_topic: "Tema Borrado" logs: title: "Logs" action: "Acción" @@ -3082,11 +3116,13 @@ es: change_site_text: "cambiar textos" suspend_user: "suspender usuario" unsuspend_user: "desbloquear usuario" + removed_suspend_user: "suspender usuario (eliminado)" + removed_unsuspend_user: "no-suspender usuario (eliminado)" grant_badge: "conceder distintivo" revoke_badge: "revocar distintivo" check_email: "comprobar e-mail" delete_topic: "eliminar tema" - recover_topic: "restaurar tema" + recover_topic: "recuperar tema" delete_post: "eliminar post" impersonate: "impersonar" anonymize_user: "anonimizar usuario" @@ -3096,6 +3132,8 @@ es: create_category: "crear categoría" silence_user: "silenciar usuario" unsilence_user: "no-silenciar usuario" + removed_silence_user: "silenciar usuario (eliminado)" + removed_unsilence_user: "no-silenciar usuario (eliminado)" grant_admin: "conceder administración" revoke_admin: "revocar administración" grant_moderation: "conceder moderación" @@ -3113,13 +3151,16 @@ es: backup_destroy: "destruir copia de seguridad" reviewed_post: "posts revisados" custom_staff: "acción personalizada por plugin" - post_locked: "mensaje bloqueado" - post_edit: "edición de mensaje" - post_unlocked: "mensaje desbloqueado" - check_personal_message: "comprobar mensaje personal" - disabled_second_factor: "desactivación de Verificación en dos pasos" - topic_published: "tema despublicado" + post_locked: "post bloqueado" + post_edit: "editar post" + post_unlocked: "post desbloqueado" + check_personal_message: "revisar mensaje personal" + disabled_second_factor: "inhabilitar Autenticación Dos Factores" + topic_published: "tema publicado" post_approved: "post aprobado" + create_badge: "crear distintivo" + change_badge: "cambiar distintivo" + delete_badge: "borrar distintivo" 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." @@ -3151,17 +3192,17 @@ es: text: "Agrupar" title: "Crea un nuevo rango de entradas para banear si hay al menos 'min_ban_entries_for_roll_up' entradas." search_logs: - title: "Logs de búsqueda" + title: "Buscar Logs" term: "Término" searches: "Búsquedas" - click_through: "Click Through" + click_through: "A través del clic" unique: "Único" unique_title: "usuarios únicos realizando la búsqueda" types: all_search_types: "Todos los tipos de búsqueda" header: "Encabezado" full_page: "Página Completa" - click_through_only: "Todo (solo entrados)" + click_through_only: "Todo (a través del clic únicamente)" header_search_results: "Resultados de búsqueda de encabezado" logster: title: "Registros de errores" @@ -3189,6 +3230,7 @@ es: placeholder_regexp: "regular expression" add: 'Agregar' success: 'Terminado' + exists: 'Ya existe' upload: "Subir" upload_successful: "Subida completada. Las palabras han sido agregadas." impersonate: @@ -3212,6 +3254,7 @@ es: suspended: 'Suspendidos' silenced: 'Silenciado' suspect: 'Sospechoso' + staged: 'Temporal' approved: "Aprobado/s?" approved_selected: one: aprobar usuario @@ -3234,6 +3277,7 @@ es: silenced: 'Usuarios Silenciados' suspended: 'Usuarios suspendidos' suspect: 'Usuarios sospechados' + staged: 'Usuarios Temporales' reject_successful: one: 1 usuario rechazado con éxito. other: '%{count} usuarios rechazados con éxito.' @@ -3266,10 +3310,14 @@ es: suspended_until: "(hasta %{until})" cant_suspend: "Este usuario no puede ser suspendido." delete_all_posts: "Eliminar todos los posts" - penalty_post_actions: "¿Qué te gustaría hacer con el mensaje asociado?" - penalty_post_delete: "Eliminar el mensaje" - penalty_post_edit: "Editar el mensaje" - penalty_post_none: "No hacer nada" + penalty_post_actions: "¿Qué te gustaría hacer con la publicación asociada?" + penalty_post_delete: "Borrar el post" + penalty_post_edit: "Editar el post" + penalty_post_none: "Nada" + penalty_count: "Contador de Faltas" + clear_penalty_history: + title: "Borrar Historial de Faltas" + description: "usuarios con faltas no pueden alcanzar NC3" delete_all_posts_confirm_MF: "Estás a punto de eliminar {POSTS, plural, one {1 post} other {# posts}} y {TOPICS, plural, one {1 topic} other {# topics}}. ¿Seguro?" silence: "Silenciar" unsilence: "No silenciar" @@ -3294,8 +3342,8 @@ es: grant_moderation: 'Conceder moderación' unsuspend: 'Quitar suspensión' suspend: 'Suspender' - show_flags_received: "Mostrar reportes recibidos" - flags_received_by: "Reportes recibidos por %{username}" + show_flags_received: "Mostrar Reportes Recibidos" + flags_received_by: "Reportes Recibidos por %{username}" flags_received_none: "Este usuario no ha recibido ningún reporte." reputation: Reputación permissions: Permisos @@ -3305,7 +3353,7 @@ es: private_topics_count: Temas privados posts_read_count: Posts leídos post_count: Posts publicados - second_factor_enabled: Verificación en dos pasos activada + second_factor_enabled: Autenticación de Dos Factores Habilitada topics_entered: Temas vistos flags_given_count: Reportes enviados flags_received_count: Reportes recibidos @@ -3335,6 +3383,7 @@ es: delete_confirm: "Estás SEGURO que quieres borrar este usuario? Esta acción es permanente!" delete_and_block: "Eliminar y bloquear este correo y esta dirección IP" delete_dont_block: "Eliminar solo." + deleting_user: "Eliminando usuario..." deleted: "El usuario fue borrado." delete_failed: "Ha habido un error al borrar ese usuario. Asegúrate que todos las publicaciones han sido borrados antes de tratando de borrar este usuario." send_activation_email: "Enviar correo de activación" @@ -3389,8 +3438,8 @@ es: likes_received: "Likes recibidos" likes_received_days: "'Me gusta' Recibidos: días únicos" likes_received_users: "'Me gusta' Recibidos: usuarios únicos." - suspended: "Suspendido (siempre)" - silenced: "Silenciado (siempre)" + suspended: "Suspendidos (todo el tiempo)" + silenced: "Silenciados (todo el tiempo)" qualifies: "Califica para el nivel de confianza 3." does_not_qualify: "No califica para el nivel de confianza 3." will_be_promoted: "Será promovido pronto." @@ -3450,12 +3499,13 @@ es: recommended: "Recomendamos personalizar los siguientes textos para que se ajusten a tus necesidades:" show_overriden: 'Sólo mostrar textos editados' settings: - show_overriden: 'Solo mostrar lo editado' - reset: 'resetear' - none: 'ninguno' + show_overriden: 'Solo mostrar anulados' + reset: 'restablecer' + none: 'ninguna' site_settings: title: 'Ajustes del sitio' no_results: "Ningún resultado encontrado" + more_than_30_results: "Hay más de 30 resultados. Por favor, refina tu búsqueda o selecciona una categoría." clear_filter: "Limpiar filtro" add_url: "añadir URL" add_host: "añadir host" @@ -3522,7 +3572,8 @@ es: enabled: Activar distintivo icon: Icono image: Imagen - icon_help: "Usa ya sea una clase Font Awesome o una URL a la imagen" + icon_help: "Usa una clase de Font Awesome" + image_help: "Ingrese la URL de la imagen (anula el campo del icono si ambos están configurados)" query: Consulta (SQL) para otorgar el distintivo target_posts: La consulta tiene como objetivo posts auto_revoke: Ejecutar diariamente la consulta de revocación diff --git a/config/locales/client.et.yml b/config/locales/client.et.yml index 94b16f3f1a..43241f1897 100644 --- a/config/locales/client.et.yml +++ b/config/locales/client.et.yml @@ -2400,7 +2400,6 @@ et: label: "Varukoopia" title: "Loo varukoopia" confirm: "Kas Sa soovid alustada uut varukoopiat?" - without_uploads: "Jah (ära kaasa faile)" download: label: "Lae alla" destroy: @@ -3024,7 +3023,6 @@ et: enabled: Luba märgis icon: Ikoon image: Pilt - icon_help: "Kasuta kas Font Awesome klassi või URL-viidet pildile" query: Märgise päring (SQL) target_posts: Päri sihtmärkide postitusi auto_revoke: Jooksuta tühistamispäringut igapäevaselt diff --git a/config/locales/client.fa_IR.yml b/config/locales/client.fa_IR.yml index 26f9e9e30a..de01c65607 100644 --- a/config/locales/client.fa_IR.yml +++ b/config/locales/client.fa_IR.yml @@ -2407,7 +2407,6 @@ fa_IR: label: "پشتیبان گیری" title: "ساخت یک پشتیبان" confirm: "آیا می خواهید یک پشیبان گیری جدید را آغاز نمایید ؟" - without_uploads: "بله (فایل ها را شامل نمی شود)" download: label: "دانلود" title: "ارسال ایمیل با لینک دانلود" @@ -3027,7 +3026,6 @@ fa_IR: enabled: فعالسازی نشان icon: آیکن image: تصویر - icon_help: "استفاده از یک کلاس Font Awesome یا URL به یک تصویر" query: پرس جوی نشان (SQL) target_posts: پرس‌و‌جوی نوشته‌های هدف auto_revoke: اجرای روزانه پروس‌و‌جوی لغو diff --git a/config/locales/client.fi.yml b/config/locales/client.fi.yml index d78aacf4b7..93afc7b6cc 100644 --- a/config/locales/client.fi.yml +++ b/config/locales/client.fi.yml @@ -225,6 +225,8 @@ fi: our_moderators: "Valvojat" stat: all_time: "Yhteensä" + last_7_days: "Viimeiset 7" + last_30_days: "Viimeiset 30" like_count: "Tykkäyksiä" topic_count: "Ketjuja" post_count: "Viestejä" @@ -400,7 +402,6 @@ fi: all: "Kaikki ryhmät" empty: "Näkyvillä olevia ryhmiä ei ole." filter: "Suodata ryhmän tyypin mukaan" - all_groups: "Kaikki ryhmät" owner_groups: "Ryhmät joiden isäntä olen" close_groups: "Suljetut ryhmät" automatic_groups: "Automaattiset ryhmät" @@ -540,6 +541,7 @@ fi: activity_stream: "Toiminta" preferences: "Asetukset" expand_profile: "Laajenna" + collapse_profile: "Supista" bookmarks: "Kirjanmerkit" bio: "Tietoa minusta" invited_by: "Kutsuja" @@ -547,6 +549,7 @@ fi: notifications: "Ilmoitukset" statistics: "Tilastot" desktop_notifications: + label: "Live-ilmoitukset" not_supported: "Tämä selain ei tue ilmoituksia, pahoittelut." perm_default: "Näytä ilmoituksia" perm_denied_btn: "Ei oikeuksia" @@ -554,6 +557,7 @@ fi: disable: "Poista ilmoitukset käytöstä" enable: "Näytä ilmoituksia" each_browser_note: "Huom: Asetus on säädettävä erikseen jokaisessa selaimessa, jota käytät." + consent_prompt: "Haluatko liveilmoituksia kun muut vastaavat viesteihisi?" dismiss: 'Unohda' dismiss_notifications: "Unohda kaikki" dismiss_notifications_tooltip: "Merkitse kaikki lukemattomat ilmoitukset luetuiksi" @@ -586,6 +590,7 @@ fi: individual_no_echo: "Lähetä sähköposti jokaisesta uudesta viestistä lukuun ottamatta omiani" many_per_day: "Lähetä minulle sähköpostia jokaisesta uudesta viestistä (noin {{dailyEmailEstimate}} päivässä)" few_per_day: "Lähetä minulle sähköpostia jokaisesta uudesta viestistä (noin 2 päivässä)" + warning: "Postituslistatila käytössä. Sähköposti-ilmoitusasetukset syrjäytetty." tag_settings: "Tunnisteet" watched_tags: "Tarkkailtavat" watched_tags_instructions: "Ketjut joilla on joku näistä tunnisteista asetetaan automaattisesti tarkkailuun. Saat ilmoituksen kaikista uusista viesteistä ja ketjuista, ja uusien viestien lukumäärä näytetään ketjun otsikon vieressä. " @@ -662,7 +667,6 @@ fi: second_factor: title: "Kaksivaiheinen tunnistautuminen" disable: "Poista kaksivaiheinen tunnistautuminen käytöstä" - enable: "tilin tietoturvan parantamiseksi" confirm_password_description: "Jatka vahvistamalla salasanasi" label: "Koodi" enable_description: | @@ -1105,6 +1109,8 @@ fi: shift: 'Shift' ctrl: 'Ctrl' alt: 'Alt' + conditional_loading_section: + loading: Ladataan... select_kit: default_header_text: Valitse... no_content: Ei osumia @@ -1299,6 +1305,8 @@ fi: posted: '{{username}} vastasi ketjuun "{{topic}}" - {{site_title}}' private_message: '{{username}} lähetti sinulle yksityisviestin keskustelussa "{{topic}}" - {{site_title}}' linked: '{{username}} linkitti viestiisi ketjusta "{{topic}}" - {{site_title}}' + confirm_title: 'Ilmoitukset käytössä - %{site_title}' + confirm_body: 'Onnistui! Ilmoitukset ovat nyt käytössä.' upload_selector: title: "Lisää kuva" title_with_attachments: "Lisää kuva tai tiedosto" @@ -1360,6 +1368,7 @@ fi: label: Ketjulla on tunniste filters: label: Tuloksiin vain ketjuja/viestejä... + title: Etsi vain otsikoista likes: joista olen tykännyt posted: joihin olen kirjoittanut watching: joita tarkkailen @@ -1747,6 +1756,7 @@ fi: instructions: 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: "Huomioi, ettei viestiin liittyviä ilmoituksia siirretä viestin uudelle omistajalle näin jälkikäteen." change_timestamp: title: "Muuta aikaleimaa..." action: "muuta aikaleimaa" @@ -2471,6 +2481,8 @@ fi: dashboard: title: "Hallintapaneeli" last_updated: "Hallintapaneeli on päivitetty viimeksi:" + find_old: "Haeskeletko vanhaa hallintapaneelia?" + old_link: "katsele sitä tästä" version: "Versio" up_to_date: "Sivusto on ajan tasalla!" critical_available: "Kriittinen päivitys on saatavilla." @@ -2505,8 +2517,11 @@ fi: whats_new_in_discourse: "Mitä uutta Discoursessa?" activity_metrics: Aktiivisuusmittareita reports: + trend_title: "%{percent} muutos. Nyt %{current}, viime jaksossa %{prev}." today: "Tänään" yesterday: "Eilen" + last_7_days: "Viimeiset 7" + last_30_days: "Viimeiset 30" all_time: "Kaikilta ajoilta" 7_days_ago: "7 päivää sitten" 30_days_ago: "30 päivää sitten" @@ -2517,6 +2532,10 @@ fi: start_date: "Alkupäivämäärä" end_date: "Loppupäivämäärä" groups: "Kaikki ryhmät" + disabled: "Raportti ei ole käytössä" + trending_search: + more: 'Hakulokit' + disabled: 'Trendaavat haut eivät ole käytössä. Kerää dataa ottamalla käyttöön asetus log search queries.' commits: latest_changes: "Viimeisimmät muutokset: päivitä usein!" by: "käyttäjältä" @@ -2587,6 +2606,7 @@ fi: type: "Tyyppi" users: "Käyttäjät" last_flagged: "Viimeksi liputettu" + no_results: "Ei ole liputettuja ketjuja." short_names: off_topic: "eksyy aiheesta" inappropriate: "sopimaton" @@ -2716,6 +2736,7 @@ fi: details: "Kun tunniste luodaan, päivitetään tai poistetaan." flag_event: name: "Lipputapahtuma" + details: "Kun lippu luodaan tai sen kanssa ollaan yhtä tai eri mieltä tai se sivuutetaan." delivery_status: title: "Toimituksen tila" inactive: "Ei toiminnassa" @@ -2794,7 +2815,7 @@ fi: label: "Varmuuskopioi" title: "Luo varmuuskopio" confirm: "Haluatko luoda uuden varmuuskopion?" - without_uploads: "Kyllä (älä sisällytä tiedostoja)" + without_uploads: "Kyllä (älä sisällytä ladattuja tiedostoja)" download: label: "Lataa" title: "Lähetä sähköposti, jossa on latauslinkki" @@ -2876,6 +2897,10 @@ fi: add_upload: "Lisää tiedosto" upload_file_tip: "Valitse ladattava tiedosto (png, woff2 jne.)" variable_name_invalid: "Muuttujan nimi ei kelpaa. Vain aakkosnumeeriset sallittu. Täytyy alkaa kirjaimella. Täytyy olla uniikki." + variable_name_error: + invalid_syntax: "Muuttujan nimi ei kelpaa - Vain aakkosnumeeriset sallittu. Täytyy alkaa kirjaimella." + no_overwrite: "Muuttujan nimi ei kelpaa. Nimi on toisen muuttujan käytössä." + must_be_unique: "Muuttujan nimi ei kelpaa. Täytyy olla uniikki." upload: "Lataa" child_themes_check: "Teemaan kuuluu tytärteemoja" css_html: "Mukautettu CSS/HTML" @@ -3120,6 +3145,9 @@ fi: disabled_second_factor: "poista kaksivaiheinen tunnistautuminen" topic_published: "ketju julkaistu" post_approved: "viesti hyväksytty" + create_badge: "luo ansiomerkki" + change_badge: "muuta ansiomerkkiä" + delete_badge: "poista ansiomerkki" 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ä." @@ -3506,7 +3534,6 @@ fi: enabled: Ota ansiomerkki käyttöön icon: Ikoni image: Kuva - icon_help: "Käytä joko Font Awesome -luokkaa tai kuvan URL-osoitetta" query: Ansiomerkkien haku tietokannasta (SQL) target_posts: Tietokantakyselyn kohdeviestit auto_revoke: Aja kumoamis-ajo päivittäin diff --git a/config/locales/client.fr.yml b/config/locales/client.fr.yml index bace6f2b83..b4281f937b 100644 --- a/config/locales/client.fr.yml +++ b/config/locales/client.fr.yml @@ -407,7 +407,6 @@ fr: all: "Tous les groupes" empty: "Il n'y a aucun groupe visible." filter: "Filtrer par type de groupe" - all_groups: "Tous les groupes" owner_groups: "Groupes dont je suis propriétaire" close_groups: "Groupes fermés" automatic_groups: "Groupes automatiques" @@ -671,7 +670,6 @@ fr: second_factor: title: "Authentification à deux facteurs" disable: "Désactiver l'authentification à deux facteurs" - enable: "pour une sécurité accrue des comptes" confirm_password_description: "Merci de confirmer votre mot de passe pour continuer" label: "Code" enable_description: | @@ -2821,7 +2819,7 @@ fr: label: "Sauvegarder" title: "Créer une sauvegarde" confirm: "Voulez-vous démarrer une nouvelle sauvegarde ?" - without_uploads: "Oui (ne pas inclure les fichiers)" + without_uploads: "Oui (n'incluez pas de téléversements)" download: label: "Télécharger" title: "Envoyer un courriel avec un lien de téléchargement" @@ -3154,6 +3152,9 @@ fr: disabled_second_factor: "désactiver l'authentification à deux facteurs" topic_published: "sujet publié" post_approved: "message approuvé" + create_badge: "créer un badge" + change_badge: "Modifier un badge" + delete_badge: "supprimer un badge" screened_emails: title: "Courriels affichés" description: "Lorsque quelqu'un essaye de créer 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." @@ -3223,6 +3224,7 @@ fr: placeholder_regexp: "expression régulière" add: 'Ajouter' success: 'Succès' + exists: 'Existe déjà' upload: "Envoyer" upload_successful: "Envoi réussi. Les mots ont été ajoutés." impersonate: @@ -3246,6 +3248,7 @@ fr: suspended: 'Suspendus' silenced: 'Sous silence' suspect: 'Suspects' + staged: 'Distant' approved: "Approuvé ?" approved_selected: one: approuver l'utilisateur @@ -3268,6 +3271,7 @@ fr: silenced: 'Utilisateurs sous silence' suspended: 'Utilisateurs suspendus' suspect: 'Utilisateurs suspects' + staged: 'Utilisateurs distants' reject_successful: one: Utilisateur rejeté avec succès. other: '%{count} utilisateurs rejetés avec succès.' @@ -3491,6 +3495,7 @@ fr: site_settings: title: 'Paramètres' no_results: "Aucun résultat trouvé." + more_than_30_results: "Il y a plus de 30 résultats. Veuillez affiner votre recherche ou sélectionner une catégorie." clear_filter: "Effacer" add_url: "ajouter URL" add_host: "ajouter hôte" @@ -3557,7 +3562,8 @@ fr: enabled: Activer le badge icon: Icône image: Image - icon_help: "Utilisez une classe CSS Font Awesome ou une URL d'image" + icon_help: "Utiliser une classe de Font Awesome" + image_help: "Entrez l'URL de l'image (remplace le champ de l'icône si les deux sont définis)" query: Requête du badge (SQL) target_posts: Requête sur les messages auto_revoke: Exécuter la requête de révocation quotidiennement diff --git a/config/locales/client.gl.yml b/config/locales/client.gl.yml index ffc773a20a..29828cac17 100644 --- a/config/locales/client.gl.yml +++ b/config/locales/client.gl.yml @@ -1686,7 +1686,6 @@ gl: 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" destroy: @@ -2188,7 +2187,6 @@ gl: 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 diff --git a/config/locales/client.he.yml b/config/locales/client.he.yml index 38ecf22014..70861d4ae9 100644 --- a/config/locales/client.he.yml +++ b/config/locales/client.he.yml @@ -16,6 +16,7 @@ he: format: '%n %u' units: byte: + many: בתים one: בית other: בתים two: בתים @@ -44,34 +45,42 @@ he: tiny: half_a_minute: "פחות מדקה" less_than_x_seconds: + many: פחות מ־%{count} שניות one: פחות משנייה other: פחות מ־%{count} שניות two: פחות מ־%{count} שניות x_seconds: + many: '%{count} שניות' one: שנייה אחת other: '%{count} שניות' two: '%{count} שניות' x_minutes: + many: '%{count} דקות' one: דקה אחת other: '%{count} דקות' two: '%{count} דקות' about_x_hours: + many: '%{count} שעות' one: שעה אחת other: '%{count} שעות' two: '%{count} שעות' x_days: + many: '%{count} ימים' one: יום אחד other: '%{count} ימים' two: '%{count} ימים' about_x_years: + many: '%{count} שנים' one: שנה אחת other: '%{count} שנים' two: '%{count} שנים' over_x_years: + many: יותר מ־%{count} שנים one: יותר משנה other: יותר מ־%{count} שנים two: יותר מ־%{count} שנים almost_x_years: + many: '%{count} שנים' one: שנה אחת other: '%{count} שנים' two: '%{count} שנים' @@ -79,41 +88,50 @@ he: date_year: "MMM 'YY" medium: x_minutes: + many: '%{count} דקות' one: דקה אחת other: '%{count} דקות' two: '%{count} דקות' x_hours: + many: '%{count} שעות' one: שעה אחת other: '%{count} שעות' two: '%{count} שעות' x_days: + many: '%{count} ימים' one: יום אחד other: '%{count} ימים' two: '%{count} ימים' date_year: "MMM D, 'YY" medium_with_ago: x_minutes: + many: לפני %{count} דקות one: לפני דקה אחת other: לפני %{count} דקות two: לפני %{count} דקות x_hours: + many: לפני %{count} שעות one: לפני שעה אחת other: לפני %{count} שעות two: לפני %{count} שעות x_days: + many: לפני %{count} ימים one: אתמול other: לפני %{count} ימים two: לפני %{count} ימים later: x_days: + many: אחרי %{count} ימים one: אחרי יום אחד other: אחרי %{count} ימים two: אחרי %{count} ימים x_months: + many: אחרי %{count} חודשים one: אחרי חודש אחד other: אחרי %{count} חודשים two: אחרי %{count} חודשים x_years: + many: אחרי %{count} שנים one: אחרי שנה אחת other: אחרי %{count} שנים two: אחרי %{count} שנים @@ -193,6 +211,7 @@ he: show_help: "אפשרויות" links: "קישורים" links_lowercase: + many: קישורים one: קישור other: קישורים two: קישורים @@ -219,6 +238,7 @@ he: max_of_count: "מקסימום של {{count}}" alternation: "או" character_count: + many: '{{count}} תווים' one: תו אחד other: '{{count}} תווים' two: '{{count}} תווים' @@ -288,6 +308,7 @@ he: cancel: "ביטול" view_pending: "הצג פוסטים ממתינים" has_pending_posts: + many: בנושא זה ישנם {{count}} פוסטים הממתינים לאישור one: ' בנושא זה ישנו פוסט אחד הממתין לאישור' other: בנושא זה ישנם {{count}} פוסטים הממתינים לאישור two: בנושא זה ישנם {{count}} פוסטים הממתינים לאישור @@ -297,6 +318,7 @@ he: title: "הפוסט זקוק לאישור" description: "קיבלנו את הפוסט אך נדרש אישור של מנחה לפני שהוא יוצג, אנא המתינו בסבלנות." pending_posts: + many: יש לכם {{count}} פוסטים ממתינים. one: יש לכם פוסט אחד שממתין. other: יש לכם {{count}} פוסטים ממתינים. two: יש לכם {{count}} פוסטים ממתינים. @@ -333,6 +355,7 @@ he: posts_read: "נקראו" posts_read_long: "פוסטים שנקראו" total_rows: + many: '%{count} משתמשים' one: משתמש/ת 1 other: '%{count} משתמשים' two: '%{count} משתמשים' @@ -432,10 +455,12 @@ he: toggle_ordering: "שנה בקר סדר" subcategories: "תתי קטגוריות" topic_sentence: + many: '%{count} נושאים' one: נושא אחד other: '%{count} נושאים' two: '%{count} נושאים' topic_stat_sentence: + many: '%{count} נושאים חדשים ב-%{unit}.' one: נושא חדש אחד ב-%{unit}. other: '%{count} נושאים חדשים ב-%{unit}.' two: '%{count} נושאים חדשים ב-%{unit}.' @@ -621,6 +646,7 @@ he: authenticated: "כתובת הדואר האלקטרוני שלך אושרה על ידי {{provider}}" frequency_immediately: "נשלח לכם מייל מיידית אם לא קראתם את מה ששלחנו לכם עליו מייל." frequency: + many: נשלח אליכם דוא"ל רק אם לא ראינו אתכם ב{{count}} הדקות האחרונות. one: נשלח אליכם דוא"ל רק אם לא ראינו אתכם בדקה האחרונה. other: נשלח אליכם דוא"ל רק אם לא ראינו אתכם ב{{count}} הדקות האחרונות. two: נשלח אליכם דוא"ל רק אם לא ראינו אתכם ב{{count}} הדקות האחרונות. @@ -708,6 +734,7 @@ he: user: "משתמשים שהוזמנו" sent: "נשלח" truncated: + many: מראה את {{count}} ההזמנות הראשונות. one: מראה את ההזמנה הראשונה. other: מראה את {{count}} ההזמנות הראשונות. two: מראה את {{count}} ההזמנות הראשונות. @@ -756,22 +783,27 @@ he: stats: "סטטיסטיקות" time_read: "זמן קריאה" topic_count: + many: נושאים נוצרו one: נושא נוצר other: נושאים נוצרו two: נושאים נוצרו post_count: + many: פוסטים נוצרו one: פוסט נוצר other: פוסטים נוצרו two: פוסטים נוצרו days_visited: + many: ימים שבוקרו one: יום שבוקר other: ימים שבוקרו two: ימים שבוקרו posts_read: + many: פוסטים נקראו one: פוסט נקרא other: פוסטים נקראו two: פוסטים נקראו bookmark_count: + many: סימניות one: סימנייה other: סימניות two: סימניות @@ -842,6 +874,7 @@ he: reached: "%{relativeAge}%{rate}הגיע לגבול הגדרות האתר של %{siteSettingRate}." exceeded: "%{relativeAge}%{rate} עבר את הגבול של הגדרות האתר ב- %{siteSettingRate}." rate: + many: '%{count} שגיאות\%{duration}' one: שגיאה ל %{duration} other: '%{count} שגיאות\%{duration}' two: '%{count} שגיאות\%{duration}' @@ -860,6 +893,7 @@ he: unmute: בטל השתקה last_reply_lowercase: תגובה אחרונה replies_lowercase: + many: תגובות one: תגובה other: תגובות two: תגובות @@ -1017,6 +1051,7 @@ he: similar_topics: "הנושא שלך דומה ל..." drafts_offline: "טיוטות מנותקות" group_mentioned: + many: על ידי אזכור {{group}}, אתם עומדים ליידע {{count}} אנשים – אתם בטוחים? one: על ידי אזכור {{group}}, אתם עומדים ליידע אדם אחד – אתם בטוחים? other: על ידי אזכור {{group}}, אתם עומדים ליידע {{count}} אנשים – אתם בטוחים? two: על ידי אזכור {{group}}, אתם עומדים ליידע {{count}} אנשים – אתם בטוחים? @@ -1190,6 +1225,7 @@ he: notification_level: "התראות" choose_new_category: "בחרו את הקטגוריה עבור הנושאים:" selected: + many: בחרתם {{count}} נושאים. one: בחרתם נושא אחד. other: בחרתם {{count}} נושאים. two: בחרתם {{count}} נושאים. @@ -1227,6 +1263,7 @@ he: search: "אין עוד תוצאות חיפוש" topic: filter_to: + many: '{{count}} פוסטים בנושא' one: פוסט אחד בנושא other: '{{count}} פוסטים בנושא' two: '{{count}} פוסטים בנושא' @@ -1243,10 +1280,12 @@ he: new: 'נושא חדש' unread: 'לא נקראו' new_topics: + many: '{{count}} נושאים חדשים' one: נושא חדש אחד other: '{{count}} נושאים חדשים' two: '{{count}} נושאים חדשים' unread_topics: + many: '{{count}} נושאים שלא נקראו' one: 1 שלא נקרא other: '{{count}} נושאים שלא נקראו' two: '{{count}} נושאים שלא נקראו' @@ -1262,18 +1301,22 @@ he: title: "הנושא לא נמצא" description: "סליחה, לא יכולנו למצוא את הנושא הזה. אולי הוא הוסר על ידי מנחה?" total_unread_posts: + many: יש לכם {{count}} פוסטים שלא נקראו בנושא זה one: יש לכם פוסט אחד שלא נקרא בנושא זה other: יש לכם {{count}} פוסטים שלא נקראו בנושא זה two: יש לכם {{count}} פוסטים שלא נקראו בנושא זה unread_posts: + many: יש לכם {{count}} פוסטים ישנים שלא נקראו בנושא הזה one: יש לכם פוסט אחד שלא נקרא בנושא הזה other: יש לכם {{count}} פוסטים ישנים שלא נקראו בנושא הזה two: יש לכם {{count}} פוסטים ישנים שלא נקראו בנושא הזה new_posts: + many: יש {{count}} פוסטים חדשים בנושא זה מאז שקראתם אותו לאחרונה one: יש פוסט אחד חדש בנושא הזה מאז שקראתם אותו לאחרונה other: יש {{count}} פוסטים חדשים בנושא זה מאז שקראתם אותו לאחרונה two: יש {{count}} פוסטים חדשים בנושא זה מאז שקראתם אותו לאחרונה likes: + many: יש {{count}} לייקים בנושא זה one: יש לייק אחד בנושא הזה other: יש {{count}} לייקים בנושא זה two: יש {{count}} לייקים בנושא זה @@ -1331,6 +1374,7 @@ he: auto_reminder: "אתם תתוזכרו בנוגע לנושא זה %{timeLeft}." auto_close_title: 'הגדרות סגירה אוטומטית' auto_close_immediate: + many: הפוסט האחרון בנושא הוא כבר בן %{count} שעות, אז הנושא ייסגר אוטומטית. one: הפוסט האחרון בנושא הוא כבר בן שעה, אז הנושא ייסגר מיידית. other: הפוסט האחרון בנושא הוא כבר בן %{count} שעות, אז הנושא ייסגר אוטומטית. two: הפוסט האחרון בנושא הוא כבר בן %{count} שעות, אז הנושא ייסגר אוטומטית. @@ -1440,6 +1484,7 @@ he: pin_validation: "דרוש תאריך על מנת לנעוץ את הנושא." not_pinned: "אין נושאים שננעצו בקטגוריה {{categoryLink}}." already_pinned: + many: 'נושאים ננעצו, נכון לעכשיו, בקטגוריה {{categoryLink}}.: {{count}}' one: 'נושא שננעצו, נכון לעכשיו בקטגוריה {{categoryLink}}: 1' other: 'נושאים ננעצו, נכון לעכשיו, בקטגוריה {{categoryLink}}.: {{count}}' two: 'נושאים ננעצו, נכון לעכשיו, בקטגוריה {{categoryLink}}.: {{count}}' @@ -1450,6 +1495,7 @@ he: global_pin_note: "משתמשים יכולים להסיר את הצמדת הנושא באופן עצמאי לעצמם." not_pinned_globally: "אין נושאים נעוצים גלובאלית." already_pinned_globally: + many: 'נושאים שכרגע נעוצים גלובאלית: {{count}}' one: 'נושאים שכרגע נעוצים גלובאלית: 1' other: 'נושאים שכרגע נעוצים גלובאלית: {{count}}' two: 'נושאים שכרגע נעוצים גלובאלית: {{count}}' @@ -1488,6 +1534,7 @@ he: login_reply: 'התחברו כדי להשיב' filters: n_posts: + many: '{{count}} פוסטים' one: פוסט אחד other: '{{count}} פוסטים' two: '{{count}} פוסטים' @@ -1498,6 +1545,7 @@ he: topic_name: "שם הנושא החדש" error: "הייתה שגיאה בהעברת הפוסטים לנושא החדש." instructions: + many: אתם עומדים ליצור נושא חדש ולמלא אותו עם {{count}} הפוסטים שבחרתם. one: אתם עומדים ליצור נושא חדש ולמלא אותו עם הפוסטים שבחרתם. other: אתם עומדים ליצור נושא חדש ולמלא אותו עם {{count}} הפוסטים שבחרתם. two: אתם עומדים ליצור נושא חדש ולמלא אותו עם {{count}} הפוסטים שבחרתם. @@ -1506,6 +1554,7 @@ he: action: "העבר לנושא קיים" error: "התרחשה שגיאה בהעברת הפוסטים לנושא הזה." instructions: + many: בבקשה בחרו את הנושא אליו תרצה להעביר את {{count}} הפוסטים. one: בבקשה בחרו נושא אליו הייתם רוצים להעביר את הפוסט. other: בבקשה בחרו את הנושא אליו תרצה להעביר את {{count}} הפוסטים. two: בבקשה בחרו את הנושא אליו תרצה להעביר את {{count}} הפוסטים. @@ -1520,6 +1569,7 @@ he: label: "בעלים חדשים של פוסטים" placeholder: "שם המשתמש של הבעלים החדש" instructions: + many: אנא בחרו את הבעלים החדש של {{count}} הפוסטים מאת {{old_user}}. one: אנא בחר את הבעלים החדש של הפוסטים מאת {{old_user}}. other: אנא בחרו את הבעלים החדש של {{count}} הפוסטים מאת {{old_user}}. two: אנא בחרו את הבעלים החדש של {{count}} הפוסטים מאת {{old_user}}. @@ -1537,6 +1587,7 @@ he: select_all: בחר הכל deselect_all: בחר כלום description: + many: בחרתם {{count}} פוסטים. one: בחרתם פוסט אחד. other: בחרתם {{count}} פוסטים. two: בחרתם {{count}} פוסטים. @@ -1553,29 +1604,35 @@ he: show_full: "הצגת פוסט מלא" show_hidden: 'הצגת תוכן מוסתר.' deleted_by_author: + many: (הפוסט נלקח בחזרה על ידי הכותבים, הוא ימחק אוטומטית בעוד %{count} שעות אלא אם כן הוא ידוגל) one: (הפוסט בוטל על ידי הכותבים, הוא ימחק אוטומטית בעוד %{count} שעות אלא אם יסומן בדגל) other: (הפוסט נלקח בחזרה על ידי הכותבים, הוא ימחק אוטומטית בעוד %{count} שעות אלא אם כן הוא ידוגל) two: (הפוסט נלקח בחזרה על ידי הכותבים, הוא ימחק אוטומטית בעוד %{count} שעות אלא אם כן הוא ידוגל) expand_collapse: "הרחב/צמצם" gap: + many: הצגת {{count}} תגובות שהוסתרו one: הצג תגובה אחת שהוסתרה other: הצגת {{count}} תגובות שהוסתרו two: הצגת {{count}} תגובות שהוסתרו unread: "הפוסט טרם נקרא" has_replies: + many: '{{count}} תגובות' one: תגובה אחת other: '{{count}} תגובות' two: '{{count}} תגובות' has_likes: + many: '{{count}} לייקים ' one: לייק אחד other: '{{count}} לייקים ' two: '{{count}} לייקים ' has_likes_title: + many: '{{count}} אנשים אהבו את התגובה הזו' one: מישהו אחד אהב את התגובה הזו other: '{{count}} אנשים אהבו את התגובה הזו' two: '{{count}} אנשים אהבו את התגובה הזו' has_likes_title_only_you: "אתם אהבתם את התגובה הזו" has_likes_title_you: + many: אתם ו {{count}} אנשים אחרים אהבתם את הפוסט הזה one: אתם ועוד מישהו אהבתם את הפוסט הזה other: אתם ו {{count}} אנשים אחרים אהבתם את הפוסט הזה two: אתם ו {{count}} אנשים אחרים אהבתם את הפוסט הזה @@ -1652,72 +1709,89 @@ he: vote: "הצבעתם לפוסט זה" by_you_and_others: off_topic: + many: אתם ועוד {{count}} אנשים אחרים דיגלתם את זה כאוף-טופיק one: אתם ועוד אחד דיגלתם את זה כאוף-טופיק other: אתם ועוד {{count}} אנשים אחרים דיגלתם את זה כאוף-טופיק two: אתם ועוד {{count}} אנשים אחרים דיגלתם את זה כאוף-טופיק spam: + many: אתם ועוד {{count}} אנשים אחרים דיגלתם את זה כספאם one: אתם ועוד אחד דיגלתם את זה כספאם other: אתם ועוד {{count}} אנשים אחרים דיגלתם את זה כספאם two: אתם ועוד {{count}} אנשים אחרים דיגלתם את זה כספאם inappropriate: + many: אתם ועוד {{count}} אנשים אחרים דיגלתם את זה כלא ראוי one: אתם ועוד אחד דיגלתם את זה כלא ראוי other: אתם ועוד {{count}} אנשים אחרים דיגלתם את זה כלא ראוי two: אתם ועוד {{count}} אנשים אחרים דיגלתם את זה כלא ראוי notify_moderators: + many: אתם ועוד {{count}} אנשים אחרים דיגלתם את זה למנחים one: אתם ועוד אחד דיגלתם את זה עבור המנחים other: אתם ועוד {{count}} אנשים אחרים דיגלתם את זה למנחים two: אתם ועוד {{count}} אנשים אחרים דיגלתם את זה למנחים notify_user: + many: אתם ו{{count}} אנשים נוספים שלחתם הודעה למשתמש הזה one: 'אתם ו-1 נוסף שלחתם הודעה למשתמש הזה. ' other: אתם ו{{count}} אנשים נוספים שלחתם הודעה למשתמש הזה two: אתם ו{{count}} אנשים נוספים שלחתם הודעה למשתמש הזה bookmark: + many: אתה ועוד {{count}} אנשים אחרים סימנתם פוסט זה עם סימנייה one: אתה ועוד אחד סימנתם פוסט זה עם סימנייה other: אתה ועוד {{count}} אנשים אחרים סימנתם פוסט זה עם סימנייה two: אתה ועוד {{count}} אנשים אחרים סימנתם פוסט זה עם סימנייה like: + many: אתה ועוד {{count}} אנשים אחרים נתתם לייק לזה one: אתה ועוד אחד נתתם לייק לזה other: אתה ועוד {{count}} אנשים אחרים נתתם לייק לזה two: אתה ועוד {{count}} אנשים אחרים נתתם לייק לזה vote: + many: אתה ועוד {{count}} אנשים אחרים הצבעתם לפוסט זה one: אתה ועוד אחד הצבעתם לפוסט זה other: אתה ועוד {{count}} אנשים אחרים הצבעתם לפוסט זה two: אתה ועוד {{count}} אנשים אחרים הצבעתם לפוסט זה by_others: off_topic: + many: '{{count}} אנשים סמנו את זה כאוף-טופיק' one: אדם אחד דיגל את זה כאוף-טופיק other: '{{count}} אנשים סמנו את זה כאוף-טופיק' two: '{{count}} אנשים סמנו את זה כאוף-טופיק' spam: + many: '{{count}} אנשים דיגלו את זה כספאם' one: אדם אחד דיגל את זה כספאם other: '{{count}} אנשים דיגלו את זה כספאם' two: '{{count}} אנשים דיגלו את זה כספאם' inappropriate: + many: '{{count}} אנשים דיגלו את זה כלא ראוי' one: אדם אחד דיגל את זה כלא ראוי other: '{{count}} אנשים דיגלו את זה כלא ראוי' two: '{{count}} אנשים דיגלו את זה כלא ראוי' notify_moderators: + many: '{{count}} אנשים דיגלו את זה למנחים' one: אדם אחד דיגל את זה למנחים other: '{{count}} אנשים דיגלו את זה למנחים' two: '{{count}} אנשים דיגלו את זה למנחים' notify_user: + many: '{{count}} שלחו הודעה למשתמש זה' one: אדם אחד שלח הודעה למשתמש זה other: '{{count}} שלחו הודעה למשתמש זה' two: '{{count}} שלחו הודעה למשתמש זה' bookmark: + many: '{{count}} אנשים סימנו פוסט זה כמועדף' one: אדם אחד סימן פוסט זה כמועדף other: '{{count}} אנשים סימנו פוסט זה כמועדף' two: '{{count}} אנשים סימנו פוסט זה כמועדף' like: + many: '{{count}} אנשים נתנו לזה לייק' one: אדם אחד נתן לזה לייק other: '{{count}} אנשים נתנו לזה לייק' two: '{{count}} אנשים נתנו לזה לייק' vote: + many: '{{count}} אנשים הצביעו לפוסט זה' one: אדם אחד הצביע לפוסט זה other: '{{count}} אנשים הצביעו לפוסט זה' two: '{{count}} אנשים הצביעו לפוסט זה' merge: confirm: + many: האם אתם בטוחים שאתם מעוניינים למזג {{count}} פוסטים אלו? one: האם אתם בטוחים שאתם מעוניינים למזג פוסטים אלו? other: האם אתם בטוחים שאתם מעוניינים למזג {{count}} פוסטים אלו? two: האם אתם בטוחים שאתם מעוניינים למזג {{count}} פוסטים אלו? @@ -1874,14 +1948,17 @@ he: custom_placeholder_notify_moderators: "ספרו לנו מה בדיוק מטריד אתכם וצרפו קישורים רלוונטיים ודוגמאות במידת האפשר." custom_message: at_least: + many: הכניסו לפחות {{count}} תווים one: הכניסו לפחות תו אחד other: הכניסו לפחות {{count}} תווים two: הכניסו לפחות {{count}} תווים more: + many: '{{count}} נשארו...' one: נשאר אחד other: '{{count}} נשארו...' two: '{{count}} נשארו...' left: + many: '{{count}} נותרו' one: נותר אחד other: '{{count}} נותרו' two: '{{count}} נותרו' @@ -1895,12 +1972,14 @@ he: links_title: "לינקים פופלארים" links_shown: "הצגת קישורים נוספים..." clicks: + many: '%{count} לחיצות' one: לחיצה אחת other: '%{count} לחיצות' two: '%{count} לחיצות' post_links: about: "הרחיבו לינקים נוספים לפוסט זה" title: + many: עוד %{count} one: עוד 1 other: עוד %{count} two: עוד %{count} @@ -1937,23 +2016,27 @@ he: original_post: "פוסט מקורי" views: "צפיות" views_lowercase: + many: צפיות one: צפיה other: צפיות two: צפיות replies: "תגובות" views_long: + many: נושא זה נצפה {{number}} פעמים one: נושא זה נצפה פעם 1 other: נושא זה נצפה {{number}} פעמים two: נושא זה נצפה {{number}} פעמים activity: "פעילות" likes: "לייקים" likes_lowercase: + many: לייקים one: לייק other: לייקים two: לייקים likes_long: "יש {{number}} לייקים לנושא הזה" users: "משתמשים" users_lowercase: + many: משתמשים one: משתמש other: משתמשים two: משתמשים @@ -1970,6 +2053,7 @@ he: latest: title: "פורסמו לאחרונה" title_with_count: + many: ({{count}}) פורסמו לאחרונה one: האחרון (1) other: ({{count}}) פורסמו לאחרונה two: ({{count}}) פורסמו לאחרונה @@ -1990,22 +2074,26 @@ he: unread: title: "לא-נקראו" title_with_count: + many: לא-נקראו ({{count}}) one: לא נקרא (1) other: לא-נקראו ({{count}}) two: לא-נקראו ({{count}}) help: "נושאים שאתם כרגע צופים או עוקבים אחריהם עם פוסטים שלא נקראו" lower_title_with_count: + many: 'לא-נקראו {{count}} ' one: לא נקרא (1) other: 'לא-נקראו {{count}} ' two: 'לא-נקראו {{count}} ' new: lower_title_with_count: + many: '{{count}} חדשים' one: חדש (1) other: '{{count}} חדשים' two: '{{count}} חדשים' lower_title: "חדש" title: "חדש" title_with_count: + many: חדשים ({{count}}) one: חדש (1) other: חדשים ({{count}}) two: חדשים ({{count}}) @@ -2019,6 +2107,7 @@ he: category: title: "{{categoryName}}" title_with_count: + many: '{{categoryName}} ({{count}})' one: '{{categoryName}} (1)' other: '{{categoryName}} ({{count}})' two: '{{categoryName}} ({{count}})' @@ -2105,6 +2194,7 @@ he: print: 'ctrl+p הדפסת נושא' badges: earned_n_times: + many: הרוויחו עיטור זה %{count} פעמים one: הרוויחו עיטור זה פעם אחת other: הרוויחו עיטור זה %{count} פעמים two: הרוויחו עיטור זה %{count} פעמים @@ -2114,14 +2204,17 @@ he: allow_title: "אתם יכולים להשתמש בעיטור זה ככותרת" multiple_grant: "אתם יכולים לזכות בזאת מספר פעמים" badge_count: + many: '%{count} עיטורים' one: 1 עיטורים other: '%{count} עיטורים' two: '%{count} עיטורים' more_badges: + many: +%{count} נוספים one: +1 נוסף other: +%{count} נוספים two: +%{count} נוספים granted: + many: '%{count} הוענקו' one: הוענק other: '%{count} הוענקו' two: '%{count} הוענקו' @@ -2384,10 +2477,12 @@ he: none: "אין אירועים קשורים." redeliver: "שליחה מחדש" incoming: + many: יש {{count}} ארועים חדשים. one: יש אירוע חדש. other: יש {{count}} ארועים חדשים. two: יש {{count}} ארועים חדשים. completed_in: + many: הושלמו ב {{count}} שניות. one: הושלמו בשנייה אחת. other: הושלמו ב {{count}} שניות. two: הושלמו ב {{count}} שניות. @@ -2453,7 +2548,6 @@ he: label: "גבוי" title: "צור גיבוי" confirm: "האם תרצו להתחיל גיבוי חדש?" - without_uploads: "כן (ללא הכללת קבצים)" download: label: "הורדה" title: "שליחת מייל עם לינק להורדה" @@ -2551,6 +2645,7 @@ he: up_to_date: "התמה מעודכנת, נבדקה לאחרונה ב:" add: "הוספה" commits_behind: + many: התמה נמצאת {{count}} קומיטים מאחור! one: התמה נמצאת קומיט 1 מאחור! other: התמה נמצאת {{count}} קומיטים מאחור! two: התמה נמצאת {{count}} קומיטים מאחור! @@ -2791,6 +2886,7 @@ he: clear_filter: "ניקוי" show_words: "הצגת מילים" word_count: + many: '%{count} מילים' one: מילה 1 other: '%{count} מילים' two: '%{count} מילים' @@ -2831,10 +2927,12 @@ he: suspect: 'חשודים' approved: "מאושר?" approved_selected: + many: אשרו משתמשים ({{count}}) one: אשר משתמש other: אשרו משתמשים ({{count}}) two: אשרו משתמשים ({{count}}) reject_selected: + many: דחו משתמשים ({{count}}) one: דחו משתמש other: דחו משתמשים ({{count}}) two: דחו משתמשים ({{count}}) @@ -2853,10 +2951,12 @@ he: suspended: 'משתמשים מושעים' suspect: 'משתמשים חשודים' reject_successful: + many: '%{count} משתמשים נדחו בהצלחה.' one: משתמש אחד נדחה בהצלחה. other: '%{count} משתמשים נדחו בהצלחה.' two: '%{count} משתמשים נדחו בהצלחה.' reject_failures: + many: דחיית %{count} משתמשים נכשלה. one: דחיית משתמש נכשלה. other: דחיית %{count} משתמשים נכשלה. two: דחיית %{count} משתמשים נכשלה. @@ -2919,14 +3019,17 @@ he: delete_forbidden_because_staff: "לא ניתן למחוק מנהלים ומנחים." delete_posts_forbidden_because_staff: "לא ניתן למחוק את כל הפרסומים של מנהלי מערכת ומפקחים." delete_forbidden: + many: לא ניתן למחוק משתמשים אם יש להם פוסטים. מחקו את כל הפוסטים לפני ניסיון מחיקה של משתמש. (פוסטים ישנים יותר מ-%{count} ימים לא ניתן למחוק.) one: לא ניתן למחוק משתמשים אם יש להם הודעות. מחקו את כל ההודעות לפני ניסיון מחיקה של משתמש. (הודעות ישנות יותר מיום אחד לא ניתן למחוק.) other: לא ניתן למחוק משתמשים אם יש להם פוסטים. מחקו את כל הפוסטים לפני ניסיון מחיקה של משתמש. (פוסטים ישנים יותר מ-%{count} ימים לא ניתן למחוק.) two: לא ניתן למחוק משתמשים אם יש להם פוסטים. מחקו את כל הפוסטים לפני ניסיון מחיקה של משתמש. (פוסטים ישנים יותר מ-%{count} ימים לא ניתן למחוק.) cant_delete_all_posts: + many: לא ניתן למחוק את כל הפוסטים. חלק מפוסטים ישנים יותר מ-%{count} ימים. (הגדרת delete_user_max_post_age.) one: לא ניתן למחוק את כל ההודעות. חלק מההודעות ישנות יותר מ-%{count} ימים. (הגדרת delete_user_max_post_age.) other: לא ניתן למחוק את כל הפוסטים. חלק מפוסטים ישנים יותר מ-%{count} ימים. (הגדרת delete_user_max_post_age.) two: לא ניתן למחוק את כל הפוסטים. חלק מפוסטים ישנים יותר מ-%{count} ימים. (הגדרת delete_user_max_post_age.) cant_delete_all_too_many_posts: + many: לא ניתן למחוק את כל הפוסטים בגלל שלמשתמשים יותר מ %{count} פוסטים. (delete_all_posts_max) one: לא ניתן למחוק את כל הפוסטים מפני שלמשתמשים יותר מפוסט אחד. (delete_all_posts_max) other: לא ניתן למחוק את כל הפוסטים בגלל שלמשתמשים יותר מ %{count} פוסטים. (delete_all_posts_max) two: לא ניתן למחוק את כל הפוסטים בגלל שלמשתמשים יותר מ %{count} פוסטים. (delete_all_posts_max) @@ -2965,6 +3068,7 @@ he: tl3_requirements: title: "דרישות עבור רמת אמון 3" table_title: + many: 'ב %{count} הימים האחרונים:' one: 'ביום האחרון:' other: 'ב %{count} הימים האחרונים:' two: 'ב %{count} הימים האחרונים:' @@ -3109,7 +3213,6 @@ he: enabled: אפשרו עיטור icon: סמליל image: תמונה - icon_help: "השתמשו במחלקה של Font Awesome או ב-URL לתמונה" query: שאילתת עיטור (SQL) target_posts: פרסומי מטרות שאילתה auto_revoke: הפעלת שאילתת ביטול יומית @@ -3133,6 +3236,7 @@ he: text: "חסרות דוגמאות הענקה. זה קורה כשחיפוש עיטורים מחזיר מזהה משתמש או מזהה פוסט שאינם קיימים. זה עלול לגרום לתוצאות לא צפויות מאוחר יותר - אנא בדקו שוב את מחרוזת החיפוש שלכם." no_grant_count: "אין עיטורים להקצאה." grant_count: + many: %{count} עיטורים להקצאה. one: עיטור אחד להקצאה. other: %{count} עיטורים להקצאה. two: %{count} עיטורים להקצאה. diff --git a/config/locales/client.id.yml b/config/locales/client.id.yml index 52b2ac260a..0baadd6006 100644 --- a/config/locales/client.id.yml +++ b/config/locales/client.id.yml @@ -25,20 +25,20 @@ id: thousands: "{{number}}k" millions: "{{number}}M" dates: - time: "j:mm a" + time: "h:mm a" timeline_date: "MMM YYYY" - long_no_year: "BBB H j:mm a" - long_no_year_no_time: "BBB H" + long_no_year: "BBB D h:mm a" + long_no_year_no_time: "MMM D" full_no_year_no_time: "MMMM Do" - long_with_year: "BBB H, TTTT j:mm a" - long_with_year_no_time: "BBB H, TTTT" + 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: "BBB H, 'TT LT" - long_date_without_year: "BBB H, LT" - long_date_with_year_without_time: "BBB H, 'TT" - long_date_without_year_with_linebreak: "BBB H
    LT" - long_date_with_year_with_linebreak: "BBB H, 'TT
    LT" - wrap_ago: "%{date} lalu" + 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" + wrap_ago: "%{date} yang lalu" tiny: half_a_minute: "< 1m" less_than_x_seconds: @@ -61,8 +61,8 @@ id: other: '> %{count}y' almost_x_years: other: '%{count}y' - date_month: "BBB H" - date_year: "BBB 'TT" + date_month: "MMM D" + date_year: "MMM 'YY" medium: x_minutes: other: '%{count} menit' @@ -70,7 +70,7 @@ id: other: '%{count} jam' x_days: other: '%{count} hari' - date_year: "BBB H, 'TT" + date_year: "MMM D, 'YY" medium_with_ago: x_minutes: other: '%{count} menit yang lalu' @@ -336,7 +336,6 @@ id: index: title: "Grup" all: "Semua Grup" - all_groups: "Semua Grup" close_groups: "Grup Tertutup" automatic_groups: "Grup Otomatis" automatic: "Otomatis" diff --git a/config/locales/client.it.yml b/config/locales/client.it.yml index b2b1c6287d..daa910089d 100644 --- a/config/locales/client.it.yml +++ b/config/locales/client.it.yml @@ -405,7 +405,6 @@ it: all: "Tutti i gruppi" empty: "Non ci sono gruppi visibili." filter: "Filtra per tipo di gruppo" - all_groups: "Tutti i gruppi" owner_groups: "Gruppi di cui sono proprietario" close_groups: "Gruppi Chiusi" automatic_groups: "Gruppi Automatici" @@ -667,7 +666,6 @@ it: second_factor: title: "Autenticazione a Due Fattori" disable: "Disabilita l'autenticazione a due fattori" - enable: "per una maggiore sicurezza dell'account" confirm_password_description: "Per favore conferma la tua password per continuare" label: "Codice" enable_description: | @@ -2624,7 +2622,6 @@ it: label: "Backup" title: "Crea un backup" confirm: "Vuoi creare un nuovo backup?" - without_uploads: "Sì (non includere i file)" download: label: "Scarica" title: "Invia una email con il collegamento per il download" @@ -3309,7 +3306,6 @@ it: enabled: Attiva distintivo icon: Icona image: Immagine - icon_help: "Usa una classe Font Awesome o la URL di un'immagine" query: Query Distintivo (SQL) target_posts: Interroga i messaggi destinazione auto_revoke: Avvia l'istruzione di revoca giornalmente diff --git a/config/locales/client.ja.yml b/config/locales/client.ja.yml index fbcf6291c3..12358e365f 100644 --- a/config/locales/client.ja.yml +++ b/config/locales/client.ja.yml @@ -2202,7 +2202,6 @@ ja: label: "バックアップ" title: "バックアップを行います" confirm: "新しくバックアップを行ってもよろしいですか?" - without_uploads: "はい(ファイルは含まない)" download: label: "ダウンロード" title: "ダウンロードリンクをメールで送る" @@ -2770,7 +2769,6 @@ ja: enabled: バッジを有効にする icon: アイコン image: 画像 - icon_help: "Font Awesomeのクラスか画像のURLを使用してください" query: バッジクエリ(SQL) target_posts: 投稿を対象 auto_revoke: 毎日クエリの取り消しを実行 diff --git a/config/locales/client.ko.yml b/config/locales/client.ko.yml index 6810a5b9a9..94e7cda596 100644 --- a/config/locales/client.ko.yml +++ b/config/locales/client.ko.yml @@ -2358,7 +2358,6 @@ ko: label: "백업" title: "백업 생성" confirm: "새로운 백업을 시작할까요?" - without_uploads: "예 (파일을 포함하지 않음)" download: label: "다운로드" title: "다운로드 링크를 붙여서 이메일 보내기" @@ -3005,7 +3004,6 @@ ko: enabled: 배지 기능 사용 icon: 아이콘 image: 이미지 - icon_help: "이미지 주소로 Font Awesome 클래스 또는 URL을 사용합니다" query: 배지 쿼리(SQL) target_posts: 글들을 대상으로 하는 쿼리 auto_revoke: 회수 쿼리를 매일 실행 diff --git a/config/locales/client.lv.yml b/config/locales/client.lv.yml index 53f8a87cb3..a08b942a20 100644 --- a/config/locales/client.lv.yml +++ b/config/locales/client.lv.yml @@ -2423,7 +2423,6 @@ lv: label: "Rezerves kopija" title: "Izveidot rezerves kopiju" confirm: "Vai jūs vēlaties uzsākt jaunas rezerves kopijas veidošanu?" - without_uploads: "Jā (neiekļaut failus)" download: label: "Lejuplādēt" title: "Nosūtīt e-pastu ar lejuplādes saiti" @@ -3007,7 +3006,6 @@ lv: enabled: Atļaut žetonu icon: Ikona image: Bilde - icon_help: "Izmanto vainu Fontu klasi vai URL uz bildi" query: Vaicājums Žetons (SQL) target_posts: Vaicājums ir vērsts uz ierakstiem auto_revoke: Palaist anulēšanas vaicājumu ikdienā diff --git a/config/locales/client.nb_NO.yml b/config/locales/client.nb_NO.yml index dea4db6db0..2b2fc3e3be 100644 --- a/config/locales/client.nb_NO.yml +++ b/config/locales/client.nb_NO.yml @@ -109,7 +109,7 @@ nb_NO: next_month: 'Neste måned' placeholder: dato share: - topic: 'del en lenke til denne tråden' + topic: 'del en lenke til dette emnet' post: 'innlegg #%{postNumber}' close: 'lukk' twitter: 'del denne lenken på Twitter' @@ -117,9 +117,9 @@ nb_NO: google+: 'del denne lenken på Google+' email: 'del denne lenken i en e-post' action_codes: - public_topic: "gjorde denne tråden offentlig %{when}" - private_topic: "gjorde denne tråden til en personlig melding %{when}" - split_topic: "del opp denne tråden %{when}" + public_topic: "gjorde dette emnet offentlig %{when}" + private_topic: "gjorde dette emnet til en personlig melding %{when}" + split_topic: "del opp dette emnet %{when}" invited_user: "inviterte %{who} %{when}" invited_group: "inviterte %{who} %{when}" user_left: "%{who} fjernet seg selv fra denne meldingen %{when}" @@ -146,7 +146,7 @@ nb_NO: banner: enabled: 'gjorde dette til et banner %{when}. Det vil vises på toppen av hver side inntil brukeren lukker det.' disabled: 'fjernet dette banneret %{when}. Det vil ikke lenger vises på toppen av hver side.' - topic_admin_menu: "administratorhandlinger for tråd" + topic_admin_menu: "administratorhandlinger for emne" wizard_required: "Velkommen til ditt nye Discourse! Kom i gang med oppstartsveiviseren ✨" emails_are_disabled: "All utgående e-post har blitt deaktivert globalt av en administrator. Ingen e-postvarslinger vil bli sendt." bootstrap_mode_enabled: "For å gjøre lansering av siden enklere er den nå i oppstartsmodus. Alle nye brukere vil få tillitsnivå 1 og daglige oppsummeringer på e-post aktivert. Oppstartsmodus vil bli slått av når antall brukere overstiger %{min_users}." @@ -170,7 +170,7 @@ nb_NO: us_gov_west_1: "AWS GovCloud (USA)" us_west_1: "USA vest (N. California)" us_west_2: "USA vest (Oregon)" - edit: 'endre tittelen og kategorien til denne tråden' + edit: 'endre tittelen og kategorien til dette emnet' not_implemented: "Beklager, den funksjonen er ikke blitt implementert enda." no_value: "Nei" yes_value: "Ja" @@ -215,7 +215,7 @@ nb_NO: one: '{{count}} tegn' other: '{{count}} tegn' suggested_topics: - title: "Anbefalte tråder" + title: "Anbefalte emner" pm_title: "Anbefalte meldinger" about: simple_title: "Om" @@ -225,8 +225,10 @@ nb_NO: our_moderators: "Våre moderatorer" stat: all_time: "Gjennom tidene" + last_7_days: "Siste 7" + last_30_days: "Siste 30" like_count: "Likes" - topic_count: "Tråder" + topic_count: "Emner" post_count: "Innlegg" user_count: "Brukere" active_user_count: "Aktive brukere" @@ -236,24 +238,24 @@ nb_NO: title: "Bokmerke" clear_bookmarks: "Fjern bokmerker" help: - bookmark: "Klikk for å bokmerke det første innlegget i denne tråden" - unbookmark: "Klikk for å fjerne alle bokmerker i denne tråden" + bookmark: "Klikk for å bokmerke det første innlegget i dette emnet" + unbookmark: "Klikk for å fjerne alle bokmerker i dette emnet" bookmarks: not_logged_in: "beklager, du må være innlogget for å kunne bokmerke innlegg" created: "du har bokmerket dette innlegget" not_bookmarked: "du har lest dette innlegget; klikk for å bokmerke det" last_read: "dette er det siste innlegget du har lest; klikk for å bokmerke det" remove: "Fjern bokmerke" - confirm_clear: "Er du sikker på at du vil fjerne alle bokmerkene fra denne tråden?" + confirm_clear: "Er du sikker på at du vil fjerne alle bokmerkene fra dette emnet?" topic_count_latest: - one: Se {{count}} nye eller oppdatert tråd - other: Se {{count}} nye eller oppdaterte tråder + one: Se {{count}} nytt eller oppdatert emne + other: Se {{count}} nye eller oppdaterte emner topic_count_unread: - one: Se {{count}} ulest tråd - other: Se {{count}} uleste tråder + one: Se {{count}} ulest emne + other: Se {{count}} uleste emner topic_count_new: - one: Se {{count}} ny tråd - other: Se {{count}} nye tråder + one: Se {{count}} nytt emne + other: Se {{count}} nye emner preview: "forhåndsvisning" cancel: "avbryt" save: "Lagre endringer" @@ -276,12 +278,12 @@ nb_NO: close: "Fjern dette banneret." edit: "Endre dette banneret >>" choose_topic: - none_found: "Ingen tråder funnet." + none_found: "Ingen emner funnet." title: - search: "Søk etter en tråd med navn, URL eller ID:" - placeholder: "skriv tittelen på tråden her" + search: "Søk etter et emne med navn, URL eller ID:" + placeholder: "skriv tittelen på emnet her" queue: - topic: "Tråd:" + topic: "Emne:" approve: 'Godkjenn' reject: 'Avvis' delete_user: 'Slett bruker' @@ -292,7 +294,7 @@ nb_NO: view_pending: "vis ventende innlegg" has_pending_posts: one: Dette emnet har 1 innlegg som venter på godkjenning - other: Denne tråden har {{count}} innlegg som venter på godkjenning + other: Dette emnet har {{count}} innlegg som venter på godkjenning confirm: "Lagre endringer" delete_prompt: "Er du sikker på at du ønsker å slette %{username}? Dette vil fjerne alle innlegg og blokkere e-post- og IP-addressen til vedkommende." approval: @@ -303,12 +305,12 @@ nb_NO: other: Du har {{count}} innlegg som venter på godkjenning. ok: "OK" user_action: - user_posted_topic: "{{user}} opprettet tråden" - you_posted_topic: "Du opprettet tråden" + user_posted_topic: "{{user}} opprettet emnet" + you_posted_topic: "Du opprettet emnet" user_replied_to_post: "{{user}} besvarte {{post_number}}" you_replied_to_post: "Du besvarte {{post_number}}" - user_replied_to_topic: "{{user}} svarte på tråden" - you_replied_to_topic: "Du svarte på tråden" + user_replied_to_topic: "{{user}} svarte på emnet" + you_replied_to_topic: "Du svarte på emnet" user_mentioned_user: "{{user}} nevnte {{another_user}}" user_mentioned_you: "{{user}} nevnte deg" you_mentioned_user: "Du nevnte {{another_user}}" @@ -322,10 +324,10 @@ nb_NO: likes_given: "Gitt" likes_received: "Mottatt" topics_entered: "Lest" - topics_entered_long: "Tråder sett" + topics_entered_long: "Emner Vist" time_read: "Tid lest" - topic_count: "Tråder" - topic_count_long: "Tråder opprettet" + topic_count: "Emner" + topic_count_long: "Emner opprettet" post_count: "Svar" post_count_long: "Svar" no_results: "Ingen treff" @@ -346,6 +348,7 @@ nb_NO: groups: add_members: title: "Legg til medlemmer" + description: "Endre medlemskapet i denne gruppen" usernames: "Brukernavn" manage: title: 'Behandle' @@ -355,6 +358,10 @@ nb_NO: delete_member_confirm: "Fjern '%{username}' fra gruppen '%{group}'?" profile: title: Profil + interaction: + title: Interaksjon + posting: Publisering + notification: Varsling membership: title: Medlemskap access: Tilgang @@ -362,6 +369,8 @@ nb_NO: title: "Logger" when: "Når" action: "Handling" + acting_user: "Utførende bruker" + target_user: "Målbruker" subject: "Emne" details: "Detaljer" from: "Fra" @@ -373,7 +382,7 @@ nb_NO: members: "Det finnes ingen medlemmer av denne gruppen." mentions: "Denne gruppen har aldri blitt nevnt." messages: "Det finnes ingen meldinger til denne gruppen." - topics: "Det finnes ingen tråder opprettet av medlemmer av denne gruppen." + topics: "Det finnes ingen emner opprettet av medlemmer av denne gruppen." logs: "Det finnes ingen logger for denne gruppen." add: "Legg til" join: "Bli medlem" @@ -398,7 +407,6 @@ nb_NO: all: "Alle grupper" empty: "Det finnes ingen synlige grupper" filter: "Filtrer etter gruppetype" - all_groups: "Alle grupper" owner_groups: "Grupper jeg eier" close_groups: "Lukkede grupper" automatic_groups: "Automatiske grupper" @@ -428,7 +436,7 @@ nb_NO: remove_owner: "Fjern som eier" remove_owner_description: "Fjern %{username} som eier av denne gruppen" owner: "Eier" - topics: "Tråder" + topics: "Emner" posts: "Innlegg" mentions: "Omtalelser" messages: "Meldinger" @@ -447,7 +455,7 @@ nb_NO: description: "Du vil bli varslet om hvert nye innlegg i hver beskjed, og antallet nye svar vil bli vist." watching_first_post: title: "Følger første innlegg" - description: "Du vil bare bli varslet om det første innlegget i hver nye tråd i denne gruppen." + description: "Du vil bare bli varslet om det første innlegget i hvert nye emne i denne gruppen." tracking: title: "Overvåker" description: "Du vil få beskjeddersom nevner @navnet ditt eller svarer deg, og antallet nye svar vil bli vist." @@ -456,7 +464,7 @@ nb_NO: description: "Du vil bli varslet hvis noen nevner @navnet ditt eller svarer deg." muted: title: "Ignorert" - description: "Du vil aldri bli varslet om noe vedrørende nye tråder i denne gruppen." + description: "Du vil aldri bli varslet om noe vedrørende nye emner i denne gruppen." flair_url: "Bilde for gruppetilhørighet på avatar" flair_url_placeholder: "(Valgfritt) Font Awesome-klasse eller URL til bilde" flair_bg_color: "Bakgrunnsfarge for gruppetilhørighetsbilde på avatar" @@ -469,7 +477,7 @@ nb_NO: "1": "Likes tildelt" "2": "Likes mottatt" "3": "Bokmerker" - "4": "Tråder" + "4": "Emner" "5": "Svar" "6": "Svar" "7": "Omtalelser" @@ -493,17 +501,17 @@ nb_NO: apply_all: "Bruk" position: "Posisjon" posts: "Innlegg" - topics: "Tråder" + topics: "Emner" latest: "Siste" latest_by: "siste av" toggle_ordering: "Slå på/av styring av sortering" subcategories: "Underkategorier" topic_sentence: - one: 1 tråd - other: '%{count} tråder' + one: 1 emne + other: '%{count} emner' topic_stat_sentence: - one: '%{count} nytt tråder de siste %{unit}.' - other: '%{count} nye tråder de siste %{unit}.' + one: '%{count} nytt emne de siste %{unit}.' + other: '%{count} nye emner de siste %{unit}.' ip_lookup: title: Slå opp IP-adresse hostname: Vertsnavn @@ -516,7 +524,7 @@ nb_NO: username: "brukernavn" trust_level: "TN" read_time: "lesetid" - topics_entered: "tråder åpnet" + topics_entered: "emner åpnet" post_count: "# innlegg" confirm_delete_other_accounts: "Er du sikker på at du vil slette disse kontoene?" powered_by: "drevet av ipinfo.io" @@ -546,6 +554,7 @@ nb_NO: notifications: "Varsler" statistics: "Statistikk" desktop_notifications: + label: "Skrivebordsvarsler" not_supported: "Varsler er ikke støttet på denne nettleseren. Beklager." perm_default: "Slå på varslinger" perm_denied_btn: "Tillatelse avslått" @@ -553,12 +562,13 @@ nb_NO: disable: "Slå av varslinger" enable: "Slå på varslinger" each_browser_note: "Merk: Du må endre denne innstillinger for hver nettleser du bruker." + consent_prompt: "Ønsker du å motta skrivebordsvarsler når andre svarer på dine innlegg?" dismiss: 'Avslå' dismiss_notifications: "Forkast alle" dismiss_notifications_tooltip: "Merk alle uleste varslinger som lest" first_notification: "Ditt første varsel! Velg det for å komme i gang." disable_jump_reply: "Ikke hopp til ditt nye innlegg etter svar" - dynamic_favicon: "Vis antall nye / oppdaterte tråder på nettleserikonet" + dynamic_favicon: "Vis antall nye / oppdaterte emner på nettleserikonet" theme_default_on_all_devices: "Gjør dette til forvalgt drakt på alle mine enheter" allow_private_messages: "Tillat andre brukere å sende meg personlige meldinger" external_links_in_new_tab: "Åpne alle eksterne lenker i ny fane" @@ -579,41 +589,43 @@ nb_NO: enabled: "Slå på e-postlistemodus" instructions: | Denne innstillingen overstyrer oppsummeringen av aktivitet.
    - Ignorerte tråder og kategorier blir ikke inkludert i disse e-postene. + Ignorerte emner og kategorier blir ikke inkludert i disse e-postene. individual: "Send en e-post for hvert nye innlegg" individual_no_echo: "Send en e-post for hvert nye innlegg bortsett fra mine egne" many_per_day: "Send meg en e-post for hvert nye innlegg (rundt {{dailyEmailEstimate}} per deg)" few_per_day: "Send meg en e-post for hvert nye innlegg (rundt to ganger om dagen)" + warning: "E-postlistemodus er aktivert. Instillinger for e-postvarslinger blir overstyrt." tag_settings: "Stikkord" watched_tags: "Fulgt" - watched_tags_instructions: "Du vil automatisk følge alle tråder med disse stikkordene. Du vil bli varslet om alle nye innlegg og tråder, og antallet nye innlegg til også vises ved siden av tråden." + watched_tags_instructions: "Du vil automatisk følge alle emner som har disse stikkordene. Du vil bli varslet om alle nye innlegg og emner, og antallet nye innlegg til også vises ved siden av emnet." tracked_tags: "Overvåkes" - tracked_tags_instructions: "Du vil automatisk overvåke alle tråder med disse stikkordene. Antallet nye innlegg vil vises ved siden av tråden." + tracked_tags_instructions: "Du vil automatisk overvåke alle emner som har disse stikkordene. Antallet nye innlegg vil vises ved siden av emnet." muted_tags: "Ignorert" - muted_tags_instructions: "Du vil ikke bli varslet om noe vedrørende nye tråder med disse stikkordene, og de vil ikke vises i siste." + muted_tags_instructions: "Du vil ikke bli varslet om noe vedrørende nye emner som har disse stikkordene, og de vil ikke vises i siste." watched_categories: "Fulgt" - watched_categories_instructions: "Du vil automatisk følge alle trådene i disse kategoriene. Du vil bli varslet om alle nye innlegg og tråder, og antallet nye innlegg vil vises ved siden av tråden." + watched_categories_instructions: "Du vil automatisk følge alle emnene i disse kategoriene. Du vil bli varslet om alle nye innlegg og emner, og antallet nye innlegg vil vises ved siden av emnet." tracked_categories: "Overvåkes" - tracked_categories_instructions: "Du vil automatisk overvåke alle tråder i disse kategoriene. Tallet på nye innlegg vil vises ved siden av tråden." + tracked_categories_instructions: "Du vil automatisk overvåke alle emner i disse kategoriene. Tallet på nye innlegg vil vises ved siden av emnet." watched_first_post_categories: "Følger første innlegg" - watched_first_post_categories_instructions: "Du vil bli varslet om det første innlegget i hver nye tråd i disse kategoriene." + watched_first_post_categories_instructions: "Du vil bli varslet om det første innlegget i hvert nye emne i disse kategoriene." watched_first_post_tags: "Følger første innlegg" - watched_first_post_tags_instructions: "Du vil bli varslet om det første innlegget i hver nye tråd med disse stikkordene." + watched_first_post_tags_instructions: "Du vil bli varslet om det første innlegget i hvert nye emne med disse stikkordene." muted_categories: "Ignorert" - muted_categories_instructions: "Du vil ikke bli varslet om noe med tanke på nye tråder i disse kategoriene, og de vil ikke vises i siste." + muted_categories_instructions: "Du vil ikke bli varslet om noe som omhandler nye emner i disse kategoriene, og de vil ikke vises i siste." no_category_access: "Som moderator har du begrenset kategoritilgang, lagring er avskrudd." 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." + delete_yourself_not_allowed: "Vennligst kontakt et medlem av staben hvis du ønsker at kontoen din skal slettes." unread_message_count: "Meldinger" admin_delete: "Slett" users: "Brukere" muted_users: "Ignorert" muted_users_instructions: "Skjul alle varsler fra denne brukeren" - muted_topics_link: "Vis ignorerte tråder" - watched_topics_link: "Vis fulgte tråder" - tracked_topics_link: "Vis fulgte tråder" - automatically_unpin_topics: "Automatisk fjern feste for tråder når jeg når bunnen." + muted_topics_link: "Vis ignorerte emner" + watched_topics_link: "Vis fulgte emner" + tracked_topics_link: "Vis overvåkede emner" + automatically_unpin_topics: "Fjern feste for et emne automatisk når jeg når bunnen." apps: "Programmer" revoke_access: "Trekk tilbake tilgang" undo_revoke_access: "Angre tilbaketrekking av tilgang" @@ -659,10 +671,15 @@ nb_NO: second_factor: title: "Totrinnsverifisering" disable: "Skru av totrinnsverifisering" - enable: "for bedret kontosikkerhet" confirm_password_description: "Bekreft passordet ditt for å fortsette" label: "Kode" + enable_description: | + Les av denne QR-koden med en støttet app (AndroidiOSWindows Phone) og skriv inn autentiseringskoden din. + disable_description: "Vennligst oppgi autentiseringskoden fra appen" show_key_description: "Skriv inn manuelt" + extended_description: | + Tofaktor autentisering øker sikkerheten for kontoen din ved at den krever en unik engangskode i tillegg til passordet. Kodene kan genereres med en Android,iOS eller Windows Phone enhet. + oauth_enabled_warning: "Vær oppmerksom på at sosiale login-metoder deaktiveres når tofaktor autentisering er aktivert på kontoen din." change_about: title: "Rediger om meg" error: "Det oppstod en feil ved endring av denne verdien." @@ -750,7 +767,7 @@ nb_NO: always: "alltid" never: "aldri" email_digests: - title: "Send meg en oppsummering på e-post av populære tråder og svar dersom jeg ikke besøker siden" + title: "Send meg en oppsummering på e-post av populære emner og svar dersom jeg ikke besøker siden" every_30_minutes: "hvert 30 minutt" every_hour: "hver time" daily: "daglig" @@ -759,20 +776,20 @@ nb_NO: every_two_weeks: "annenhver uke" include_tl0_in_digests: "Inkluder innhold fra nye brukere i oppsummerings-eposter" email_in_reply_to: "Inkluder et utdrag i e-poster av innlegget man svarer på" - email_direct: "Send meg en e-post når noen siterer meg, svarer på innlegget mitt, nevner @brukernavnet mitt eller inviterer meg til en tråd" + email_direct: "Send meg en e-post når noen siterer meg, svarer på innlegget mitt, nevner @brukernavnet mitt eller inviterer meg til et emne" email_private_messages: "Motta en e-post når noen sender meg en melding" email_always: "Send meg varsler på e-post selv når jeg er aktiv på nettstedet" other_settings: "Annet" categories_settings: "Kategorier" new_topic_duration: - label: "Anse tråder som nye når" + label: "Anse emner som nye når" not_viewed: "jeg ikke har sett dem ennå" last_here: "opprettet siden jeg var her sist" after_1_day: "opprettet i løpet av det siste døgnet" after_2_days: "opprettet i løpet av de siste 2 døgnene" after_1_week: "opprettet i løpet av sist uke" after_2_weeks: "opprettet i løpet av de siste 2 ukene" - auto_track_topics: "Overvåk automatisk tråder jeg åpner" + auto_track_topics: "Overvåk automatisk emner jeg åpner" auto_track_options: never: "aldri" immediately: "øyeblikkelig" @@ -783,7 +800,7 @@ nb_NO: after_4_minutes: "etter 4 minutt" after_5_minutes: "etter 5 minutt" after_10_minutes: "etter 10 minutt" - notification_level_when_replying: "Når jeg skriver noe i en tråd, sett tråden som" + notification_level_when_replying: "Når jeg skriver noe i et emne, sett emnet som" invited: search: "skriv for å søke etter invitasjoner…" title: "invitasjoner" @@ -800,7 +817,7 @@ nb_NO: pending: "Ventende invitasjoner" pending_tab: "På vent" pending_tab_with_count: "Ventende ({{count}})" - topics_entered: "Tråder vist" + topics_entered: "Emner Vist" posts_read_count: "Innlegg lest" expired: "Denne invitasjonen har utløpt" rescind: "Fjern" @@ -839,8 +856,8 @@ nb_NO: time_read: "lesetid" recent_time_read: "nylig lesetid" topic_count: - one: tråd opprettet - other: tråder opprettet + one: emne opprettet + other: emner opprettet post_count: one: innlegg skrevet other: innlegg skrevet @@ -854,8 +871,8 @@ nb_NO: one: dag besøkt other: dager besøkt topics_entered: - one: tråd vist - other: tråder vist + one: emne vist + other: emner vist posts_read: one: innlegg lest other: innlegg lest @@ -865,9 +882,9 @@ nb_NO: top_replies: "Mest Populære Svar" no_replies: "Ingen svar ennå." more_replies: "Flere svar" - top_topics: "Mest populære tråder" - no_topics: "Ingen tråder ennå." - more_topics: "Flere tråder" + top_topics: "Mest populære emner" + no_topics: "Ingen emner enda." + more_topics: "Flere Emner" top_badges: "Toppmerker" no_badges: "Ingen merker ennå." more_badges: "Flere merker" @@ -887,13 +904,14 @@ nb_NO: header_title: "Profil, meldinger, bokmerker og innstillinger" title: title: "Tittel" + none: "(ingen)" filters: all: "Alle" stream: posted_by: "Skrevet av" sent_by: "Sendt av" private_message: "melding" - the_topic: "tråden" + the_topic: "emnet" loading: "Laster…" errors: prev_page: "ved lasting" @@ -922,8 +940,8 @@ nb_NO: enabled: "Dette nettstedet er i lesemodus. Fortsett gjerne å lese, men du kan ikke svare, gi likes eller utføre andre handlinger som er slått av." login_disabled: "Innlogging er deaktivert mens nettsiden er i skrivebeskyttet modus." logout_disabled: "Du kan ikke logge ut når nettstedet er i lese-modus." - too_few_topics_and_posts_notice: "La oss få i gang diskusjonen! Det finnes for øyeblikket %{currentTopics} / %{requiredTopics} tråder og %{currentPosts} / %{requiredPosts} svar. Nye besøkende trenger noen samtaler å lese og svare på." - too_few_topics_notice: "La oss få i gang diskusjonen. Det finnes for øyeblikket %{currentTopics} / %{requiredTopics} tråder. Nye besøkende trenger noen samtaler å lese og svare på." + too_few_topics_and_posts_notice: "La oss dra i gang diskusjonen! Det finnes for øyeblikket %{currentTopics} / %{requiredTopics} emner og %{currentPosts} / %{requiredPosts} svar. Nye besøkende trenger noen samtaler å lese og svare på." + too_few_topics_notice: "La oss dra i gang diskusjonen! Det finnes for øyeblikket %{currentTopics} / %{requiredTopics} emner. Nye besøkende trenger noen samtaler å lese og svare på." too_few_posts_notice: "La oss få i gang diskusjonen. Det finnes for øyeblikket %{currentPosts} / %{requiredPosts} svar. Nye besøkende trenger noen samtaler å lese og svare på." logs_error_rate_notice: reached: "%{relativeAge}%{rate} nådde innstillingsgrensen satt i %{siteSettingRate}." @@ -933,13 +951,13 @@ nb_NO: other: '%{count} feil/%{duration}' learn_more: "lær mer…" all_time: 'totalt' - all_time_desc: 'totalt antall tråder opprettet' + all_time_desc: 'totalt antall emner opprettet' year: 'år' - year_desc: 'tråder opprettet de siste 365 dagene' + year_desc: 'emner opprettet de siste 365 dagene' month: 'måned' - month_desc: 'tråder opprettet de siste 30 dagene' + month_desc: 'emner opprettet de siste 30 dagene' week: 'uke' - week_desc: 'tråder opprettet de siste 7 dagene' + week_desc: 'emner opprettet de siste 7 dagene' day: 'dag' first_post: Første innlegg mute: Ignorer @@ -961,14 +979,14 @@ nb_NO: intro: "Hei du! :heart_eyes: Det ser ut som du følger diskusjonen, men ikke har registrert deg ennå." 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 denne tråden: de mest interessante innleggene ifølge brukerne." + enabled_description: "Du ser for øyeblikket en oppsummering av dette emnet: de mest interessante innleggene ifølge brukerne." description: "Det finnes {{replyCount}} svar." description_time: "Det finnes {{replyCount}} svar med en forventet lesetid på {{readingTime}} minutter." - enable: 'Oppsummer denne tråden' + enable: 'Oppsummer dette emnet' disable: 'Vis alle innlegg' deleted_filter: - enabled_description: "Denne tråden inneholder slettede innlegg, som er blitt skjult." - disabled_description: "Slettede innlegg i tråden vises." + enabled_description: "Dette emnet inneholder slettede innlegg, som er blitt skjult." + disabled_description: "Slettede innlegg i emnet vises." enable: "Skjul slettede innlegg" disable: "Vis slettede innlegg" private_message_info: @@ -1003,7 +1021,12 @@ nb_NO: button_ok: "OK" button_help: "Hjelp" email_login: + link_label: "Send meg lenke til innlogging via e-post" button_label: "med e-post" + complete_username: "Hvis en konto matcher brukernavnet %{username}, vil du snart motta en e-post med en lenke som logger deg inn." + complete_email: "Hvis en konto matcher %{email}, vil du snart motta en e-post med en lenke som logger deg inn." + complete_username_found: "Vi fant en konto som matcher brukernavnet %{username}, du vil snart motta en e-post med lenke for innlogging." + complete_email_found: "Vi fant en konto som matcher %{email}, du vil snart motta en e-post med lenke for innlogging." complete_username_not_found: "Ingen konto har med brukernavnet %{username} er registrert" complete_email_not_found: "Ingen konto med e-postadressen %{email} er registrert" login: @@ -1029,6 +1052,7 @@ nb_NO: not_allowed_from_ip_address: "Du kan ikke logge inn fra den IP-adressen." 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." + omniauth_disallow_totp: "Kontoen din har tofaktor autentisering aktivert. Vennligst logg inn med passordet ditt." resend_title: "Send aktivterings-e-post på nytt" change_email: "Endre e-postadresse" provide_new_email: "Oppgi en ny adresse og vi vil sende din aktiverings-e-post på nytt." @@ -1082,9 +1106,9 @@ nb_NO: facebook_messenger: "Facebook Meldingstjeneste" category_page_style: categories_only: "Kun kategorier" - categories_with_featured_topics: "Kategorier med fremhevede tråder" - categories_and_latest_topics: "Kategorier og siste tråder" - categories_and_top_topics: "Kategorier og topptråder" + categories_with_featured_topics: "Kategorier med Fremhevede Emner" + categories_and_latest_topics: "Kategorier og Siste Emner" + categories_and_top_topics: "Kategorier og Toppemner" shortcut_modifier_key: shift: 'Shift' ctrl: 'Ctrl' @@ -1099,6 +1123,9 @@ nb_NO: max_content_reached: one: Du kan kun velge {{count}} gjenstand. other: Du kan kun velge {{count}} gjenstander. + min_content_not_reached: + one: Velg minst {{count}} element. + other: Velg minst {{count}} elementer. emoji_picker: filter_placeholder: Søk etter emoji people: Folk @@ -1118,11 +1145,11 @@ nb_NO: dark_tone: Mørk hudtone shared_drafts: title: "Delte kladder" - notice: "Denne tråden er kun synlig for dem som kan se {{category}}-kategorien." + notice: "Dette emnet er kun synlig for dem som kan se {{category}}-kategorien." destination_category: "Målkategori" publish: "Publiser delt kladd" confirm_publish: "Er du sikker på at du vil publisere denne kladden?" - publishing: "Publiserer tråd…" + publishing: "Publiserer Emne…" composer: emoji: "Emoji :)" more_emoji: "mer…" @@ -1133,11 +1160,11 @@ nb_NO: add_warning: "Dette er en offisiell advarsel." toggle_whisper: "Slå på/av hvisking" toggle_unlisted: "Skjul eller gjør synlig" - posting_not_on_topic: "Du svarer på tråden \"{{title}}\", men for øyeblikket ser du på et annet tråd." + posting_not_on_topic: "Du svarer på emnet \"{{title}}\", men for øyeblikket ser du på et annet emne." saving_draft_tip: "lagrer…" saved_draft_tip: "lagret" saved_local_draft_tip: "lagret lokalt" - similar_topics: "Tråden din har likheter med…" + similar_topics: "Emnet ditt har likheter med…" drafts_offline: "utkast offline" group_mentioned_limit: "Warning! Du varslet {{group}}, dog har denne gruppen flere medlemmer en administratoren har satt opp som grense for varseling, {{max}} brukere. Ingen vil bli varslet." group_mentioned: @@ -1146,7 +1173,7 @@ nb_NO: cannot_see_mention: category: "Du nevnte {{username}}, men de vil ikke ikke bli varslet fordi de ikke har tilgang til denne kategorien. Du må legge dem til en gruppe som har tilgang til denne kategorien." private: "Du nevnte {{username}}, men de vil ikke bli varslet fordi de ikke kan se denne samtalen. Du må invitere dem til denne private samtalen." - duplicate_link: "Det ser ut til at lenken din til {{domain}} allerede ble publisert i tråden av @{{username}} i et svar {{ago}}. Er du sikker på at du vil publisere den igjen?" + duplicate_link: "Det ser ut til at lenken din til {{domain}} allerede ble publisert i emnet av @{{username}} i et svar {{ago}}. Er du sikker på at du vil publisere den igjen?" error: title_missing: "Tittel er påkrevd" title_too_short: "Tittel må være på minst {{min}} tegn" @@ -1155,15 +1182,17 @@ nb_NO: post_length: "Innlegget må være på minst {{min}} tegn" try_like: 'Har du prøvd knappen?' category_missing: "Du må velge en kategori" + tags_missing: "Du må velge minst {{count}} stikkord" save_edit: "Lagre endring" - reply_original: "Svar på den opprinnelige tråden" + reply_original: "Svar på det Opprinnelige Emnet" reply_here: "Svar her" reply: "Svar" cancel: "Avbryt" - create_topic: "Opprett tråd" + create_topic: "Opprett Emne" create_pm: "Melding" create_whisper: "Hvisk" create_shared_draft: "Opprett delt kladd" + edit_shared_draft: "Rediger Delt Utkast" title: "Eller trykk Ctrl+Enter" users_placeholder: "Legg til en bruker" title_placeholder: "Oppsummert i en setning, hva handler denne diskusjonen om?" @@ -1171,9 +1200,10 @@ nb_NO: edit_reason_placeholder: "hvorfor endrer du?" show_edit_reason: "(legg till endringsbegrunnelse)" topic_featured_link_placeholder: "Skriv inn lenke vist med tittel." - remove_featured_link: "Fjern lenke fra tråden." + remove_featured_link: "Fjern lenke fra emnet." reply_placeholder: "Skriv her. Bruk Markdown, BBCode eller HTML for å formattere. Dra og slipp bilder." reply_placeholder_no_images: "Skriv her. Bruk Markdown, BBkode, eller HTML for å formatere." + reply_placeholder_choose_category: "Du må velge en kategori før du skriver her." view_new_post: "Se ditt nye innlegg." saving: "Lagrer" saved: "Lagret!" @@ -1213,28 +1243,28 @@ nb_NO: yourself_confirm: title: "Glemte du å legge til mottagere?" body: "Nå sender du denne meldingen bare til deg selv!" - admin_options_title: "Valgfrie tråd-instillinger for stab" + admin_options_title: "Valgfrie emne-instillinger for stab" composer_actions: reply_to_post: label: "Svar på innlegg %{postNumber} av %{postUsername}" desc: Svar på et spesifikt innlegg reply_as_new_topic: - label: Svar med lenket tråd - desc: Opprette ny tråd lenket til denne tråden + label: Svar med lenket emne + desc: Opprette nytt emne lenket til dette emnet reply_as_private_message: label: Ny melding desc: Opprett en ny personlig melding reply_to_topic: - label: Svar på tråd - desc: "Svar på tråd, ikke et spesifikt innlegg " + label: Svar på emnet + desc: "Svar på emnet, ikke et spesifikt innlegg " toggle_whisper: label: Veksle visking desc: Hvisking er kun synlig for stab create_topic: - label: "Nytt tråd" + label: "Nytt Emne" shared_draft: label: "Delt kladd" - desc: "Lag en kladdetråd som kun er synlig for staben" + desc: "Lag et emneutkast som kun er synlig for staben" notifications: tooltip: regular: @@ -1243,7 +1273,7 @@ nb_NO: message: one: Én ulest melding other: '{{count}} uleste meldinger' - title: "varsler om at @navnet ditt blir nevnt, svar på dine innlegg og tråder, meldinger, osv" + title: "varsler om at @navnet ditt blir nevnt, svar på dine innlegg og emner, meldinger, osv" none: "Notifikasjoner er ikke tilgjengelig for øyeblikket." empty: "Ingen varsler funnet." more: "se gamle varsler" @@ -1267,7 +1297,7 @@ nb_NO: linked: "{{username}} {{description}}" granted_badge: "Gjorde seg fortjent til '{{description}}'" topic_reminder: "{{username}} {{description}}" - watching_first_post: "Ny tråd {{description}}" + watching_first_post: "Nytt Emne {{description}}" group_message_summary: one: '{{count}} melding i din {{group_name}} innboks' other: '{{count}} meldinger i din innboks for {{group_name}}' @@ -1279,6 +1309,8 @@ nb_NO: posted: '{{username}} skrev noe i "{{topic}}" - {{site_title}}' private_message: '{{username}} sendte deg en personlig melding i "{{topic}}" - {{site_title}}' linked: '{{username}} lenket til innlegget ditt i "{{topic}}" - {{site_title}}' + confirm_title: 'Varslinger aktivert - %{site_title}' + confirm_body: 'Suksess! Varslinger er nå aktivert.' upload_selector: title: "Legg til bilde" title_with_attachments: "Legg til et bilde eller en fil" @@ -1298,13 +1330,17 @@ nb_NO: sort_by: "Sorter etter" relevance: "Relevanse" latest_post: "Siste innlegg" - latest_topic: "Siste tråd" + latest_topic: "Siste Emne" most_viewed: "Mest Lest" most_liked: "Mest Likt" select_all: "Velg alle" clear_all: "Fjern Alle" too_short: "Din søketekst er for kort." - title: "søk etter tråder, innlegg, brukere eller kategorier" + result_count: + one: 1 resultat for{{term}} + other: {{count}}{{plus}} resultater for{{term}} + title: "søk etter emner, innlegg, brukere eller kategorier" + full_page_title: "søk etter emner eller innlegg" no_results: "Ingen resultater funnet." no_more_results: "Ingen flere resultater funnet." searching: "Søker…" @@ -1312,7 +1348,7 @@ nb_NO: results_page: "Søkeresultater for \"{{term}}\"" more_results: "Det finnes flere resultater. Begrens søket ditt." cant_find: "Finner du ikke det du leter etter?" - start_new_topic: "Kanskje opprette en ny tråd?" + start_new_topic: "Kanskje du kan starte et nytt emne?" or_search_google: "Eller prøv å søke på Google istedenfor:" search_google: "Prøv å søke på Google istedenfor:" search_google_button: "Google" @@ -1320,7 +1356,7 @@ nb_NO: context: user: "Søk i innleggene av @{{username}}" category: "Søk i kategorien #{{category}}" - topic: "Søk i denne tråden" + topic: "Søk i dette emnet" private_messages: "Søk i meldinger" advanced: title: Avansert søk @@ -1335,7 +1371,8 @@ nb_NO: with_tags: label: Merket filters: - label: Vis bare tråder/innlegg… + label: Vis bare emner/innlegg… + title: Kun treff i titler likes: Jeg likte posted: jeg skrev innlegg i watching: Jeg følger @@ -1351,7 +1388,7 @@ nb_NO: images: inkluder bilde(r) all_tags: Alle stikkord nevnt ovenfor statuses: - label: Hvor tråder + label: Hvor emner open: er åpen closed: er lukket archived: er arkivert @@ -1364,7 +1401,7 @@ nb_NO: label: Skrevet before: før after: etter - hamburger_menu: "gå til en annen liste over tråder eller en annen kategori" + hamburger_menu: "gå til en annen liste over emner eller en annen kategori" new_item: "ny" go_back: 'gå tilbake' not_logged_in_user: 'brukerside med oppsummering av nåværende aktivtet og preferanser.' @@ -1374,62 +1411,63 @@ nb_NO: bulk: select_all: "Velg alle" clear_all: "Fjern alle" - unlist_topics: "Fjern tråder fra lister" - relist_topics: "Før opp igjen tråder i lister" + unlist_topics: "Fjern Emner fra Lister" + relist_topics: "Før opp igjen Emner i Lister" reset_read: "Nullstill lest" - delete: "Slett tråder" + delete: "Slett Emner" dismiss: "Avslå" dismiss_read: "Forkast alle uleste" dismiss_button: "Forkast…" - dismiss_tooltip: "Forkast kun nye innlegg eller slutt å overvåke tråder" - also_dismiss_topics: "Slutt å overvåke disse trådene slik at de aldri igjen vises til meg som ulest" + dismiss_tooltip: "Forkast kun nye innlegg eller slutt å overvåke emner" + also_dismiss_topics: "Slutt å overvåke disse emnene slik at de aldri igjen vises til meg som ulest" dismiss_new: "Forkast nye" - toggle: "slå på/av massevelging av tråder" + toggle: "slå på/av massevelging av emner" actions: "Massehandlinger" change_category: "Velg kategori" - close_topics: "Lukk tråder" - archive_topics: "Arkiver tråder" + close_topics: "Lukk Emner" + archive_topics: "Arkiver Emner" notification_level: "Varsler" - choose_new_category: "Velg den nye kategorien for trådene:" + choose_new_category: "Velg den nye kategorien for emnene:" selected: - one: Du har valgt 1 tråd. - other: Du har valgt {{count}} tråder. + one: Du har valgt 1 emne. + other: Du har valgt {{count}} emner. change_tags: "Erstatt stikkord" append_tags: "Legg til stikkord" - choose_new_tags: "Velg nye stikkord for disse trådene:" - choose_append_tags: "Velg nye stikkord å legge til disse trådene:" - changed_tags: "Stikkordene for de trådene ble endret." + choose_new_tags: "Velg nye stikkord for følgende emner:" + choose_append_tags: "Velg nye stikkord å legge til følgende emner:" + changed_tags: "Stikkordene for de valgte emnene ble endret." none: - unread: "Du har ingen uleste tråder." - new: "Du har ingen nye tråder å lese." - read: "Du har ikke lest noen tråder ennå." - posted: "Du har ikke skrevet innlegg i noen tråder ennå." - latest: "Det finnes ingen siste tråder. Det var synd." - hot: "Det finnes ingen populære tråder." - bookmarks: "Du har ingen bokmerkede tråder ennå." - category: "Det finnes ingen {{category}}-tråder." - top: "Det finnes ingen populære tråder." + unread: "Du har ingen uleste emner." + new: "Du har ingen nye emner å lese." + read: "Du har ikke lest noen emner enda." + posted: "Du har ikke skrevet innlegg i noen emner enda." + latest: "Det finnes ingen siste emner. Det er sørgelig." + hot: "Det finnes ingen populære emner." + bookmarks: "Du har ingen bokmerkede emner enda." + category: "Det finnes ingen {{category}}-emner." + top: "Det finnes ingen populære emner." search: "Det finnes ingen søkeresultater" educate: - new: '

    Dine nye tråder vil vises her.

    Som forvalg anses tråder som nye og viser enny-indikator hvis de be opprettet i løpet av de siste 2 dagene.

    Gå til innstillinger for å endre dette.

    ' - unread: '

    Dine uleste tråder vil vises her.

    Som forvalg anses tråder som ulest og vil vise ulest-tall 1 dersom du:

    • Opprettet tråden
    • Svarte på tråden
    • Leste tråden i mer enn 4 minutter

    Eller dersom du uttrykkelig har satt tråden som overvåkes eller følges via varselkontrollen nederst i hver tråd.

    Gå tilinnstillingene dine for å endre dette.

    ' + new: '

    Dine nye emner vil vises her.

    Som forvalg anses emner som nye og viser enny-indikator hvis de be opprettet i løpet av de siste 2 dagene.

    Gå til innstillinger for å endre dette.

    ' + unread: '

    Dine uleste emner vil vises her.

    Som forvalg anses emner som ulest og vil vise ulest-tall 1 dersom du:

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

    Eller dersom du uttrykkelig har satt emnet som overvåkes eller følges via varselkontrollen nederst i hvert emne.

    Gå tilinnstillingene dine for å endre dette.

    ' bottom: - latest: "Det finnes ingen flere siste tråder." - hot: "Det finnes ingen flere populære tråder." - posted: "Det finnes ingen flere tråder med innlegg." - read: "Det finnes ingen flere leste tråder." - new: "Det finnes ingen flere nye tråder." - unread: "Det finnes ingen flere uleste tråder." - category: "Det finnes ingen {{category}}-tråder igjen." - top: "Det finnes ingen flere populære tråder." - bookmarks: "Det finnes ingen flere bokmerkede tråder." + latest: "Det finnes ingen flere siste emner." + hot: "Det finnes ingen flere populære emner." + posted: "Det finnes ingen flere emner med innlegg." + read: "Det finnes ingen flere leste emner." + new: "Det finnes ingen flere nye emner." + unread: "Det finnes ingen flere uleste emner." + category: "Det finnes ingen {{category}}-emner igjen." + top: "Det finnes ingen flere populære emner." + bookmarks: "Det finnes ingen flere bokmerkede emner." search: "Det finnes ingen flere søkeresultater" topic: filter_to: - one: 1 innlegg i tråd - other: '{{count}} innlegg i tråd' - create: 'Ny tråd' - create_long: 'Opprett et ny tråd' + one: 1 innlegg i emnet + other: '{{count}} innlegg i emnet' + create: 'Nytt Emne' + create_long: 'Opprett et nytt Emne' + open_draft: "Åpne Utkast" private_message: 'Begynn en melding' archive_message: help: 'Flytt meldinger til arkivet ditt' @@ -1438,61 +1476,62 @@ nb_NO: title: 'Flytt til innboks' help: 'Flytt melding tilbake til innboks' edit_message: + help: 'Rediger første innlegg i meldingen' title: 'Rediger melding' - list: 'Tråder' - new: 'ny tråd' + list: 'Emner' + new: 'nytt emne' unread: 'ulest' new_topics: - one: Ett ny tråd - other: '{{count}} nye tråder' + one: Ett nytt emne + other: '{{count}} nye emner' unread_topics: - one: Ett ulest tråd - other: '{{count}} uleste tråder' - title: 'Tråd' + one: Ett ulest emne + other: '{{count}} uleste emner' + title: 'Emne' invalid_access: - title: "Tråden er privat" - description: "Beklager, du har ikke tilgang til den tråden!" - login_required: "Du må være innlogget for å lese den tråden." + title: "Emnet er privat" + description: "Beklager, du har ikke tilgang til det emnet!" + login_required: "Du må være innlogget for å lese det emnet." server_error: - title: "Tråden kunne ikke lastes inn." - description: "Beklager, vi kunne ikke laste inn den tråden, muligens på grunn av et tilkoblingsproblem. Prøv igjen. Dersom problemet vedvarer, gi beskjed til oss." + title: "Emnet kunne ikke lastes inn." + description: "Beklager, vi kunne ikke laste inn det emnet, muligens på grunn av et tilkoblingsproblem. Prøv igjen. Dersom problemet vedvarer, gi beskjed til oss." not_found: - title: "Tråd ikke funnet" - description: "Beklager, vi kunne ikke finne den tråden. Kanskjer den ble fjernet av en moderator?" + title: "Fant ikke emnet" + description: "Beklager, vi kunne ikke finne det emnet. Kanskje det ble fjernet av en moderator?" total_unread_posts: one: du har 1 ulest innlegg i dette emnet - other: du har {{count}} uleste innlegg i denne tråden + other: du har {{count}} uleste innlegg i dette emnet unread_posts: - one: du har 1 ulest gammelt innlegg i denne tråden - other: du har {{count}} uleste gamle innlegg i denne tråden + one: du har 1 ulest gammelt innlegg i dette emnet + other: du har {{count}} uleste gamle innlegg i dette emnet new_posts: - one: Det finnes 1 nytt innlegg i denne tråden siden sist du leste det - other: Det finnes {{count}} nye innlegg i denne tråden siden sist du leste det + one: det er 1 nytt innlegg i dette emnet siden sist du leste det + other: det er {{count}} nye innlegg i dette emnet siden sist du leste det likes: - one: det er én like i denne tråden - other: det er {{number}} likes i denne tråden - back_to_list: "Tilbake til listen over tråder" - options: "Valg for tråder" - show_links: "vis lenker i denne tråden" - toggle_information: "vis/skjul detaljer for tråden" - read_more_in_category: "Vil du lese mer? Les andre tråder i {{catLink}} eller {{latestLink}}." + one: det er én like i dette emnet + other: det er {{number}} likes i dette emnet + back_to_list: "Tilbake til Listen over Emner" + options: "Valg for Emner" + show_links: "vis lenker i dette emnet" + toggle_information: "vis/skjul detaljer for emnet" + read_more_in_category: "Vil du lese mer? Les andre emner i {{catLink}} eller {{latestLink}}." read_more: "Vil du lese mer? {{catLink}} eller {{latestLink}}." - read_more_MF: "Det { UNREAD, plural, =0 {} one { finnes 1 unread } other { finnes # unread } } { NEW, plural, =0 {} one { {BOTH, select, true{og } false {finnes } other{}} 1 new tråd} other { {BOTH, select, true{og } false {er } other{}} # new tråder} } igjen, or {CATEGORY, select, true {se andre tråder i {catLink}} false {{latestLink}} other {}}" + read_more_MF: "Det { UNREAD, plural, =0 {} one { er 1 ulest } other { finnes # uleste } } { NEW, plural, =0 {} one { {BOTH, select, true{og } false {finnes } other{}} 1 nytt emne} other { {BOTH, select, true{og } false {er } other{}} # nye emner} } igjen, eller {CATEGORY, select, true {se andre emner i {catLink}} false {{latestLink}} other {}}" browse_all_categories: Se alle kategorier - view_latest_topics: se siste tråder - suggest_create_topic: "Hvorfor ikke opprette en tråd?" + view_latest_topics: se siste emner + suggest_create_topic: "Kanskje du kan lage et nytt emne?" jump_reply_up: hopp til tidligere svar jump_reply_down: hopp til senere svar - deleted: "Tråden er blitt slettet" + deleted: "Emnet ble slettet" topic_status_update: - title: "tidsbestemt handling for tråd" + title: "Tidsbestemt handling for emne" save: "Sett opp tidsbestemt handling" num_of_hours: "Antall timer:" remove: "Fjern tidsbestemt handling" publish_to: "Publiser til:" when: "Når:" - public_timer_types: Tidsbestemte handlinger for tråd - private_timer_types: Brukerstyrte tidsbestemte handlinger for tråd + public_timer_types: Tidsbestemte handlinger for emne + private_timer_types: Brukerstyrte tidsbestemte handlinger for emne auto_update_input: none: "Velg et tidsrom" later_today: "Senere i dag" @@ -1513,35 +1552,35 @@ nb_NO: temp_open: title: "Åpne midlertidig" auto_reopen: - title: "Automatisk åpning av tråd" + title: "Automatisk åpning av emne" temp_close: title: "Lukk midlertidig" auto_close: - title: "Automatisk lukking av tråd" - label: "Tidsbolk for automatisk lukking av tråd:" + title: "Automatisk lukking av emne" + label: "Tidsrom for automatisk lukking av emne:" error: "Skriv inn en gyldig verdi." - based_on_last_post: "Ikke lukk før det siste innlegget i tråden er minst så gammelt." + based_on_last_post: "Ikke lukk før det siste innlegget i emnet er minst så gammelt." auto_delete: - title: "Automatisk sletting av tråd" + title: "Automatisk sletting av emne" reminder: title: "Påminn meg" status_update_notice: - auto_open: "Denne tråden vil åpnes automatisk %{timeLeft}." - auto_close: "Denne tråden vil lukkes automatisk %{timeLeft}." - auto_publish_to_category: "Denne tråden vil bli opprettet i #%{categoryName} %{timeLeft}." - auto_close_based_on_last_post: "Denne tråden vil bli lukket %{duration} etter det siste innlegget." - auto_delete: "Denne tråden vil bli automatisk slettet %{timeLeft}." - auto_reminder: "Du vil bli påminnet om denne tråden %{timeLeft}." + auto_open: "Dette emnet vil åpnes automatisk %{timeLeft}." + auto_close: "Dette emnet vil lukkes automatisk %{timeLeft}." + auto_publish_to_category: "Dette emnet vil bli opprettet i #%{categoryName} %{timeLeft}." + auto_close_based_on_last_post: "Dette emnet vil bli lukket %{duration} etter det siste innlegget." + auto_delete: "Dette emnet vil bli automatisk slettet %{timeLeft}." + auto_reminder: "Du vil bli påminnet om dette emnet %{timeLeft}." auto_close_title: 'Auto-lukk innstillinger' auto_close_immediate: - one: Det siste innlegget i tråden er allerede en time gammelt, så tråden vil stenges umiddelbart. - other: Det siste innlegget i tråden er allerede %{count} timer gammelt, så tråden vil stenges umiddelbart. + one: Det siste innlegget i emnet er allerede en time gammelt, så emnet vil stenges umiddelbart. + other: Det siste innlegget i emnet er allerede %{count} timer gammelt, så emnet vil stenges umiddelbart. timeline: back: "Tilbake" back_description: "Gå tilbake til forrige uleste innlegg" replies_short: "%{current} / %{total}" progress: - title: fremgang i tråd + title: fremgang i emne go_top: "topp" go_bottom: "bunn" go: "gå" @@ -1553,36 +1592,36 @@ nb_NO: total: innlegg totalt current: gjeldende innlegg notifications: - title: endre hvor ofte du blir varslet om denne tråden + title: endre hvor ofte du blir varslet om dette emnet reasons: - mailing_list_mode: "Du har e-postlistemodus påslått, så du vil bli varslet på e-post om svar på denne tråden." - "3_10": 'Du vil motta varsler fordi du følger et stikkord for denne tråden' + mailing_list_mode: "Du har e-postlistemodus påslått, så du vil bli varslet på e-post om nye svar i dette emnet." + "3_10": 'Du vil motta varsler fordi du følger et stikkord for dette emnet.' "3_6": 'Du vil motta varsler fordi du følger denne kategorien' - "3_5": 'Du vil motta varsler fordi du startet å følge denne tråden automatisk.' - "3_2": 'Du vil motta varsler fordi du følger denne tråden' - "3_1": 'Du vil motta varsler fordi du opprettet denne tråden.' - "3": 'Du vil motta varsler fordi du følger denne tråden.' + "3_5": 'Du vil motta varsler fordi du startet å følge dette emnet automatisk.' + "3_2": 'Du vil motta varsler fordi du følger dette emnet.' + "3_1": 'Du vil motta varsler fordi du opprettet dette emnet.' + "3": 'Du vil motta varsler fordi du følger dette emnet.' "2_8": 'Du vil se antall nye svar fordi du følger denne kategorien.' - "2_4": 'Du vil se antall nye svar fordi du skrev et svar til denne tråden.' - "2_2": 'Du vil se antall nye svar fordi du overvåker denne tråden.' - "2": 'Du vil se antall nye svar fordi du leste denne tråden.' + "2_4": 'Du vil se antall nye svar fordi du skrev et svar i dette emnet.' + "2_2": 'Du vil se antall nye svar fordi du overvåker dette emnet.' + "2": 'Du vil se antall nye svar fordi du leste dette emnet.' "1_2": 'Du vil bli varslet om noen nevner @navnet ditt eller svarer på innlegget ditt.' "1": 'Du vil bli varslet om noen nevner @navnet ditt eller svarer på innlegget ditt.' "0_7": 'Du ignorerer alle varsler i denne kategorien.' - "0_2": 'Du ignorerer alle varsler om denne tråden.' - "0": 'Du ignorerer alle varsler om denne tråden.' + "0_2": 'Du ignorerer alle varsler om dette emnet.' + "0": 'Du ignorerer alle varsler om dette emnet.' watching_pm: title: "Følger" description: "Du vil bli varslet om hvert nye innlegg i denne meldingen. Antall nye tilbakemeldinger vil også bli vist. " watching: title: "Følger" - description: "Du vil bli varslet om hvert nytt innlegg i denne tråden, og antall nye svar vil også bli vist." + description: "Du vil bli varslet om hvert nytt innlegg i dette emnet, og antall nye svar vil også bli vist." tracking_pm: title: "Overvåker" description: "Antall nye tilbakemeldinger vil bli vist for denne meldingen. Du vil bli varslet om noen nevner ditt @name eller svarer på din melding. " tracking: title: "Overvåker" - description: "Antall nye svar vil bli vist for denne tråden. Du vil bli varslet dersom noen nevner @navnet ditt eller svarer på innlegget ditt." + description: "Antall nye svar vil bli vist for dette emnet. Du vil bli varslet dersom noen nevner @navnet ditt eller svarer på innlegget ditt." regular: title: "Normal" description: "Du vil bli varslet om noen nevner @navnet ditt eller svarer på innlegget ditt." @@ -1594,71 +1633,71 @@ nb_NO: description: "Du vil aldri bli varslet om noe vedrørende denne meldingnen. " muted: title: "Ignorert" - description: "Du vil aldri bli varslet om noe vedrørende denne tråden, og den vil ikke vises i siste." + description: "Du vil aldri bli varslet om noe vedrørende dette emnet, og det vil ikke vises i siste." actions: - recover: "Gjenopprett tråd" - delete: "Slett tråd" - open: "Åpne tråd" - close: "Lukk tråd" + recover: "Gjenopprett Emne" + delete: "Slett Emne" + open: "Åpne Emne" + close: "Lukk Emne" multi_select: "Velg innlegg…" - timed_update: "Sett opp tidsbestemt handling for tråd…" - pin: "Fest tråd…" - unpin: "Løsne tråd…" - unarchive: "Opphev arkivering av tråd" - archive: "Arkiver tråd" + timed_update: "Sett opp tidsbestemt handling for emne…" + pin: "Fest Emne…" + unpin: "Løsne Emne…" + unarchive: "Opphev arkivering av emne" + archive: "Arkiver Emne" invisible: "Skjul" visible: "Gjør synlig" reset_read: "Tilbakestill lesedata" - make_public: "Gjør til offentlig tråd" + make_public: "Gjør til Offentlig Emne" make_private: "Opprett personlig melding" feature: - pin: "Fest tråd" - unpin: "Løsne tråd" - pin_globally: "Fest tråd over alt" - make_banner: "Bannertråd" - remove_banner: "Fjern bannertråd" + pin: "Fest Emne" + unpin: "Løsne Emne" + pin_globally: "Fest Emne Globalt" + make_banner: "Banneremne" + remove_banner: "Fjern Banneremne" reply: title: 'Svar' - help: 'begynn å skrive et svar i denne tråden' + help: 'begynn å skrive et svar i dette emnet' clear_pin: title: "Løsne" - help: "Fjern festet-statusen til denne tråden slik at den ikke lenger vises øverst i listen din over tråder" + help: "Fjern festet-statusen til dette emnet slik at det ikke lenger vises øverst i listen din over emner" share: title: 'Del' - help: 'del en lenke til denne tråden' + help: 'del en lenke til dette emnet' print: title: 'Skriv ut' - help: 'Åpne en utskriftsvennlig utgave av denne tråden.' + help: 'Åpne en utskriftsvennlig utgave av dette emnet' flag_topic: title: 'Rapporter' help: 'rapporter dette innlegget privat eller send et privat varsel om det' - success_message: 'Du har rapportert denne tråden' + success_message: 'Du har rapportert dette emnet.' feature_topic: - title: "Fremhev denne tråden" - pin: "La denne tråden vises øverst i {{categoryLink}}-kategorien inntil" - confirm_pin: "Du har allerede {{count}} festede tråder. For mange festede tråder kan være et problem for nye og anonyme brukere. Er du sikker på at du ønsker å feste enda en tråd i denne kategorien?" - unpin: "Fjern denne tråden fra toppen av {{categoryLink}}-kategorien." - unpin_until: "Fjern denne tråden fra toppen av {{categoryLink}}-kategorien, eller vent til %{until}." - pin_note: "Brukere kan fjerne festet for tråden for seg selv." - pin_validation: "En dato kreves for å feste denne tråden." - not_pinned: "Det finnes ingen festede tråder i {{categoryLink}}." + title: "Fremhev denne emnet" + pin: "La dette emnet vises øverst i {{categoryLink}}-kategorien frem til" + confirm_pin: "Du har allerede {{count}} festede emner. For mange festede emner kan være slitsomt for nye og anonyme brukere. Er du sikker på at du ønsker å feste enda et emne i denne kategorien?" + unpin: "Fjern dette emnet fra toppen av {{categoryLink}}-kategorien." + unpin_until: "Fjern dette emnet fra toppen av {{categoryLink}}-kategorien, eller vent til %{until}." + pin_note: "Brukere kan fjerne festet for emnet individuelt for seg selv." + pin_validation: "En dato kreves for å feste dette emnet." + not_pinned: "Det finnes ingen festede emner i {{categoryLink}}." already_pinned: - one: 'Tråder for øyeblikket låst i {{categoryLink}}: Ett' - other: 'Tråder som er festet i {{categoryLink}} for øyeblikket: {{count}}' - pin_globally: "La denne tråden vises øverst i alle listene over tråder inntil" - confirm_pin_globally: "Du har allerede {{count}} globalt festede tråder. For mange festede tråder kan være et problem for nye og anonyme brukere. Er du sikker på at du vil feste enda en tråd globalt? " - unpin_globally: "Fjern denne tråden fra toppen av alle lister over tråder. " - unpin_globally_until: "Fjern denne tråden fra toppen av alle lister over tråder eller vent til %{until}." - global_pin_note: "Brukere kan fjerne festet for tråden for seg selv" - not_pinned_globally: "Det finnes ingen globalt festede tråder." + one: 'Emner som er festet i {{categoryLink}} for øyeblikket: 1' + other: 'Emner som er festet i {{categoryLink}} for øyeblikket: {{count}}' + pin_globally: "La dette emnet vises øverst i alle listene over emner inntil" + confirm_pin_globally: "Du har allerede {{count}} globalt festede emner. For mange festede emner kan være slitsomt for nye og anonyme brukere. Er du sikker på at du vil feste enda et emne globalt? " + unpin_globally: "Fjern dette emnet fra toppen av alle lister over emner." + unpin_globally_until: "Fjern dette emnet fra toppen av alle lister over emner eller vent til %{until}." + global_pin_note: "Brukere kan fjerne festet for emnet individuelt for seg selv." + not_pinned_globally: "Det finnes ingen globalt festede emner." already_pinned_globally: - one: 'Tråder for øyeblikket festet globalt: 1' - other: 'Tråder som er festet globalt for øyeblikket: {{count}}' - make_banner: "Gjør denne tråden til et banner som vises øverst på alle sider." + one: 'Emner som er festet globalt for øyeblikket: 1' + other: 'Emner som er festet globalt for øyeblikket: {{count}}' + make_banner: "Gjør dette emnet til et banner som vises øverst på alle sider." remove_banner: "Fjern banneret som vises øverst alle sider. " - banner_note: "Brukere kan fjerne banneret ved å lukke det. Kun én tråd kan være banner på et gitt tidspunkt. " - no_banner_exists: "Det finnes ingen bannertråd. " - banner_exists: "Det finnes en bannertråd for øyeblikket . " + banner_note: "Brukere kan fjerne banneret ved å lukke det. Kun ett emne kan være valgt som banner av gangen." + no_banner_exists: "Det er ikke valgt et banneremne. " + banner_exists: "Det finnes et banneremne allerede." inviting: "Inviterer…" automatically_add_to_groups: "Denne invitasjonen inkluderer også tilgang til disse gruppene:" invite_private: @@ -1670,23 +1709,23 @@ nb_NO: success_group: "Vi har invitert den gruppen til å delta i denne meldingen." error: "Beklager, det oppstod en feil ved å invitere den brukeren." group_name: "gruppenavn" - controls: "Handlinger for tråd" + controls: "Handlinger for Emne" invite_reply: title: 'Inviter' username_placeholder: "brukernavn" action: 'Send Invitasjon' - help: 'Inviter andre til denne tråden via e-post eller varsler' + help: 'Inviter andre til dette emnet via e-post eller varsler' to_forum: "Vi sender en kortfattet e-post som gjør det mulig for en venn å umiddelbart registreres ved å klikke på en lenke. Ingen innlogging er nødvendig." - sso_enabled: "Oppgi brukernavnet til personen du ønsker å invitere til denne tråden." - to_topic_blank: "Oppgi brukernavnet eller e-postadressen til personen du ønsker å invitere til denne tråden." - to_topic_email: "Du har oppgitt en e-postadresse. Vi vil sende en invitasjon som lar vennen din svare på denne tråden umiddelbart." - to_topic_username: "Du har oppgitt et brukernavn. Vi sender et varsel med en lenke som inviterer dem til denne tråden." - to_username: "Oppgi brukernavnet til personen du ønsker å invitere. Vi sender et varsel med en lenke som inviterer vedkommende til denne tråden." + sso_enabled: "Oppgi brukernavnet til personen du ønsker å invitere til dette emnet." + to_topic_blank: "Oppgi brukernavnet eller e-postadressen til personen du ønsker å invitere til dette emnet." + to_topic_email: "Du har oppgitt en e-postadresse. Vi vil sende en invitasjon som lar vennen din svare på dette emnet umiddelbart." + to_topic_username: "Du har oppgitt et brukernavn. Vi sender et varsel med en lenke som inviterer dem til dette emnet." + to_username: "Oppgi brukernavnet til personen du ønsker å invitere. Vi sender et varsel med en lenke som inviterer vedkommende til dette emnet." email_placeholder: 'navn@example.com' success_email: "Vi har sendt ut en invitasjon til {{emailOrUsername}}. Vi varsler deg når invitasjonen er godtatt. Sjekk invitiasjonsfanen på brukersiden din for å beholde oversikten over invitasjonene dine." - success_username: "Vi har invitert den brukeren til å delta i denne tråden." + success_username: "Vi har invitert den valgte brukeren til å delta i dette emnet." error: "Beklager, vi kunne ikke invitere den brukeren. Vedkommende har muligens allerede blitt invitert? (Antall invitasjoner er begrenset)" - success_existing_email: "En bruker med e-postadressen {{emailOrUsername}} finnes allerede. Vi har invitert den brukeren til å ta del i tråden." + success_existing_email: "En bruker med e-postadressen {{emailOrUsername}} finnes allerede. Vi har invitert brukeren til å delta i dette emnet." login_reply: 'Logg Inn for å svare' filters: n_posts: @@ -1694,20 +1733,20 @@ nb_NO: other: '{{count}} innlegg' cancel: "Fjern filter" split_topic: - title: "Flytt til ny tråd" - action: "flytt til ny tråd" - topic_name: "Nytt navn på tråden" - error: "Det oppstod en feil ved flytting av innlegg til den nye tråden." + title: "Flytt til Nytt Emne" + action: "flytt til nytt emne" + topic_name: "Nytt Navn på Emne" + error: "Det oppstod en feil ved flytting av innlegg til det nye emnet." instructions: - one: Du er i ferd med å lage et ny tråd basert på innlegget du har valgt.. - other: Du er i ferd med å opprette et ny tråd og fylle den med de {{count}} innleggne du har valgt. + one: Du er i ferd med å opprette et nytt emne basert på innlegget du har valgt.. + other: Du er i ferd med å opprette et nytt emne og fylle det med de {{count}} innleggene du har valgt. merge_topic: - title: "Flytt til eksisterende tråd" - action: "flytt til eksisterende tråd" - error: "Det oppstod en feil ved flytting av innlegg til den tråden" + title: "Flytt til Eksisterende Emne" + action: "flytt til eksisterende emne" + error: "Det oppstod en feil ved flytting av innlegg til det valgte emnet." instructions: - one: Velg den tråden du vil flytte det innlegget til. - other: Velg tråden du vil flytte de {{count}} innleggene til. + one: Velg emnet du vil flytte dette innlegget til. + other: Velg emnet du vil flytte de {{count}} innleggene til. merge_posts: title: "Slå sammen valgte innlegg" action: "slå sammen valgte innlegg" @@ -1721,12 +1760,13 @@ nb_NO: instructions: one: Velg den nye eieren til innlegget av {{old_user}}. other: Velg den nye eieren til {{count}} innlegg av {{old_user}}. + instructions_warn: "Merk at varslinger bakover i tid for dette innlegget ikke vil bli overført til den nye brukeren." change_timestamp: title: "Endre tidsstempel…" action: "endre tidsstempel" invalid_timestamp: "Tidsstempel kan ikke være i fremtiden." - error: "Det oppstod en feil ved endring av tidsstempel for tråden." - instructions: "Vennligst velg det nye tidsstempelet for tråden. Innlegg i tråden blir oppdatert med samme tidsforskjell." + error: "Det oppstod en feil ved endring av tidsstempel for emnet." + instructions: "Vennligst velg det nye tidsstempelet for emnet. Innlegg i emnet blir oppdatert med samme tidsforskjell." multi_select: select: 'velg' selected: 'valgte ({{count}})' @@ -1756,7 +1796,7 @@ nb_NO: post_number: "innlegg {{number}}" wiki_last_edited_on: "wikien sist redigert" last_edited_on: "innlegg sist redigert" - reply_as_new_topic: "Svar med lenket tråd" + reply_as_new_topic: "Svar med lenket Emne" reply_as_new_private_message: "Svar som ny melding til de samme mottakerne" continue_discussion: "Fortsetter diskusjonen fra {{postLink}}:" follow_quote: "gå til det siterte innlegget" @@ -1974,10 +2014,10 @@ nb_NO: choose: 'Velg en katekori…' edit: 'rediger' edit_long: "Rediger" - view: 'Se tråder i kategori' + view: 'Se Emner i Kategori' general: 'Generelt' settings: 'Innstillinger' - topic_template: "Mal for tråd" + topic_template: "Mal for Emne" tags: "Stikkord" tags_allowed_tags: "Bare tillat disse etikettene brukt i denne kategorien:" tags_allowed_tag_groups: "Bare tillat stikkord fra disse gruppene å bli brukt i denne kategorien:" @@ -1994,7 +2034,7 @@ nb_NO: save_error: Det oppstod en feil ved lagrinen av denne kategorien. name: "Kategorinavn" description: "Beskrivelse" - topic: "kategoritråd" + topic: "kategoriemne" logo: "Kategoribilde" background_image: "Kategoriens bakgrunnsbilde" badge_colors: "Merkefarger" @@ -2013,17 +2053,17 @@ nb_NO: images: "Bilder" email_in: "Egendefinert innkommende e-postadresse:" email_in_allow_strangers: "Godta e-post fra anonyme brukere uten brukerkonto" - email_in_disabled: "Publisering av nye tråder via e-post er deaktivert i innstillingene for nettstedet. For å aktivere publisering av nye tråder via e-post," + email_in_disabled: "Publisering av nye emner via e-post er deaktivert i innstillingene for nettstedet. For å aktivere publisering av nye emner via e-post," email_in_disabled_click: 'aktiver innstillingen "e-post inn".' mailinglist_mirror: "Kategorien gjenspeiler en e-postliste" - suppress_from_latest: "Utelat denne kategorien fra siste tråder." - show_subcategory_list: "Vis listen over underkategorier over tråder i denne kategorien." - num_featured_topics: "Antall tråder vist på kategori-siden:" - subcategory_num_featured_topics: "Antall fremhevede tråder på overkategoriens side:" - all_topics_wiki: "Gjør nye tråder til wiki-er som forvalg." + suppress_from_latest: "Utelat denne kategorien fra siste emner." + show_subcategory_list: "Plasser listen over underkategorien i toppen av emner i denne kategorien." + num_featured_topics: "Antall emner som skal vises på kategori-siden:" + subcategory_num_featured_topics: "Antall fremhevede emner på hovedkategoriens side:" + all_topics_wiki: "Gjør nye emner til wiki-er som standard." subcategory_list_style: "Listestil for underkategorier:" - sort_order: "Sorter liste over tråder etter:" - default_view: "Forvalgt liste over tråder:" + sort_order: "Emneliste Sorteres Etter:" + default_view: "Forvalgt Emneliste:" default_top_period: "Forvalgt topp-periode:" allow_badges_label: "Tillat merker å bli tildelt i denne kategorien" edit_permissions: "Rediger tillatelser" @@ -2033,23 +2073,24 @@ nb_NO: default_position: "Forvalgt posisjon" position_disabled: "Kategorier vil bli vist i henhold til aktivitet. For å styre rekkefølgen av kategorier i listen" position_disabled_click: 'aktiver innstillingen "faste kategoriposisjoner".' + minimum_required_tags: 'Minste antall stikkord som kreves for et emne:' parent: "Foreldrekategori" notifications: watching: title: "Følger" - description: "Du vil automatisk følge alle trådene i disse kategoriene. Du vil bli varslet om hvert nye innlegg i hver tråd, og antall nye svar vil bli vist." + description: "Du vil automatisk følge alle emnene i disse kategoriene. Du vil bli varslet om alle nye innlegg i hvert emne, og antall nye svar vil bli vist." watching_first_post: title: "Følger første innlegg" - description: "Du vil bare bli varslet om det første innlegget i hver nye tråd i disse kategoriene." + description: "Du vil bare bli varslet om det første innlegget i hvert nye emne i disse kategoriene." tracking: title: "Overvåkning" - description: "Du vil automatisk overvåke alle tråder i disse kategoriene. Du vil bli varslet dersom noen nevner @navnet ditt eller svarer deg, og antallet nye svar vil bli vist." + description: "Du vil automatisk overvåke alle emner i disse kategoriene. Du vil bli varslet dersom noen nevner @navnet ditt eller svarer deg, og antallet nye svar vil bli vist." regular: title: "Normal" description: "Du vil bli varslet om noen nevner @navnet ditt eller svarer deg." muted: title: "Ignorert" - description: "Du vil aldri bli varslet om noe vedrørende nye tråder i disse kategoriene, og de vil ikke vises i siste." + description: "Du vil aldri bli varslet om noe vedrørende nye emner i disse kategoriene, og de vil ikke vises i listen over siste." sort_options: default: "forvalg" likes: "Likes" @@ -2064,9 +2105,9 @@ nb_NO: sort_descending: 'Synkende' subcategory_list_styles: rows: "Rader" - rows_with_featured_topics: "Rader med fremhevede tråder" + rows_with_featured_topics: "Rader med fremhevede emner" boxes: "Bokser" - boxes_with_featured_topics: "Bokser med fremhevede tråder" + boxes_with_featured_topics: "Bokser med fremhevede emner" flagging: title: 'Takk for at du hjelper å holde forumet ryddig!' action: 'Rapporter innlegg' @@ -2074,7 +2115,7 @@ nb_NO: notify_action: 'Melding' official_warning: 'Offisiell advarsel' delete_spammer: "Slett spammer" - delete_confirm_MF: "Du er i ferd med å slette {POSTS, plural, one {1 innlegg} other {# innlegg}} og {TOPICS, plural, one {1 tråd} other {# tråder}} opprettet av denne brukeren, fjerne kontoen, blokkere påmeldinger fra IP-adressen {ip_address}, og legge til e-postadressen {email} til en permanent blokkeringsliste. Er du sikker på at denne brukeren virkelig sender søppelpost?" + delete_confirm_MF: "Du er i ferd med å slette {POSTS, plural, one {1 innlegg} other {# innlegg}} og {TOPICS, plural, one {1 emne} other {# emner}} opprettet av denne brukeren, fjerne kontoen, blokkere påmeldinger fra IP-adressen {ip_address}, og legge til e-postadressen {email} til en permanent blokkeringsliste. Er du sikker på at denne brukeren virkelig sender søppelpost?" yes_delete_spammer: "Ja, slett spammer" ip_address_missing: "(N/A)" hidden_email_address: "(skjult)" @@ -2100,10 +2141,10 @@ nb_NO: other: '{{count}} gjenstående' flagging_topic: title: "Takk for at du hjelper med å vedlikeholde god skikk i samfundet vårt!" - action: "Rapporter tråd" + action: "Rapporter Emne" notify_action: "Melding" topic_map: - title: "Oppsummering av tråd" + title: "Oppsummering av Emne" participants_title: "Hyppige innleggsskrivere" links_title: "Populære Lenker" links_shown: "vis flere lenker…" @@ -2119,28 +2160,28 @@ nb_NO: warning: help: "Dette er en offisiell advarsel." bookmarked: - help: "Du bokmerket denne tråden" + help: "Du bokmerket dette emnet" locked: - help: "denne tråden er låst; den aksepterer ikke lenger nye svar" + help: "Dette emnet er stengt; det er ikke mulig å skrive nye svar" archived: - help: "denne tråden er arkivert; den er fryst og kan ikke bli endret" + help: "Dette emnet er arkivert; det er frosset og kan ikke lenger endres" locked_and_archived: - help: "Denne tråden er lukket og arkivert; den godtar ikke lenger nye innlegg og kan ikke endres" + help: "Dette emnet er både lukket og arkivert; det er ikke mulig å skrive nye svar eller endre på det" unpinned: title: "Feste fjernet" help: "Denne ble løsnet for deg; den vil vises i vanlig rekkefølge" pinned_globally: title: "Globalt fastsatt" - help: "Denne tråden er festet globalt; den vil vises øverst i seneste og sin kategori" + help: "Dette emnet er festet globalt; det vil vises øverst i siste og listen for emnets kategori" pinned: title: "Fastsatt" - help: "Denne tråden er festet for deg; det vil vises øverst i sin kategori" + help: "Dette emnet er festet for deg; det vil vises øverst i sin kategori" invisible: - help: "Denne tråden er ikke synlig; den vil ikke vises i lister over tråder, og er kun tilgjengelig via en direkte lenke" + help: "Dette emnet er ikke synlig; det vil ikke vises i lister over emner, og er kun tilgjengelig via en direkte lenke" posts: "Innlegg" - posts_long: "det finnes {{number}} innlegg i denne tråden" + posts_long: "det er {{number}} innlegg i dette emnet" posts_likes_MF: | - Denne tråden har {count, plural, one {1 svar} other {# svar}} {ratio, select, + Dette emnet har {count, plural, one {1 svar} other {# svar}} {ratio, select, low {med mange likes i forhold til innlegg} med {med veldig mange likes i forhold til innlegg} high {med ekstremt mange likes i forhold til innlegg} @@ -2152,14 +2193,14 @@ nb_NO: other: visninger replies: "Svar" views_long: - one: denne tråden er vist 1 gang - other: denne tråden er blitt vist {{number}} ganger + one: dette emnet er lest 1 gang + other: dette emnet er lest {{number}} ganger activity: "Aktivitet" likes: "Likes" likes_lowercase: one: like other: likes - likes_long: "det finnes {{number}} likes i denne tråden" + likes_long: "det finnes {{number}} likes i dette emnet" users: "Deltakere" users_lowercase: one: bruker @@ -2172,33 +2213,33 @@ nb_NO: not_available: "Ikke tilgjengelig!" categories_list: "Kategoriliste" filters: - with_topics: "%{filter} tråder" - with_category: "%{filter} %{category} tråder" + with_topics: "%{filter} emner" + with_category: "%{filter} %{category} emner" latest: title: "Siste" title_with_count: one: Siste (1) other: Siste ({{count}}) - help: "tråder med nylige innlegg" + help: "emner med nylige innlegg" hot: title: "Populær" - help: "et utvalg av de mest populære trådene" + help: "et utvalg av de mest populære emnene" read: title: "Lest" - help: "tråder du har lest, i den rekkefølgen du sist leste dem" + help: "emner du har lest, i den rekkefølgen du sist leste dem" search: title: "Søk" - help: "Søk i alle tråder" + help: "søk i alle emner" categories: title: "Kategorier" title_in: "Kategori - {{categoryName}}" - help: "alle tråder sortert etter kategori" + help: "alle emner sortert etter kategori" unread: title: "Uleste" title_with_count: one: Ulest (1) other: Ulest ({{count}}) - help: "tråder du følger eller overvåker for øyeblikket, med uleste innlegg" + help: "emner du følger eller overvåker for øyeblikket, med uleste innlegg" lower_title_with_count: one: 1 ulest other: '{{count}} uleste' @@ -2211,22 +2252,22 @@ nb_NO: title_with_count: one: Nye (1) other: Nye ({{count}}) - help: "tråder opprettet de siste dagene" + help: "emner opprettet de siste dagene" posted: title: "Mine innlegg" - help: "tråder du har bidratt med innlegg i" + help: "emner du har bidratt med innlegg i" bookmarks: title: "Bokmerker" - help: "tråder du har bokmerket" + help: "emner du har bokmerket" category: title: "{{categoryName}}" title_with_count: one: '{{categoryName}} (1)' other: '{{categoryName}} ({{count}})' - help: "siste tråder i {{categoryName}}-kategorien" + help: "siste emner i {{categoryName}}-kategorien" top: title: "Aktive" - help: "de mest aktive trådene det siste året, den siste måneden, uken eller dagen " + help: "de mest aktive emnene det siste året, den siste måneden, uken eller dagen " all: title: "Totalt" yearly: @@ -2271,31 +2312,31 @@ nb_NO: jump: '# Gå til innlegg #' back: 'u Tilbake' up_down: 'k/j Flytt utvalg ↑ ↓' - open: 'o eller Enter Åpne valgt tråd' + open: 'o eller Enter Åpne valgt emne' next_prev: 'shift+j/shift+k Neste/forrige del' application: title: 'Applikasjon' - create: 'c Opprett ny tråd' + create: 'c Opprett nytt emne' notifications: 'n Åpne varsler' hamburger_menu: '= Åpne hamburgermeny' user_profile_menu: 'p Åpne brukermenyen' - show_incoming_updated_topics: '. Vis oppdaterte tråder' + show_incoming_updated_topics: '. Vis oppdaterte emner' search: '/ eller Ctrl+Alt+f Søk' help: '? Åpne tastaturhjelp' dismiss_new_posts: 'x, r Forkast Nye/Innlegg' - dismiss_topics: 'x, t Forkast tråder' + dismiss_topics: 'x, t Forkast Emner' log_out: 'shift+z shift+z Logg ut' composing: title: 'Skriving' return: 'shift+c Gå tilbake til redigeringspanelet' actions: title: 'Handlinger' - bookmark_topic: 'f Legg til/fjern bokmerke for tråd' - pin_unpin_topic: 'shift+p Fest/fjern feste for tråd' - share_topic: 'shift+s Del tråd' + bookmark_topic: 'f Legg til/fjern bokmerke for emne' + pin_unpin_topic: 'shift+p Fest/fjern feste for emne' + share_topic: 'shift+s Del emne' share_post: 's Del innlegg' - reply_as_new_topic: 't Svar som lenket tråd' - reply_topic: 'shift+r Svar på tråd' + reply_as_new_topic: 't Svar som lenket emne' + reply_topic: 'shift+r Svar på emne' reply_post: 'r Svar på innlegg' quote_post: 'q Siter innlegg' like: 'l Lik innlegg' @@ -2303,11 +2344,11 @@ nb_NO: bookmark: 'b Bokmerk innlegg' edit: 'e Rediger innlegg' delete: 'd Slett innlegg' - mark_muted: 'm, m Ignorer tråden' - mark_regular: 'm, r Vanlig (forvalgt) tråd' - mark_tracking: 'm, t Overvåk tråd' - mark_watching: 'm, w Følg tråd' - print: 'ctrl+p Skriv ut tråd' + mark_muted: 'm, m Ignorer emne' + mark_regular: 'm, r Vanlig (forvalgt) emne' + mark_tracking: 'm, t Overvåk emne' + mark_watching: 'm, w Følg emne' + print: 'ctrl+p Skriv ut emne' badges: earned_n_times: one: Har gjort seg fortjent til dette merket @@ -2359,8 +2400,8 @@ nb_NO: choose_for_topic: "valgfrie stikkord" delete_tag: "Slett stikkord" delete_confirm: - one: Er du sikker på at du ønsker å slette dette stikkordet og fjerne det fra tråden det er tilknyttet? - other: Er du sikker på at du ønsker å slette dette stikkordet og fjerne det fra {{count}} tråder som har det? + one: Er du sikker på at du ønsker å slette dette stikkordet og fjerne det fra emnet det er tilknyttet? + other: Er du sikker på at du ønsker å slette dette stikkordet og fjerne det fra {{count}} emner som er tilknyttet det? delete_confirm_no_topics: "Er du sikker på at du ønsker å slette dette stikkordet?" rename_tag: "Gi stikkord nytt navn" rename_instructions: "Velg et nytt navn for dette stikkordet:" @@ -2370,26 +2411,26 @@ nb_NO: manage_groups: "Behandle stikkordgrupper" manage_groups_description: "Definer grupper for å organisere stikkord" filters: - without_category: "%{filter} %{tag} tråder" - with_category: "%{filter} %{tag} tråder i %{category}" - untagged_without_category: "%{filter} tråder uten stikkord" - untagged_with_category: "%{filter} tråder uten stikkord i %{category}" + without_category: "%{filter} %{tag} emner" + with_category: "%{filter} %{tag} emner i %{category}" + untagged_without_category: "%{filter} emner uten stikkord" + untagged_with_category: "%{filter} emner uten stikkord i %{category}" notifications: watching: title: "Følger" - description: "Du vil automatisk følge alle trådene med dette stikkordet. Du vil bli varslet om alle nye innlegg og tråder; i tillegg vil antallet uleste og nye innlegg vises ved siden av tråden." + description: "Du vil automatisk følge alle emnene med dette stikkordet. Du vil bli varslet om alle nye innlegg og emner; i tillegg vil antallet uleste og nye innlegg vises ved siden av emnet." watching_first_post: title: "Følger første innlegg" - description: "Du vil bare bli varslet om det første innlegget i hver nye tråd med dette stikkordet." + description: "Du vil bare bli varslet om det første innlegget i hvert nye emne med dette stikkordet." tracking: title: "Overvåkning" - description: "Du vil automatisk overvåke alle tråder med dette stikkordet. Antallet uleste og nye innlegg vil vises ved siden av tråden." + description: "Du vil automatisk overvåke alle emner med dette stikkordet. Antallet uleste og nye innlegg vil vises ved siden av emnet." regular: title: "Aktivt medlem" description: "Du vil bli varslet hvis noen nevner @navnet ditt eller svarer på innlegget ditt." muted: title: "Ignorert" - description: "Du vil ikke bli varslet om noe vedrørende nye tråder med dette stikkordet, og de vil ikke vises i ulest-listen din." + description: "Du vil ikke bli varslet om noe vedrørende nye emner med dette stikkordet, og de vil ikke vises i ulest-listen din." groups: title: "Stikkordgrupper" about: "Legg stikkord til grupper for å kunne organisere dem enklere." @@ -2398,38 +2439,42 @@ nb_NO: parent_tag_label: "Overordnet stikkord:" parent_tag_placeholder: "Valgfritt" parent_tag_description: "Stikkord fra denne gruppen kan ikke brukes med mindre det overordnede stikkordet er til stede." - one_per_topic_label: "Begrens til ett stikkord fra denne gruppen per tråd " + one_per_topic_label: "Begrens til ett stikkord fra denne gruppen per emne " new_name: "Ny stikkordgruppe" save: "Lagre" delete: "Slett" confirm_delete: "Er du sikker på at du vil slette denne stikkordgruppen?" + everyone_can_use: "Stikkord kan benyttes av alle" + usable_only_by_staff: "Stikkord er synlige for alle, men kun staben kan bruke dem" + visible_only_to_staff: "Stikkord er kun synlige for staben" topics: none: - unread: "Du har ingen uleste tråder." - new: "Du har ingen nye tråder." - read: "Du har ikke lest noen tråder ennå." - posted: "Du har ikke skrevet noe innlegg i tråder ennå." - latest: "Det finnes ingen flere siste tråder." - hot: "Det finnes ingen populære tråder." - bookmarks: "Du har ikke bokmerket noen tråder ennå." - top: "Det finnes ingen populære tråder." + unread: "Du har ingen uleste emner." + new: "Du har ingen nye emner." + read: "Du har ikke lest noen emner enda." + posted: "Du har ikke skrevet noe innlegg i emner enda." + latest: "Det finnes ingen flere siste emner." + hot: "Det finnes ingen populære emner." + bookmarks: "Du har ikke bokmerket noen emner ennå." + top: "Det finnes ingen populære emner." search: "Det finnes ingen søkeresultater." bottom: - latest: "Det finnes ingen flere siste tråder." - hot: "Det finnes ingen flere populære tråder." - posted: "Det finnes ingen flere tråder med innlegg." - read: "Det finnes ingen flere leste tråder." - new: "Det finnes ingen flere nye tråder." - unread: "Det finnes ingen flere uleste tråder." - top: "Det finnes ingen flere populære tråder." - bookmarks: "Det finnes ingen bokmerkede tråder." + latest: "Det finnes ingen flere siste emner." + hot: "Det finnes ingen flere populære emner." + posted: "Det finnes ingen flere emner med innlegg." + read: "Det finnes ingen flere leste emner." + new: "Det finnes ingen flere nye emner." + unread: "Det finnes ingen flere uleste emner." + top: "Det finnes ingen flere populære emner." + bookmarks: "Det finnes ingen bokmerkede emner." search: "Det finnes ingen flere søkeresultater" invite: custom_message: "Gjør din invitasjon litt mer personlig ved å skrive ett" custom_message_link: "egendefinert melding" custom_message_placeholder: "Skriv inn din egendefinerte melding" custom_message_template_forum: "Hei, du burde ta del i dette forumet!" - custom_message_template_topic: "Hei, jeg tenkte du ville like denne tråden!" + custom_message_template_topic: "Hei, jeg tenkte du ville like dette emnet!" + forced_anonymous: "På grunn av ekstrem belastning vises denne siden midlertidig på samme måte som om du var logget ut." safe_mode: enabled: "Sikkert modus er påskrudd, for å skru av sikkert modus, lukk dette nettleservinduet" admin_js: @@ -2440,6 +2485,8 @@ nb_NO: dashboard: title: "Dashbord" last_updated: "Dashboardet var sist oppdatert:" + find_old: "Ser du etter det gamle dashbordet?" + old_link: "besøk det her" version: "Versjon" up_to_date: "Du har den seneste versjonen!" critical_available: "En kritisk oppdatering er tilgjengelig." @@ -2464,14 +2511,21 @@ nb_NO: space_free: "{{size}} ledig" uploads: "opplastinger" backups: "sikkerhetskopier" + lastest_backup: "Siste: %{date}" traffic_short: "Trafikk" traffic: "Applikasjon webforespørsler" page_views: "Sidevisninger" page_views_short: "Sidevisninger" show_traffic_report: "Vis detaljert trafikkrapport" + community_health: Samfunnshelse + whats_new_in_discourse: "Hva er nytt i Discourse?" + activity_metrics: Aktivitetsmåling reports: + trend_title: "%{percent} endring. Nåværende %{current}, var %{prev} i forrige periode." today: "I dag" yesterday: "I går" + last_7_days: "Siste 7" + last_30_days: "Siste 30" all_time: "Gjennom tidene" 7_days_ago: "7 dager siden" 30_days_ago: "30 dager siden" @@ -2482,6 +2536,10 @@ nb_NO: start_date: "Startdato" end_date: "Sluttdato" groups: "Alle grupper" + disabled: "Denne rapporten er deaktivert" + trending_search: + more: 'Logg for søk' + disabled: 'Rapporten for trending av søk er deaktivert. Aktiver logging av søkeord for å samle inn data.' commits: latest_changes: "Siste endringer: Oppdater ofte!" by: "av" @@ -2489,7 +2547,7 @@ nb_NO: title: "Rapporteringer" active_posts: "Rapporterte innlegg" old_posts: "Gamle rapporterte innlegg" - topics: "Rapporterte tråder" + topics: "Rapporterte Emner" moderation_history: "Moderatorhistorikk" agree: "Godta" agree_title: "Bekreft at denne rapporteringen er gyldig og korrekt" @@ -2508,21 +2566,27 @@ nb_NO: delete: "Slett" delete_title: "Fjern innlegget denne rapporteringen refererer til." delete_post_defer_flag: "Slett innlegg og ingorer flagg" - delete_post_defer_flag_title: "Slett innlegg; hvis det er første innlegg, slett tråden" + delete_post_defer_flag_title: "Slett innlegg; hvis det er første innlegg, slett emnet" delete_post_agree_flag: "Slett innlegg og samtykk med flagg" - delete_post_agree_flag_title: "Slett innlegg; hvis det er første innlegg, slett tråden" + delete_post_agree_flag_title: "Slett innlegg; hvis det er første innlegg, slett emnet" delete_flag_modal_title: "Slett og…" delete_spammer: "Slett spammer" - delete_spammer_title: "Fjern denne brukeren og alle innlegg og tråder av brukeren." + delete_spammer_title: "Fjern denne brukeren og alle innlegg og emner laget av brukeren." disagree_flag_unhide_post: "Si deg uenig med rapportering (vis innlegg)" disagree_flag_unhide_post_title: "Fjern alle rapporteringer fra dette innlegget og gjør det synlig igjen" disagree_flag: "Si deg uenig" disagree_flag_title: "Benekt rapportering som ugyldig eller uriktig" clear_topic_flags: "Ferdig" - clear_topic_flags_title: "Tråden er blitt undersøkt og problemer er blitt løst. Klikk Ferdig for å fjerne rapporteringene." + clear_topic_flags_title: "Emnet er undersøkt og problemene ble løst. Klikk Ferdig for å fjerne rapporteringene." more: "(flere svar…)" suspend_user: "Steng ute bruker" suspend_user_title: "Steng ute bruker for dette innlegget" + replies: + one: '[1 svar]' + other: '[%{count} svar]' + delete_replies: + one: Fjern %{count} svar i tillegg til dette innlegget? + other: Fjern de %{count} svarene i tillegg til dette innlegget? dispositions: agreed: "enig" disagreed: "uenig" @@ -2534,18 +2598,19 @@ nb_NO: error: "Noe gikk galt" reply_message: "Svar" no_results: "Det finnes ingen rapporterte innlegg." - topic_flagged: "Denne tråden er blitt rapportert." + topic_flagged: "Dette emnet har blitt rapportert." show_full: "vis hele innlegget" - visit_topic: "Besøk tråden for å utføre handling" + visit_topic: "Besøk emnet for å utføre handling" was_edited: "Innlegget ble redigert etter første rapportering" previous_flags_count: "Dette innlegget har allerede blitt rapportert {{count}} ganger." show_details: "Vis rapportdetaljer" details: "detaljer" flagged_topics: - topic: "Tråd" + topic: "Emne" type: "Type" users: "Brukere" last_flagged: "Sist rapporter" + no_results: "Det er ingen emner med flagg." short_names: off_topic: "utenfor temaet" inappropriate: "upassende" @@ -2555,17 +2620,41 @@ nb_NO: groups: new: title: "Ny gruppe" + create: "Opprett" name: too_short: "Gruppenavnet er for kort" too_long: "Gruppenavnet er for langt" + checking: "Sjekker om gruppenavnet er ledig..." available: "Gruppenavn tilgjengelig" not_available: "Gruppenavn ikke tilgjengelig" blank: "Gruppenavnet kan ikke være tomt" + bulk_add: + title: "Legg Til Fra Liste" + complete_users_not_added: "Disse brukerne ble ikke lagt til (sjekk om kontoen finnes):" + paste: "Lim inn en liste over brukernavn eller e-poster, en per linje:" + add_members: + as_owner: "Sett bruker(e) som eier(e) av denne gruppen" manage: + interaction: + email: E-post + incoming_email: "Brukerdefinert innkommende e-postadresse" + incoming_email_placeholder: "velg e-postadresse" + visibility: Synlighet + visibility_levels: + title: "Hvem kan se denne gruppen?" + public: "Alle" + members: "Gruppeeiere, medlemmer og administratorer" + staff: "Gruppeeiere og stab" + owners: "Gruppeeiere og administratorer" membership: automatic: Automatisk trust_level: Tillitsnivå trust_levels_title: "Tillitsnivå som automatisk gis til nye medlemmer når de legges til:" + trust_levels_none: "Ingen" + automatic_membership_email_domains: "Brukere som registreres med et e-postdomene identisk med et fra denne listen vil automatisk legges til i denne gruppen:" + automatic_membership_retroactive: "Bruk den samme regelen på eksisterende brukere med matchende e-postdomener" + primary_group: "Sett som primærgruppe automatisk" + name_placeholder: "Gruppenavn, ingen mellomrom, samme som regel for brukernavn" primary: "Primærgruppe" no_primary: "(ingen primærgruppe)" title: "Grupper" @@ -2580,6 +2669,8 @@ nb_NO: add: "Legg til" custom: "Egendefinert" automatic: "Automatisk" + default_title: "Standardtittel" + default_title_description: "vil gjelde for alle brukere i denne gruppen" group_owners: Eiere add_owners: Legg til eiere none_selected: "Velg en gruppe for å komme i gang" @@ -2595,7 +2686,7 @@ nb_NO: revoke: "Trekk tilbake" confirm_regen: "Er du sikker på at du vil erstatte den API-nøkkelen med en ny?" confirm_revoke: "Er du sikker på at du vil trekke tilbake den nøkkelen?" - info_html: "Din API-nøkkel vil tillate deg å lage og oppdatere tråder ved å bruke JSON-kall." + info_html: "API-nøkkelen din vil tillate deg å lage og oppdatere emner ved å bruke JSON-kall." all_users: "Alle brukere" note_html: "Hold denne nøkkelen hemmelig, alle brukere som har den, vil kunne opprette vilkårlige innlegg som hvilken som helst bruker. " web_hooks: @@ -2631,14 +2722,26 @@ nb_NO: groups_filter: "Utløse grupper" delete_confirm: "Slette denne webhooken?" topic_event: - name: "Hendelse for tråd" - details: "Når det finnes en ny, revidert, endret eller slettet tråd." + name: "Hendelse for Emne" + details: "Når det finnes et nytt, revidert, endret eller slettet emne." post_event: name: "Innleggshendelse" details: "Når det er et nytt, redigert, slettet eller gjenopprettet innlegg." user_event: name: "Brukerhendelse" details: "Når en bruker logger inn, logger ut, blir opprettet, godkjent eller oppdatert." + group_event: + name: "Gruppehandling" + details: "Når en gruppe lages, oppdateres eller slettes." + category_event: + name: "Kategorihandling" + details: "Når en kategori lages, oppdateres eller slettes." + tag_event: + name: "Stikkordshandling" + details: "Når et stikkord lages, oppdateres eller slettes." + flag_event: + name: "Flagghandling" + details: "Når et flagg settes, aksepteres, avvises eller ignoreres." delivery_status: title: "Sendingsstatus" inactive: "Inaktiv" @@ -2680,6 +2783,7 @@ nb_NO: change_settings: "Endre instillinger" change_settings_short: "Innstillinger" howto: "Hvordan installerer jeg utvidelser?" + official: "Offisiell Plugin" backups: title: "Sikkerhetskopier" menu: @@ -2716,7 +2820,7 @@ nb_NO: label: "Sikkerhetskopi" title: "Opprett en sikkerhetskopi" confirm: "Vil du starte en ny sikkerhetskopiering?" - without_uploads: "Ja (ikke inkluder filer)" + without_uploads: "Ja (ikke inkluderer opplastinger)" download: label: "Last ned" title: "Send e-post med nedlastingslenke" @@ -2798,6 +2902,11 @@ nb_NO: add_upload: "Legg til opplasting" upload_file_tip: "Velg en effekt å laste opp (PNG, WOFF2, osv…)" variable_name: "Variabelnavn for SCSS:" + variable_name_invalid: "Ugyldig variabelnavn. Kun alfanumeriske tegn tillatt. Må starte med en bokstav. Må være unikt. " + variable_name_error: + invalid_syntax: "Ugyldig variabelnavn. Kun alfanumeriske tegn tillatt. Må starte med en bokstav." + no_overwrite: "Ugyldig variabelnavn. Kan ikke overskrive en eksisterende variabel." + must_be_unique: "Ugyldig variabelnavn. Må være unikt." upload: "Last opp" child_themes_check: "Drakten inneholder andre underdrakter" css_html: "Egendefinert CSS/HTML" @@ -2806,6 +2915,8 @@ nb_NO: delete_upload_confirm: "Slett denne opplastingen? (Draktens CSS kan slutte å virke!)" import_web_tip: "Pakkebrønn inneholdende drakt" import_file_tip: ".dcstyle.json-fil inneholdende drakt" + is_private: "Drakten er i et privat git repository" + public_key: "Gi den følgende public keyen tilgang til repoet:" about_theme: "Om drakt" license: "Lisens" component_of: "Drakten er en del av:" @@ -2878,10 +2989,10 @@ nb_NO: description: "Tekst og ikoner i nettstedets hode." highlight: name: 'utheving' - description: 'Bakgrunnsfargen på uthevede elementer på siden, slik som innlegg og tråder.' + description: 'Bakgrunnsfargen på uthevede elementer på siden, slik som innlegg og emner.' danger: name: 'fare' - description: 'Uthevingsfarge for handlinger som sletting av innlegg og tråder.' + description: 'Uthevingsfarge for handlinger som sletting av innlegg og emner.' success: name: 'suksess' description: 'Brukt til å indikere hvorvidt en handling var vellykket.' @@ -2959,7 +3070,7 @@ nb_NO: suspend_user: "Bruker utestengt" silence_user: "Bruker dempet" delete_post: "Innlegg slettet" - delete_topic: "Tråd slettet" + delete_topic: "Emne Slettet" logs: title: "Logger" action: "Handling" @@ -2967,7 +3078,7 @@ nb_NO: last_match_at: "Siste treff" match_count: "Treff" ip_address: "IP" - topic_id: "Tråd-ID" + topic_id: "Emne-ID" post_id: "Innleggs-ID" category_id: "Kategori-ID" delete: 'Slett' @@ -3007,8 +3118,8 @@ nb_NO: grant_badge: "tildel merke" revoke_badge: "trekk tilbake merke" check_email: "sjekk e-post" - delete_topic: "slett tråd" - recover_topic: "angre sletting av tråd" + delete_topic: "slett emne" + recover_topic: "angre sletting av emne" delete_post: "slett innlegg" impersonate: "overta brukerkonto" anonymize_user: "anonymiser bruker" @@ -3036,9 +3147,15 @@ nb_NO: reviewed_post: "gjennomsett innlegg" custom_staff: "egendefinert handling for programtillegg" post_locked: "innlegg låst" + post_edit: "innlegg redigert" post_unlocked: "innlegg opplåst" check_personal_message: "sjekk personlig melding" disabled_second_factor: "deaktiver totrinnsverifisering" + topic_published: "emne publisert" + post_approved: "innlegg godkjent" + create_badge: "lag merke" + change_badge: "endre merke" + delete_badge: "slett merke" 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." @@ -3108,6 +3225,7 @@ nb_NO: placeholder_regexp: "regulært uttrykk" add: 'Legg til' success: 'Suksess' + exists: 'Eksisterer fra før' upload: "Last opp" upload_successful: "Opplastet. Ord lagt til." impersonate: @@ -3131,6 +3249,7 @@ nb_NO: suspended: 'Utestengt' silenced: 'Dempet' suspect: 'Mistenkt' + staged: 'Arrangert' approved: "Godkjent?" approved_selected: one: godkjenn bruker @@ -3153,6 +3272,7 @@ nb_NO: silenced: 'Dempede brukere' suspended: 'Utestengte brukere' suspect: 'Mistenkte brukere' + staged: 'Arrangerte Brukere' reject_successful: one: Avvist 1 bruker. other: Avviste %{count} brukere. @@ -3189,7 +3309,7 @@ nb_NO: penalty_post_delete: "Slett innlegget" penalty_post_edit: "Rediger innlegget" penalty_post_none: "ikke gjør noe" - delete_all_posts_confirm_MF: "Du er i ferd med å slette {POSTS, plural, one {1 innlegg} other {# innlegg}} og {TOPICS, plural, one {1 tråd} other {# tråder}}. Er du sikker?" + delete_all_posts_confirm_MF: "Du er i ferd med å slette {POSTS, plural, one {1 innlegg} other {# innlegg}} og {TOPICS, plural, one {1 emne} other {# emner}}. Er du sikker?" silence: "Demp" unsilence: "Opphev demping" silenced: "Dempet?" @@ -3221,11 +3341,11 @@ nb_NO: activity: Aktivitet like_count: Likes tildelt / mottatt last_100_days: 'de siste 100 dagene' - private_topics_count: Private tråder + private_topics_count: Private Emner posts_read_count: Innlegg lest post_count: Innlegg skrevet second_factor_enabled: totrinnsverifisering aktivert - topics_entered: Tråder sett + topics_entered: Emner Lest flags_given_count: Rapporteringer tildelt flags_received_count: Rapporteringer mottatt warnings_received_count: Advarsler mottatt @@ -3254,6 +3374,7 @@ nb_NO: delete_confirm: "Er du HELT SIKKER på at du vil slette denne brukeren? Denne handlingen er permanent!" delete_and_block: "Slett og blokker denne e-post- og IP-adressen" delete_dont_block: "Bare slett" + deleting_user: "Sletter bruker..." deleted: "Brukeren ble slettet." delete_failed: "Det oppstod en feil ved slettingen av den brukeren. Sørg for at alle av brukerens innlegg er slettet før du prøver å slette brukeren." send_activation_email: "Send e-post for aktivering" @@ -3265,7 +3386,7 @@ nb_NO: deactivate_failed: "Det oppstod et problem ved deaktiveringen av den brukeren." unsilence_failed: 'Feil ved fjerning av forstumming av bruker.' silence_failed: 'Feil ved forstumming av bruker.' - silence_confirm: 'Er du sikker på at du vil dempe denne brukeren? Vedkommende vil ikke kunne opprette nye tråder eller innlegg.' + silence_confirm: 'Er du sikker på at du vil dempe denne brukeren? Vedkommende vil ikke kunne opprette nye emner eller innlegg.' silence_accept: 'Ja, dem denne brukeren' bounce_score: "Antall tilbakesendinger" reset_bounce_score: @@ -3274,8 +3395,8 @@ nb_NO: visit_profile: "Besøk denne brukerinnstillingssiden for å redigere vedkommendes profil" deactivate_explanation: "En deaktivert bruker må bekrefte e-postadressen sin på nytt." suspended_explanation: "En utestengt bruker kan ikke logge inn." - silence_explanation: "En dempet bruker kan ikke skrive innlegg eller opprette tråder." - staged_explanation: "En arrangert bruker kan bare skrive innlegg via e-post i bestemte tråder." + silence_explanation: "En dempet bruker kan ikke skrive innlegg eller opprette emner." + staged_explanation: "En arrangert bruker kan bare skrive innlegg via e-post i bestemte emner." bounce_score_explanation: none: "Ingen tilbakesendinger ble mottatt nylig fra den e-posten." some: "Noen tilbakesendinger ble mottatt nylig fra den e-posten." @@ -3297,9 +3418,9 @@ nb_NO: requirement_heading: "Krav" visits: "Besøk" days: "dager" - topics_replied_to: "Tråder besvart" - topics_viewed: "Tråder vist" - topics_viewed_all_time: "Tråder vist (totalt)" + topics_replied_to: "Emner Besvart" + topics_viewed: "Emner Lest" + topics_viewed_all_time: "Emner Lest (totalt)" posts_read: "Innlegg lest" posts_read_all_time: "Innlegg lest (totalt)" flagged_posts: "Rapporterte innlegg" @@ -3308,6 +3429,8 @@ nb_NO: likes_received: "Likes mottatt" likes_received_days: "Likes mottatt: Unike dager" likes_received_users: "Likes mottatt: Unike brukere" + suspended: "Suspenderte (gjennom tidene)" + silenced: "Dempet (gjennom tidene)" qualifies: "Kvalifiserer til tillitsnivå 3." does_not_qualify: "Kvalifiserer ikke til tillitsnivå 3." will_be_promoted: "Vil snart forfremmes." @@ -3367,10 +3490,13 @@ nb_NO: recommended: "Skreddersøm av følgende tekst for å kle dine behov anbefales:" show_overriden: 'Bare vis overstyrte' settings: + show_overriden: 'Vis kun overstyrte' reset: 'tilbakestill' + none: 'ingen' site_settings: title: 'Innstillinger' no_results: "Ingen treff funnet." + more_than_30_results: "Det er over 30 resultater. Vennligst skjerp søket eller velg en kategori." clear_filter: "Tøm" add_url: "legg til URL" add_host: "legg til vert" @@ -3416,7 +3542,7 @@ nb_NO: modal_title: Merkegrupper granted_by: Tildelt av granted_at: Tildelt - reason_help: (En lenke til et innlegg eller tråd) + reason_help: (En lenke til et innlegg eller emne) save: Lagre delete: Slett delete_confirm: "Er du sikker på at du vil slette dette merket?" @@ -3437,7 +3563,8 @@ nb_NO: enabled: Aktiver merke icon: Ikon image: Bilde - icon_help: "Bruk enten en Font Awesome class eller URL for et bilde" + icon_help: "Bruk en Font Awesome klasse" + image_help: "Oppgi URL for bildet (overstyrer ikonfeltet hvis begge er satt)" query: Spørring for merke (SQL) target_posts: Spørring har innlegg som mål auto_revoke: Kjør tilbakedragningsspørring daglig @@ -3479,7 +3606,7 @@ nb_NO: embedding: get_started: "Hvis du vil bygge inn Discourse på en annen nettside, begynn med å legge til dens vert." confirm_delete: "Er du sikker på at du vil slette den verten?" - sample: "Bruk følgende HTML-kode på siden din for å bygge inn Discourse-tråder. Erstatt ERSTATT_MEG med riktig nettadresse til siden du bygger den inn i." + sample: "Bruk følgende HTML-kode på siden din for å bygge inn Discourse-emner. Erstatt ERSTATT_MEG med riktig nettadresse til siden du bygger den inn i." title: "Innbygging" host: "Tillatte verter" class_name: "Klassenavn" @@ -3491,8 +3618,8 @@ nb_NO: feed_settings: "Informasjonskanals-innstillinger" feed_description: "Å tilby en RSS/ATOM-strøm for nettstedet ditt kan forbedre Discourses evne til å importere innholdet ditt." crawling_settings: "Innstillinger for søkeroboter" - crawling_description: "Dersom Discourse oppretter tråder for innleggene dine og ingen RSS/ATOM-informasjonskanal finnes, vil det prøve å tolke innholdet ditt ut fra HTML-koden din. Noen ganger kan det være utfordrende å hente ut innhold, så muligheten til å oppgi CSS-regler er der for å gjøre uthentingen enklere." - embed_by_username: "Brukernavn for opprettelse av tråd" + crawling_description: "Dersom Discourse oppretter emner for innleggene dine og ingen RSS/ATOM-informasjonskanal finnes, vil det prøve å tolke innholdet ditt ut fra HTML-koden din. Noen ganger kan det være utfordrende å hente ut innhold, så muligheten til å oppgi CSS-regler er der for å gjøre uthentingen enklere." + embed_by_username: "Brukernavn for opprettelse av emne" embed_post_limit: "Maksimalt antall innlegg å bygge inn" embed_username_key_from_feed: "Nøkkel for å hente Discourse-brukernavn fra informasjonskanal" embed_title_scrubber: "Regulære uttrykk brukt til å finne og korrigere feil i titler" @@ -3507,8 +3634,8 @@ nb_NO: permalink: title: "Permalenker" url: "URL" - topic_id: "Tråd-ID" - topic_title: "Tråd" + topic_id: "Emne-ID" + topic_title: "Emne" post_id: "Innleggs-ID" post_title: "Innlegg" category_id: "Kategori-ID" diff --git a/config/locales/client.nl.yml b/config/locales/client.nl.yml index db255a70c9..22e43611a4 100644 --- a/config/locales/client.nl.yml +++ b/config/locales/client.nl.yml @@ -2468,7 +2468,6 @@ nl: label: "Back-up maken" title: "Een back-up maken" confirm: "Wilt u een nieuwe back-up starten?" - without_uploads: "Ja (geen bestanden bijvoegen)" download: label: "Downloaden" title: "E-mail met downloadkoppeling verzenden" @@ -3125,7 +3124,6 @@ nl: enabled: Badge inschakelen icon: Pictogram image: Afbeelding - icon_help: "Gebruik ofwel een Font Awesome-klasse of een URL naar een afbeelding" query: Badgequery (SQL) target_posts: Geassocieerde berichten opvragen auto_revoke: Intrekkingsquery dagelijks uitvoeren diff --git a/config/locales/client.pl_PL.yml b/config/locales/client.pl_PL.yml index d506ff2934..c562f0d794 100644 --- a/config/locales/client.pl_PL.yml +++ b/config/locales/client.pl_PL.yml @@ -54,6 +54,11 @@ pl_PL: many: '%{count}s' one: 1s other: '%{count}s' + less_than_x_minutes: + few: < %{count} min + many: '< %{count} min ' + one: < 1 min + other: '< %{count} min ' x_minutes: few: '%{count}m' many: '%{count}m' @@ -142,6 +147,7 @@ pl_PL: other: '%{count} lat później' previous_month: 'Poprzedni miesiąc' next_month: 'Następny miesiąc' + placeholder: data share: topic: 'udostępnij odnośnik do tego tematu' post: 'wpis #%{postNumber}' @@ -155,6 +161,7 @@ pl_PL: split_topic: "podziel ten temat %{when}" invited_user: "%{who} został zaproszony %{when}" invited_group: "%{who} został zaproszony %{when}" + user_left: "%{who} usunął siebie z tej konwersacji %{when}" removed_user: "%{who} został usunięty %{when}" removed_group: "%{who} został usunięty %{when}" autoclosed: @@ -204,6 +211,7 @@ pl_PL: not_implemented: "Bardzo nam przykro, ale ta funkcja nie została jeszcze zaimplementowana." no_value: "Nie" yes_value: "Tak" + submit: "Prześlij" generic_error: "Przepraszamy, wystąpił błąd." generic_error_with_reason: "Wystąpił błąd: %{error}" sign_up: "Rejestracja" @@ -258,6 +266,8 @@ pl_PL: our_moderators: "Moderatoratorzy" stat: all_time: "Ogółem" + last_7_days: "Ostatnie 7" + last_30_days: "Ostatnie 30" like_count: "Lajki" topic_count: "Tematy" post_count: "Wpisy" @@ -278,6 +288,21 @@ pl_PL: last_read: "to ostatni przeczytany przez ciebie wpis: kliknij, aby dodać zakładkę" remove: "Usuń zakładkę" confirm_clear: "Czy na pewno chcesz usunąć wszystkie zakładki ustawione w tym temacie?" + topic_count_latest: + few: Zobacz {{count}} nowe albo zaktualizowane tematy + many: Zobacz {{count}} nowych albo zaktualizowanych tematów + one: Zobacz {{count}} nowy albo zaktualizowany temat + other: Zobacz {{count}} nowych albo zaktualizowanych tematów + topic_count_unread: + few: Zobacz {{count}} nieprzeczytane tematy + many: Zobacz {{count}} nieprzeczytanych tematów + one: Zobacz {{count}} nieprzeczytany temat + other: Zobacz {{count}} nieprzeczytanych tematów + topic_count_new: + few: Zobacz {{count}} nowe tematy + many: Zobacz {{count}} nowych tematów + one: Zobacz {{count}} nowy temat + other: Zobacz {{count}} nowych tematów preview: "podgląd" cancel: "anuluj" save: "Zapisz zmiany" @@ -290,6 +315,7 @@ pl_PL: pasting: "Wklejanie..." enable: "Włącz" disable: "Wyłącz" + continue: "Kontynuuj" undo: "Cofnij" revert: "Przywróć" failed: "Niepowodzenie" @@ -373,6 +399,31 @@ pl_PL: make_user_group_owner: "Nadaj prawa właściciela" remove_user_as_group_owner: "Usuń prawa właściciela" groups: + add_members: + title: "Dodaj członków" + usernames: "Nazwy użytkowników" + manage: + title: 'Zarządzaj' + name: 'Nazwa' + full_name: 'Pełna nazwa' + add_members: "Dodaj członków" + delete_member_confirm: "Usunąć '%{username}' z grupy '%{group}'?" + profile: + title: Profil + interaction: + title: Interakcja + notification: Powiadomienie + membership: + title: Członkostwo + access: Dostęp + logs: + title: "Logi" + when: "Kiedy" + action: "Akcja" + subject: "Temat" + details: "Szczegóły" + from: "Od" + to: "Do" public_admission: "Zezwól wszystkim użytkownikom na dołączanie do tej grupy (widoczność grupy musi być ustawiona na publiczną)" public_exit: "Zezwól wszystkim użytkownikom na opuszczanie tej grupy" empty: @@ -383,6 +434,8 @@ pl_PL: topics: "Nie ma wątków stworzonych przez użytkowników tej grupy" logs: "Nie ma logów dla tej grupy" add: "Dodaj" + join: "Dołącz" + leave: "Opuść" message: "Wiadomość" allow_membership_requests: "Zezwól użytkownikom na wysyłanie zaproszeń do właścicieli grupy." membership_request_template: "Wyświetl niestandardowy szablon użytkownikom, w momencie wysyłania wniosku o członkostwo." @@ -392,17 +445,43 @@ pl_PL: reason: "Poinformuj właścicieli grupy dlaczego do niej należysz." membership: "Członkostwo" name: "Nazwa" + group_name: "Nazwa grupy" + user_count: "Użytkownicy" bio: "O grupie" + selector_placeholder: "podaj nazwę użytkownika" owner: "właściciel" index: title: "Grupy" + all: "Wszystkie grupy" empty: "Nie ma widocznych grup" + owner_groups: "Grupy, które do mnie należą" + close_groups: "Zamknięte grupy" + closed: "Zamknięta" + public: "Publiczna" + private: "Prywatna" + public_groups: "Publiczne grupy" + close_group: Zamknij grupę + my_groups: "Moje grupy" + group_type: "Rodzaj grupy" + is_group_user: "Członek" + is_group_owner: "Właściciel" title: few: Grupy many: Grup one: Grupa other: Grup activity: "Aktywność" + members: + title: "Członkowie" + filter_placeholder_admin: "nazwa użytkownika lub adres e-mail" + filter_placeholder: "nazwa użytkownika" + remove_member: "Usuń członka" + remove_member_description: "Usuń %{username} z tej grupy" + make_owner: "Uczyń właścicielem" + make_owner_description: "Uczyń %{username} właścicielem tej grupy" + remove_owner: "Usuń z funkcji właściciela" + remove_owner_description: "Usuń %{username} z funkcji właściciela tej grupy" + owner: "Właściciel" topics: "Tematy" posts: "Wpisów" mentions: "Wzmianki" @@ -455,6 +534,7 @@ pl_PL: "14": "Oczekujące" categories: all: "wszystkie kategorie" + all_subcategories: "wszystkie w %{categoryName}" no_subcategory: "żadne" category: "Kategoria" category_list: "Wyświetl listę kategorii" @@ -516,6 +596,7 @@ pl_PL: activity_stream: "Aktywność" preferences: "Ustawienia" expand_profile: "Rozwiń" + collapse_profile: "Zwiń" bookmarks: "Zakładki" bio: "O mnie" invited_by: "Zaproszono przez" @@ -523,6 +604,7 @@ pl_PL: notifications: "Powiadomienia" statistics: "Statystyki" desktop_notifications: + label: "Natychmiastowe powiadomienia" not_supported: "Powiadomienia nie są wspierane przez tę przeglądarkę. Przepraszamy." perm_default: "Włącz powiadomienia" perm_denied_btn: "Brak uprawnień" @@ -530,6 +612,7 @@ pl_PL: disable: "Wyłącz powiadomienia" enable: "Włącz powiadomienia" each_browser_note: "Uwaga: to ustawienie musisz zmienić w każdej przeglądarce której używasz." + consent_prompt: "Czy chcesz otrzymywać natychmiastowe powiadomienia, gdy ktoś odpowie na twój post?" dismiss: 'Odrzuć' dismiss_notifications: "Odrzuć wszystkie" dismiss_notifications_tooltip: "Oznacz wszystkie powiadomienia jako przeczytane" @@ -581,6 +664,7 @@ pl_PL: 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." + delete_yourself_not_allowed: "Skontaktuj się z członkiem ekipy jeśli chcesz, aby twoje konto zostało usunięte." unread_message_count: "Wiadomości" admin_delete: "Usuń" users: "Użytkownicy" @@ -613,6 +697,7 @@ pl_PL: 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" + tags: "Tagi" preferences_nav: account: "Konto" profile: "Profil" @@ -632,6 +717,15 @@ pl_PL: choose: "Wybierz hasło" second_factor: title: "Dwuskładnikowe uwierzytelnianie" + disable: "Wyłącz dwuskładnikowe uwierzytelnianie" + confirm_password_description: "Potwierdź swoje hasło, aby kontynuować" + label: "Kod" + enable_description: | + Zeskanuj ten kod QR za pomocą wspieranej aplikacji (AndroidiOSWindows Phone) i podaj swój kod uwierzytelniający. + disable_description: "Podaj kod uwierzytelniający ze swojej aplikacji" + show_key_description: "Wpisz ręcznie" + extended_description: | + Dwuskładnikowe uwierzytelnianie zwiększa bezpieczeństwo twojego konta dzięki wymogowi podawanie jednorazowego tokenu oprócz twego hasła przy każdej próbie zalogowania. Tokeny można generować na urządzeniach z systemem Android, iOS lub Windows Phone. change_about: title: "Zmień O mnie" error: "Wystąpił błąd podczas zmiany tej wartości." @@ -759,6 +853,7 @@ pl_PL: title: "Zaproszenia" user: "Zaproszony(-a) użytkownik(-czka)" sent: "Wysłane" + none: "Brak zaproszeń do wyświetlenia." truncated: few: Wyświetlanie {{count}} pierwszych zaproszeń. many: Wyświetlanie {{count}} pierwszych zaproszeń. @@ -833,6 +928,11 @@ pl_PL: many: dni odwiedzin one: dzień odwiedzin other: dni odwiedzin + topics_entered: + few: przeczytane tematy + many: przeczytane tematy + one: przeczytany temat + other: przeczytane tematy posts_read: few: przeczytanych postów many: przeczytane posty @@ -868,6 +968,7 @@ pl_PL: header_title: "profil, wiadomości, zakładki i ustawienia" title: title: "Tytuł" + none: "(brak)" filters: all: "Wszystkie" stream: @@ -987,10 +1088,13 @@ pl_PL: title: "Logowanie" username: "Użytkownik" password: "Hasło" + second_factor_title: "Dwuskładnikowe uwierzytelnianie" + second_factor_description: "Podaj kod uwierzytelniający ze swojej aplikacji:" email_placeholder: "adres email lub nazwa użytkownika" caps_lock_warning: "Caps Lock jest włączony" error: "Nieznany błąd" rate_limit: "Poczekaj, zanim ponowisz próbę logowania." + blank_username: "Podaj swój adres e-mail lub nazwę użytkownika." blank_username_or_password: "Podaj swój email lub nazwę użytkownika i hasło" reset_password: 'Resetuj hasło' logging_in: "Uwierzytelnianie…" @@ -1058,14 +1162,28 @@ pl_PL: categories_only: "Tylko kategorie" categories_with_featured_topics: "Kategorie z wybranymi tematami" categories_and_latest_topics: "Kategorie i ostatnie tematy" + categories_and_top_topics: "Kategorie i najlepsze tematy" shortcut_modifier_key: shift: 'Shift' ctrl: 'Ctrl' alt: 'Alt' + conditional_loading_section: + loading: Ładowanie... select_kit: default_header_text: Wybierz... no_content: Nie znaleziono dopasowań filter_placeholder: Wyszukiwanie... + create: "Stwórz: '{{content}}'" + max_content_reached: + few: Może wybrać tylko {{count}} elementy. + many: Możesz wybrać tylko {{count}} elementów. + one: Możesz wybrać tylko jeden element. + other: Możesz wybrać tylko {{count}} elementów. + min_content_not_reached: + few: Wybierz co najmniej {{count}} elementy. + many: Wybierz co najmniej {{count}} elementów. + one: Wybierz co najmniej jeden element. + other: Wybierz co najmniej {{count}} elementów. emoji_picker: filter_placeholder: Szukaj emoji people: Ludzie @@ -1083,6 +1201,10 @@ pl_PL: medium_tone: Średni kolor skóry medium_dark_tone: Średnio ciemny kolor skóry dark_tone: Ciemny kolor skóry + shared_drafts: + notice: "Ten temat jest widoczny tylko użytkowników mających dostęp do kategorii {{category}}." + destination_category: "Kategoria docelowa" + publishing: "Publikowanie tematu..." composer: emoji: "Emoji :)" more_emoji: "więcej…" @@ -1116,6 +1238,7 @@ pl_PL: post_length: "Wpis musi zawierać przynajmniej {{min}} znaków" try_like: 'Może warto użyć przycisku ?' category_missing: "Musisz wybrać kategorię" + tags_missing: "Musisz wybrać co najmniej {{count}} tagów" save_edit: "Zapisz zmiany" reply_original: "Odpowiedz na Oryginalny Temat" reply_here: "Odpowiedz tutaj" @@ -2697,7 +2820,6 @@ pl_PL: label: "Kopia zapasowa" title: "Wykonaj kopię zapasową" confirm: "Czy chcesz wykonać kopię zapasową?" - without_uploads: "Tak (bez załączników)" download: label: "Pobierz" title: "Wyślij email z linkiem do pobrania" @@ -3410,7 +3532,6 @@ pl_PL: enabled: Włącz odznakę icon: Ikona image: Grafika - icon_help: "Użyj jednej z klas Font Awesome lub adresu URL do grafiki" query: "Zapytanie odznaki (SQL) " target_posts: Wpisy powiązane z odznaką auto_revoke: Codziennie uruchamiaj zapytanie odbierające odznakę diff --git a/config/locales/client.pt.yml b/config/locales/client.pt.yml index ef588d20f3..0ba161c9c9 100644 --- a/config/locales/client.pt.yml +++ b/config/locales/client.pt.yml @@ -2359,7 +2359,6 @@ pt: label: "Fazer Cópia de segurança" title: "Criar uma cópia de segurança" confirm: "Deseja criar uma nova cópia de segurança?" - without_uploads: "Sim (não incluir ficheiros)" download: label: "Transferir" title: "Enviar mensagem com hiperligação de transferência" @@ -2898,7 +2897,6 @@ pt: enabled: Ativar distintivos icon: Ícone image: Imagem - icon_help: "Use uma classe Font Awesome ou um URL para uma imagem" query: "\"Query\" de Distintivo (SQL)" target_posts: "\"Query\" direcionada a publicações" auto_revoke: "Executar diariamente a \"query\" de revogação " diff --git a/config/locales/client.pt_BR.yml b/config/locales/client.pt_BR.yml index a1cbcaee30..64ec306a12 100644 --- a/config/locales/client.pt_BR.yml +++ b/config/locales/client.pt_BR.yml @@ -2381,7 +2381,6 @@ pt_BR: label: "Backup" title: "Cria um backup" confirm: "Você quer iniciar um novo backup?" - without_uploads: "Sim (não inclua arquivos)" download: label: "Download" title: "Enviar email com link para download" @@ -2958,7 +2957,6 @@ pt_BR: enabled: Habilitar emblema icon: Ícone image: Imagem - icon_help: "Use uma classe do Font Awesome ou uma URL de uma imagem" query: Badge Query (SQL) target_posts: Consultar respostas selecionadas auto_revoke: Rodar revocation query todo dia diff --git a/config/locales/client.ro.yml b/config/locales/client.ro.yml index 404f483992..8b495e558f 100644 --- a/config/locales/client.ro.yml +++ b/config/locales/client.ro.yml @@ -420,7 +420,6 @@ ro: all: "Toate grupurile" empty: "Nu există nici un grup vizibil." filter: "Filtrează după tipul grupului" - all_groups: "Toate grupurile" owner_groups: "Grupuri pe care le dețin" close_groups: "Grupuri închise" automatic_groups: "Grupuri automate" @@ -2294,7 +2293,7 @@ ro: few: A primit acest ecuson de %{count} ori one: A primit acest ecuson o dată other: A primit acest ecuson de %{count} de ori - granted_on: "Acordat acum %{date}" + granted_on: "Acordat %{date}" others_count: "Alții cu acest ecuson (%{count})" title: Ecusoane multiple_grant: "Poți primi asta de mai multe ori" @@ -2670,7 +2669,6 @@ ro: label: "Backup" title: "Creează un backup" confirm: "Ești sigur că vei să începi o nouă operațiune de backup?" - without_uploads: "Da (nu include fişierele)" download: label: "Descărcare" title: "Trimite email cu link de descărcare" @@ -3323,7 +3321,6 @@ ro: enabled: Activează ecuson icon: Pictogramă image: Imagine - icon_help: "Folosiţi o clasă de fonturi Font Awesome sau un URL pentru imagine" query: Interogare ecusoane (SQL) target_posts: Interogarea mesajelor utilizatorilor-ţintă auto_revoke: Pornește verificarea de revocare în fiecare zi diff --git a/config/locales/client.ru.yml b/config/locales/client.ru.yml index cb4cd657d6..a661e95b88 100644 --- a/config/locales/client.ru.yml +++ b/config/locales/client.ru.yml @@ -447,7 +447,6 @@ ru: all: "Все Группы" empty: "Нет видимых групп." filter: "Фильтр по типу группы" - all_groups: "Все Группы" owner_groups: "Группы в которых я владелец" close_groups: "Закрытая группа" automatic_groups: "Автоматические Группы" @@ -2826,7 +2825,6 @@ ru: label: "Резервная копия" title: "Создать резервную копию" confirm: "Запустить резервное копирование?" - without_uploads: "Да (исключить файлы)" download: label: "Скачать" title: "Послать письмо со ссылкой для скачивания" @@ -3559,7 +3557,6 @@ ru: enabled: Активировать использование награды icon: Иконка image: Картинка - icon_help: "Используйте класс шрифта Font Awesome или ссылку на картинку" query: Выборка награды (SQL) target_posts: Выборка целевых сообщений auto_revoke: Запускать запрос на отзыв ежедневно diff --git a/config/locales/client.sk.yml b/config/locales/client.sk.yml index 248eb05edb..960e214035 100644 --- a/config/locales/client.sk.yml +++ b/config/locales/client.sk.yml @@ -427,7 +427,6 @@ sk: title: "Skupiny" all: "Všetky skupiny" empty: "Nenašli sa viditeľné skupiny." - all_groups: "Všetky skupiny" owner_groups: "Skupiny, ktorých som vlastníkom" close_groups: "Uzavreté skupina" automatic_groups: "Automatické skupiny" @@ -2386,7 +2385,6 @@ sk: label: "Záloha" title: "Vytvoriť zálohu" confirm: "Prajete si spustiť novú zálohu?" - without_uploads: "Áno (nezahŕňať súbory)" download: label: "Stiahnuť" destroy: @@ -2904,7 +2902,6 @@ sk: 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 diff --git a/config/locales/client.sl.yml b/config/locales/client.sl.yml index 657ed14521..8abdeb97e9 100644 --- a/config/locales/client.sl.yml +++ b/config/locales/client.sl.yml @@ -1466,7 +1466,6 @@ sl: label: "Varnostna kopija" title: "Ustvari varnostno kopijo" confirm: "Želite ustvariti varnostno kopijo?" - without_uploads: "Ja (ne vključi datotek)" download: label: "Naloži" export_csv: diff --git a/config/locales/client.sq.yml b/config/locales/client.sq.yml index 5eb9ec8649..901adcdefb 100644 --- a/config/locales/client.sq.yml +++ b/config/locales/client.sq.yml @@ -2522,7 +2522,6 @@ sq: enabled: Aktivizoni stemën icon: Ikonë image: Imazh - icon_help: "Përdor një klas FontAwesome ose URL-në e një imazhi" query: Query Steme (SQL) show_posts: Trego postimin që akordoi stemën në faqen e stemave trigger_type: diff --git a/config/locales/client.sr.yml b/config/locales/client.sr.yml index b34ab2bdd9..9587e80bf3 100644 --- a/config/locales/client.sr.yml +++ b/config/locales/client.sr.yml @@ -1541,7 +1541,6 @@ sr: backup: title: "Napravi sigurnosnu kopiju" confirm: "Želite li pokrenuti novu sigurnosnu kopiju?" - without_uploads: "Da (ne uključuj datoteke)" destroy: title: "Ukloni kopiju" confirm: "Jeste li sigurni da želite uništiti ovu sigurnosnu kopiju?" @@ -1965,7 +1964,6 @@ sr: enabled: Omogući značku icon: Ikona image: Slika - icon_help: "Koristite ili Font Awesome klase ili URL za neku sliku" query: Upitnik Značke (SQL) target_posts: Upitnik cilja poruke auto_revoke: Svakodnevno pokreni upitnik o povlačenju diff --git a/config/locales/client.sv.yml b/config/locales/client.sv.yml index 74e7357013..fa96845726 100644 --- a/config/locales/client.sv.yml +++ b/config/locales/client.sv.yml @@ -112,6 +112,7 @@ sv: email: 'skicka denna länk i ett e-postmeddelande' action_codes: public_topic: "gjorde det här ämnet publikt %{when}" + private_topic: "gjorde det här ämnet till ett personligt meddelande %{when}" split_topic: "splitta det här ämnet %{when}" invited_user: "bjöd in %{who} %{when}" invited_group: "bjöd in %{who} %{when}" @@ -142,6 +143,7 @@ sv: topic_admin_menu: "administratörsåtgärder för ämne" wizard_required: "Välkommen till din nya Discourse! Låt oss komma igång genom uppsättnings guiden ✨" emails_are_disabled: "All utgående e-post har blivit globalt inaktiverad av en administratör. Inga e-postnotifikationer av något slag kommer att skickas ut." + bootstrap_mode_enabled: "Du är i bootstrap-läge för att göra lanseringen av din nya webbplats enklare. Alla nya användare kommer att beviljas förtroendenivå 1 och få dagliga sammanfattningar skickade via e-post. Det här stängs automatiskt av när det totala antalet användare överstiger %{min_users}." bootstrap_mode_disabled: "Bootstrap-läge stängs av om 24 timmar." themes: default_description: "Standard" @@ -166,6 +168,7 @@ sv: not_implemented: "Denna funktion har inte implementerats än, vi beklagar!" no_value: "Nej" yes_value: "Ja" + submit: "Skicka" generic_error: "Tyvärr, ett fel har inträffat." generic_error_with_reason: "Ett fel inträffade: %{error}" sign_up: "Registrera" @@ -216,6 +219,8 @@ sv: our_moderators: "Våra moderatorer" stat: all_time: "Alla dagar" + last_7_days: "Senaste 7" + last_30_days: "Senaste 30" like_count: "Gillningar" topic_count: "Ämnen" post_count: "Inlägg" @@ -2300,7 +2305,6 @@ sv: label: "Säkerhetskopia" title: "Skapa en säkerhetskopia" confirm: "Vill du skapa en ny säkerhetskopiering?" - without_uploads: "Ja (inkludera inte filer)" download: label: "Ladda ner" title: "Skicka mail med nedladdningslänk" @@ -2845,7 +2849,6 @@ sv: enabled: Aktivera utmärkelse icon: Ikon image: Bild - icon_help: "Använd antingen en Font Awesome-klass eller en URL till en bild" query: Utmärkelsesökning (SQL) target_posts: Sök målets inlägg auto_revoke: Kör återkallelsesökning dagligen diff --git a/config/locales/client.te.yml b/config/locales/client.te.yml index a749495222..9b6d66cd77 100644 --- a/config/locales/client.te.yml +++ b/config/locales/client.te.yml @@ -1179,7 +1179,6 @@ te: backup: title: "బ్యాకప్ సృష్టించు" confirm: "మీరు కొత్త బ్యాకప్ మొదలుపెట్టాలనుకుంటున్నారా?" - without_uploads: "అవులు (దస్త్రాలు కాకుండా)" destroy: title: "బ్యాకప్ తొలగించు" confirm: "మీరు నిజంగానే బ్యాకప్ ను నాశనం చేయాలనుకుంటున్నారా?" @@ -1591,7 +1590,6 @@ te: enabled: బ్యాడ్జి చేతనం చేయి icon: ఐకాన్ image: బొమ్మ - icon_help: "చిత్రానికి బ్రహ్మాండమైన ఫాంట్ లేదా URL గాని ఉపయోగించండి" target_posts: టపాలు లక్ష్యంగా ప్రశ్న show_posts: చిహ్నాల పుటలో మంజూరు అయిన చిహ్నాన్ని చూపండి trigger: ట్రిగ్గరు diff --git a/config/locales/client.th.yml b/config/locales/client.th.yml index 397a1812fa..f748ef0db3 100644 --- a/config/locales/client.th.yml +++ b/config/locales/client.th.yml @@ -309,7 +309,6 @@ th: index: title: "กลุ่ม" empty: "ไม่มีกลุ่มที่เห็นได้" - all_groups: "ทุกกลุ่ม" activity: "กิจกรรม" topics: "กระทู้" posts: "โพสต์" diff --git a/config/locales/client.tr_TR.yml b/config/locales/client.tr_TR.yml index 5d36c9416f..11e7782b04 100644 --- a/config/locales/client.tr_TR.yml +++ b/config/locales/client.tr_TR.yml @@ -395,7 +395,6 @@ tr_TR: all: "Tüm Gruplar" empty: "Görünen hiç bir grup bulunmamaktadır." filter: "Grup tipine göre filtrele" - all_groups: "Tüm Gruplar" close_groups: "Kapanmış Gruplar" automatic_groups: "Otomatik Gruplar" automatic: "Otomatik" @@ -548,7 +547,7 @@ tr_TR: moderator_tooltip: "Bu kullanıcı bir moderatör" admin_tooltip: "Bu kullanıcı bir yönetici." silenced_tooltip: "Bu kullanıcı susturuldu" - suspended_notice: "Bu kullanıcı {{tarih}} tarihine kadar uzaklaştırıldı." + suspended_notice: "Bu kullanıcı {{date}} tarihine kadar uzaklaştırıldı." suspended_permanently: "Bu kullanıcı askıya alındı." suspended_reason: "Neden:" github_profile: "Github" @@ -637,7 +636,6 @@ tr_TR: second_factor: title: "İki Faktörlü Kimlik Doğrulama" disable: "İki faktörlü kimlik doğrulamayı devre dışı bırak" - enable: "gelişmiş hesap güvenliği için" confirm_password_description: "Devam etmek için lütfen şifrenizi onaylayın" enable_description: | Desteklenen bir uygulamada bu QR kodunu tarayın (Android - iOS - Windows Phone) ve kimlik doğrulama kodunuzu girin. @@ -2552,7 +2550,6 @@ tr_TR: label: "Yedek Oluştur" title: "Yedek oluştur" confirm: "Yeni bir yedekleme başlatmak istiyor musunuz?" - without_uploads: "Evet (dosya eklemeyin)" download: label: "İndir" destroy: @@ -3186,7 +3183,6 @@ tr_TR: enabled: Rozeti etkinleştir icon: İkon image: Görsel - icon_help: "Font Awesome sınıfı veya görsel URL'i kullanın" query: Rozet Sorgusu (SQL) target_posts: Sorgu gönderileri hedefliyor auto_revoke: Geri alma sorgusunu her gün çalıştır. diff --git a/config/locales/client.uk.yml b/config/locales/client.uk.yml index dc777d3fd4..11b79ffd5c 100644 --- a/config/locales/client.uk.yml +++ b/config/locales/client.uk.yml @@ -1221,7 +1221,6 @@ uk: confirm: "Are you sure you want to cancel the current operation?" backup: title: "Create a backup" - without_uploads: "Так (не включати файли)" download: label: "Завантажити" destroy: diff --git a/config/locales/client.ur.yml b/config/locales/client.ur.yml index e1e54a4e79..b64fc6829b 100644 --- a/config/locales/client.ur.yml +++ b/config/locales/client.ur.yml @@ -394,7 +394,6 @@ ur: all: "تمام گروپس" empty: "کوئی نظر آنے والے گروپ موجود نہیں ہیں۔" filter: "گروپ قِسم کے حساب سے فِلٹر کریں" - all_groups: "تمام گروپس" owner_groups: "گروپس جن کا میں مالک ہوں" close_groups: "بند گروپس" automatic_groups: "خودکار گروپس" @@ -655,7 +654,6 @@ ur: second_factor: title: "دو فیکٹر توثیق" disable: "دو فیکٹر توثیق غیر فعال کریں" - enable: "بہتر اکاؤنٹ سیکورٹی کیلئے" confirm_password_description: "جاری رکھنے کیلئے براہ کرم اپنے پاسوَرڈ کی تصدیق کریں" label: "کَوڈ" enable_description: | @@ -2722,7 +2720,6 @@ ur: label: "بیک اَپ" title: "بیک اَپ بنائیں" confirm: "کیا آپ نیا بیک اَپ شروع کرنا چاہتے ہیں؟" - without_uploads: "جی ہاں (فائلوں کو شامل نہ کیا جائے)" download: label: "ڈاؤن لوڈ" title: "ڈاؤن لوڈ لنک کے ساتھ اِیمیل بھیجیں" @@ -3450,7 +3447,6 @@ ur: enabled: بَیج فعال کریں icon: آئیکن image: تصویر - icon_help: "تصویر کا URL یا فونٹ اَوسم کلاس استعمال کریں" query: بَیج قُوَیری (SQL) target_posts: ھدف پوسٹس کو قُوَیری کریں auto_revoke: روزانہ رَیوَوکَیشَن قُوَیری چلائیں diff --git a/config/locales/client.vi.yml b/config/locales/client.vi.yml index 9699d70909..2c92ec6195 100644 --- a/config/locales/client.vi.yml +++ b/config/locales/client.vi.yml @@ -1984,7 +1984,6 @@ vi: 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" destroy: @@ -2485,7 +2484,6 @@ vi: 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 diff --git a/config/locales/client.zh_CN.yml b/config/locales/client.zh_CN.yml index 7c8b288d73..61bb1bcc13 100644 --- a/config/locales/client.zh_CN.yml +++ b/config/locales/client.zh_CN.yml @@ -592,7 +592,6 @@ zh_CN: second_factor: title: "双重验证" disable: "停用双重验证" - enable: "为了加强账户安全" confirm_password_description: "确认密码以继续" label: "编码" disable_description: "请输入来自 app 的验证码" @@ -2475,7 +2474,6 @@ zh_CN: label: "备份" title: "建立一个备份" confirm: "你确定要开始建立一个备份吗?" - without_uploads: "是(不包括文件)" download: label: "下载" title: "发送含下载链接的邮件" @@ -3183,7 +3181,6 @@ zh_CN: enabled: 启用徽章系统 icon: 图标 image: 图片 - icon_help: "使用 Font Awesome class 或者图片的链接" query: 徽章查询(SQL) target_posts: 查询到的帖子 auto_revoke: 每天运行撤销查询 diff --git a/config/locales/client.zh_TW.yml b/config/locales/client.zh_TW.yml index 5ab23abc03..e83362e0da 100644 --- a/config/locales/client.zh_TW.yml +++ b/config/locales/client.zh_TW.yml @@ -45,12 +45,16 @@ zh_TW: other: < %{count} 秒 x_seconds: other: '%{count} 秒' + less_than_x_minutes: + other: < %{count} 分鐘 x_minutes: other: '%{count} 分鐘' about_x_hours: other: '%{count} 小時' x_days: other: '%{count} 天' + x_months: + other: '%{count} 月' about_x_years: other: '%{count} 年' over_x_years: @@ -131,8 +135,10 @@ zh_TW: cn_north_1: "中國 (北京)" eu_central_1: "歐洲 (法蘭克福)" eu_west_1: "歐洲 (愛爾蘭)" + eu_west_2: "歐洲 (倫敦)" sa_east_1: "南美洲 (聖保羅)" us_east_1: "美國東部 (北維珍尼亞州)" + us_east_2: "美國東部 (俄亥俄州)" us_gov_west_1: "AWS GovCloud (美國)" us_west_1: "美國西部 (北加州)" us_west_2: "美國西部 (奧勒岡州)" @@ -140,6 +146,7 @@ zh_TW: not_implemented: "抱歉,此功能尚未開放。" no_value: "否" yes_value: "是" + submit: "提交" generic_error: "抱歉,發生錯誤。" generic_error_with_reason: "發生錯誤: %{error}" sign_up: "註冊" @@ -188,6 +195,8 @@ zh_TW: our_moderators: "我們的版主" stat: all_time: "所有時間" + last_7_days: "最近 7 天" + last_30_days: "最近 30 天" like_count: "讚" topic_count: "討論話題" post_count: "文章" @@ -296,14 +305,29 @@ zh_TW: groups: add_members: title: "新增成員" + description: "管理這個群組的成員" usernames: "使用者名稱" manage: title: '管理' + name: '名稱' full_name: '全名' add_members: "新增成員" delete_member_confirm: "從 '\b%{group}‘ 群組移除 '%{username}''?" profile: title: 個人資料 + interaction: + notification: 通知 + membership: + title: 會員資格 + logs: + title: "記錄" + when: "時間" + action: "動作" + target_user: "目標使用者" + subject: "主旨" + details: "詳情" + from: "從" + to: "到" empty: posts: "群組成員沒有發佈帖子。" members: "這個團隊裡面沒有成員" @@ -312,10 +336,14 @@ zh_TW: topics: "群組的成員從未發表主題。" logs: "這個團隊裡面沒有日誌" add: "新增" + join: "加入" leave: "離開" request: "請求" message: "訊息" allow_membership_requests: "允許使用者向群組擁有者傳送加入要求?" + membership_request: + submit: "提交請求" + title: "請求加入 @%{group_name}" membership: "會員資格" name: "名字" group_name: "群組名稱" @@ -327,19 +355,32 @@ zh_TW: title: "群組" all: "所有群組" empty: "沒有可看見的群組。" - all_groups: "所有群組" + owner_groups: "我是擁有者的群組" + close_groups: "已關閉的群組" + automatic_groups: "自動群組" + automatic: "自動" + closed: "已關閉" + public: "公開" private: "私密" public_groups: "公開群組" + automatic_group: 自動群組 + close_group: 關閉群組 my_groups: "我的群組" + group_type: "群組類型" + is_group_user: "成員" is_group_owner: "擁有者" title: other: 群組 activity: "活動" members: + title: "成員" filter_placeholder_admin: "使用者名稱或電子郵件" filter_placeholder: "使用者名稱" remove_member: "移除成員" + remove_member_description: "從這個群組移除 %{username}" make_owner: "設置為擁有者" + make_owner_description: "設置 %{username} 為這個群組的擁有者" + owner: "擁有者" topics: "主題" posts: "文章" mentions: "提及" @@ -445,6 +486,7 @@ zh_TW: activity_stream: "活動" preferences: "偏好設定" expand_profile: "展開" + collapse_profile: "收合" bookmarks: "書籤" bio: "關於我" invited_by: "邀請人" @@ -466,6 +508,8 @@ zh_TW: first_notification: "你的頭一個通知!選中它開始。" disable_jump_reply: "不要在回覆之後直接跳到我的文章" dynamic_favicon: "在瀏覽器小圖示上顯示新主題/更新的主題數" + theme_default_on_all_devices: "在我所有的裝置上將此設為預設佈景" + allow_private_messages: "允許其他使用者寄送個人訊息給我" external_links_in_new_tab: "以新分頁開啟所有外部連結" enable_quoting: "允許引用已標註的文字" change: "修改" @@ -474,6 +518,7 @@ zh_TW: moderator_tooltip: "此用戶為板主" admin_tooltip: "此用戶為管理員" suspended_notice: "此用戶已被停權至 {{date}}。" + suspended_permanently: "此用戶已被停權。" suspended_reason: "原因: " github_profile: "Github" email_activity_summary: "活動摘要" @@ -488,14 +533,14 @@ zh_TW: many_per_day: "每當有新文章時,寄給我郵件通知(每天約有 {{dailyEmailEstimate}} 封)。" few_per_day: "每當有新文章時,寄給我郵件通知(每天約有 2 封)。" tag_settings: "標籤" - watched_tags: "已觀看" - watched_tags_instructions: "您將會自動監視所有這些添加的主題。您會收到新文章或新主題的通知,新文章數量將出現在每個主題後。" + watched_tags: "已關注" + watched_tags_instructions: "您將會自動關注該標籤中的所有主題。您會收到新文章或新主題的通知,新文章數量將出現在每個主題後。" tracked_tags: "已追蹤" tracked_tags_instructions: "您將會自動監視所有這些添加的主題。新文章數量將出現在每個主題後。" muted_tags: "靜音" muted_tags_instructions: "你將不會收到有這些標籤的新主題任何通知,它們也不會出現在“最新”主題列表。" - watched_categories: "關注" - watched_categories_instructions: "你將自動監看這些分類中的所有主題。所有新帖子和新主題會通知你,新帖數量也將顯示在主題旁邊。" + watched_categories: "已關注" + watched_categories_instructions: "你將自動關注這些分類中的所有主題。所有新帖子和新主題會通知你,新帖數量也將顯示在主題旁邊。" tracked_categories: "追蹤" tracked_categories_instructions: "你將自動跟蹤這些分類中的所有主題。新帖數量將會顯示在主題旁邊。" watched_first_post_categories: "關注第一則帖子" @@ -513,12 +558,13 @@ zh_TW: muted_users: "靜音" muted_users_instructions: "禁止來自這些用戶的所有通知。" muted_topics_link: "顯示已靜音的主題" - watched_topics_link: "顯示已觀看的討論話題" + watched_topics_link: "顯示已關注的討論話題" automatically_unpin_topics: "當我完整閲讀了主題時自動解除置頂。" apps: "應用" revoke_access: "撤銷許可" undo_revoke_access: "解除撤銷許可" api_approved: "已批准:" + theme: "佈景" home: "預設首頁" staff_counters: flags_given: "有幫助的投訴" @@ -537,6 +583,7 @@ zh_TW: move_to_archive: "封存" failed_to_move: "移動到所選郵件失敗(也許你的網絡沒有開啟)" select_all: "選擇全部" + tags: "標籤" preferences_nav: account: "帳號" profile: "基本資料" @@ -555,6 +602,9 @@ zh_TW: choose_new: "選擇一個新密碼" choose: "選擇一個密碼" second_factor: + title: "兩步驟驗證" + disable: "停用兩步驟驗證" + enable: "啟用兩步驟驗證來增加帳號安全性" disable_description: "請從您的應用程式輸入驗證碼" show_key_description: "手動輸入" change_about: @@ -723,14 +773,19 @@ zh_TW: title: "摘要" stats: "統計" time_read: "閱讀時間" + recent_time_read: "最近的閱讀時間" topic_count: other: 討論話題已建立 post_count: other: 帖子已建立 + likes_given: + other: 已送出 likes_received: other: 已接收 days_visited: other: 到訪天數 + topics_entered: + other: 已讀討論話題 posts_read: other: 讀過的文章 bookmark_count: @@ -760,6 +815,7 @@ zh_TW: header_title: "個人頁面、消息、書籤和設置" title: title: "頭銜" + none: "(無)" filters: all: "全部" stream: @@ -817,6 +873,8 @@ zh_TW: mute: 靜音 unmute: 取消靜音 time_read: 已讀 + time_read_recently: '最近' + time_read_recently_tooltip: '%{time_read} 總共閱讀時間 (%{recent_time_read} 在最近 60 天)' last_reply_lowercase: 最新回覆 replies_lowercase: other: 回覆 @@ -870,6 +928,7 @@ zh_TW: title: "登入" username: "用戶" password: "密碼" + second_factor_title: "兩步驟驗證" email_placeholder: "電子郵件地址或用戶名稱" caps_lock_warning: "大寫鎖定中" error: "未知的錯誤" @@ -1038,6 +1097,7 @@ zh_TW: empty: "未找到任何通知。" more: "檢視較舊的通知" total_flagged: "所有被投訴的文章" + granted_badge: "得到 '{{description}}'" popup: mentioned: '{{username}}在“{{topic}}”提到了你 - {{site_title}}' group_mentioned: '{{username}}在“{{topic}}”提到了你 - {{site_title}}' @@ -1089,7 +1149,7 @@ zh_TW: filters: likes: 我給了讚的 posted: 我參與發帖 - watching: 我正在監看 + watching: 我正在關注 tracking: 我正在追蹤 first: 是第一帖 pinned: 是置頂的 @@ -1239,12 +1299,16 @@ zh_TW: title: 改變你收到該主題通知的頻率 reasons: mailing_list_mode: "郵件列表模式已啟用,將以郵件通知你關於該主題的回覆。" - "3_10": '因為你正監看該主題上的標籤,你將會收到通知。' + "3_10": '因為你正關注該主題上的標籤,你將會收到通知。' "3_6": '你將會收到通知,因為你正在關注此分類。' - "3_5": '你將會收到通知,因為你在觀看此討論話題。' + "3_5": '你將會收到通知,因為你自動關注此討論話題。' "3_2": '你將收到關於此討論話題的通知,因為你正在關注此討論話題。' "3_1": '你將收到關於此討論話題的通知,因為你建立了此討論話題。' "3": '你將收到關於此討論話題的通知,因為你正在關注此討論話題。' + "2_8": '您將會看到新回覆的數量,因為你正在追蹤這個分類。' + "2_4": '您將會看到新回覆的數量,因為你回覆了此討論話題。' + "2_2": '您將會看到新回覆的數量,因為你正在追蹤這個話題。' + "2": '您將會看到新回覆的數量,因為你看過這個話題。' "1_2": '如果有人@你或回覆你,將通知你。' "1": '如果有人@你或回覆你,將通知你。' "0_7": '你正忽略此分類中的所有通知。' @@ -1618,7 +1682,7 @@ zh_TW: notifications: watching: title: "關注" - description: "你將自動監看這些分類中的所有主題。每一個主題的每一個新帖,將通知你,還將顯示新回覆的數量。" + description: "你將自動關注這些分類中的所有主題。每一個主題的每一個新帖,將通知你,還將顯示新回覆的數量。" watching_first_post: title: "關注新的發文" description: "在這些分類裡面,只是每一個新主題的第一帖,才會通知你。" @@ -1877,6 +1941,7 @@ zh_TW: granted: other: '%{count} 授予' select_badge_for_title: 選擇一個徽章作為你的頭銜使用 + none: "(無)" badge_grouping: getting_started: name: 開始 @@ -1918,7 +1983,8 @@ zh_TW: untagged_with_category: "%{category}無標籤的%{filter}主題" notifications: watching: - title: "監看" + title: "關注" + description: "你將自動監看該標籤中的所有主題。新帖子和新主題會通知你,再者未讀和新帖的數量也將顯示在主題旁邊。" watching_first_post: title: "關注新的發文" tracking: @@ -2054,6 +2120,9 @@ zh_TW: was_edited: "文章已在第一次標記後被編輯" previous_flags_count: "這篇文章已經被標記 {{count}} 次。" groups: + manage: + membership: + trust_levels_none: "無" primary: "主要群組" no_primary: "( 沒有主要群組 )" title: "群組" @@ -2197,7 +2266,6 @@ zh_TW: label: "備份" title: "新增備份" confirm: "你確定要新增備份嗎?" - without_uploads: "是 ( 不包含檔案 )" download: label: "下載" destroy: @@ -2236,6 +2304,7 @@ zh_TW: new_style: "新增樣式" import: "匯入" delete: "刪除" + delete_confirm: "刪除這個佈景?" about: "修改網站的 CSS 和 HTML headers。請新增一個自定樣式來開始使用。" color: "顏色" opacity: "不透明度" @@ -2248,6 +2317,9 @@ zh_TW: none_selected: "選擇一個電子郵件範本開始編輯" revert: "恢復變更" revert_confirm: "你確定要恢復這個變更?" + theme: + import_theme: "匯入佈景" + title: "佈景" colors: title: "顏色" long_title: "顏色樣式" @@ -2417,6 +2489,7 @@ zh_TW: change_readonly_mode: "變更唯讀模式" backup_download: "下載備份" backup_destroy: "刪除備份" + disabled_second_factor: "停用兩步驟驗證" screened_emails: title: "過濾的電子郵件地址" description: "以下的電子郵件地址將無法用來建立新用戶。" @@ -2449,6 +2522,8 @@ zh_TW: title: "如果有至少 'min_ban_entries_for_roll_up' 個記錄,建立一個子網域封鎖記錄" logster: title: "錯誤紀錄" + watched_words: + title: "已關注的文字" impersonate: title: "檢視角度" help: "使用此工具以用戶的檢視角度進行除錯。完成後將需登出。" @@ -2667,6 +2742,7 @@ zh_TW: show_overriden: '只顯示修改過的項目' settings: reset: '重置' + none: '無' site_settings: title: '設定' no_results: "未找到任何結果。" @@ -2736,7 +2812,6 @@ zh_TW: enabled: 啟用徽章 icon: 圖示 image: 圖片 - icon_help: "使用 Font Awesome class 或者圖片的聯結" query: 徽章查詢語法 (SQL) target_posts: 查詢文章張貼目標 auto_revoke: 每日執行撤銷用的 SQL 語法 diff --git a/config/locales/server.ar.yml b/config/locales/server.ar.yml index 3b58888287..5e5335b5af 100644 --- a/config/locales/server.ar.yml +++ b/config/locales/server.ar.yml @@ -753,9 +753,7 @@ ar: xaxis: "اليوم" yaxis: "مرّات الزّيارة" signups: - title: "المستخدمون الجدد" xaxis: "اليوم" - yaxis: "عدد المستخدمين الجدد" profile_views: title: "مشاهدات الحساب الشخصي للعضو" xaxis: "اليوم" diff --git a/config/locales/server.bg.yml b/config/locales/server.bg.yml new file mode 100644 index 0000000000..5f42a58a84 --- /dev/null +++ b/config/locales/server.bg.yml @@ -0,0 +1,1341 @@ +# 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/ + +bg: + 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: [~, January, February, March, April, May, June, July, August, September, October, November, December] + <<: *datetime_formats + time: + <<: *datetime_formats + title: "Discourse" + topics: "Теми" + posts: "публикации" + loading: "Зареждане" + log_in: "Вход" + submit: "Изпрати" + purge_reason: "Автоматично изтрит като изоставен, неактивен акаунт" + disable_remote_images_download_reason: "Изтеглянето на отдалечени изображения беше изключено, защото няма достатъчно място на хард диска." + anonymous: "Анонимен" + remove_posts_deleted_by_author: "Изтрит от автора" + themes: + other_error: "Нещо се обърка при актуализирането на стила" + emails: + incoming: + default_subject: "Тази тема има нужда от заглавие" + show_trimmed_content: "Показване на съкратеното съдържание" + errors: + empty_email_error: "Се случва, когато raw имейла който получихме беше празен." + no_message_id_error: "Се случва, когато имейла няма 'Message-Id' хедър." + inactive_user_error: "Се случва, когато изпращача не е активен." + errors: &errors + format: '%{attribute} %{message}' + messages: + too_long_validation: "е ограничен на %{max} символа ; вие въведохте %{length}." + invalid_boolean: "Невалиден булев." + taken: "е вече заето" + accepted: трябва да се приеме + blank: не може да бъде празно + present: трябва да се попълни + confirmation: "не съвпада %{attribute}" + empty: не може да бъде празно + equal_to: "трябва да бъде равно на %{count}" + even: трябва да бъде равен + exclusion: е запазено + greater_than: "трябва да бъде по-голямо от %{count}" + greater_than_or_equal_to: "трябва да бъде по-голямо или равно на %{count}" + has_already_been_used: "вече е бил използван" + inclusion: не е включено в списъка + invalid: не невалидно + less_than: "трябва да бъде по-малко от %{count}" + less_than_or_equal_to: "трябва да бъде по-малко или равно на %{count}" + not_a_number: не е число + not_an_integer: трябва да бъде число + odd: трябва да е нечетно + record_invalid: 'Валидирането е неуспешно %{errors}' + restrict_dependent_destroy: + one: "Записът не може да бъде изтрит, защото е зависим от съществуващите %{record}" + many: "Записът не може да бъде изтрит, защото е зависим от съществуващите %{record}" + too_long: + one: прекалено дълго (трябва да бъде само 1 символ) + other: е прекалено дълго (максималния брой символи е %{count}) + too_short: + one: прекалено кратко (минимума е 1 символ) + other: е прекалено кратко (миниума е %{count} символи) + wrong_length: + one: е с грешна дължина (трябва да бъде поне 1 символ) + other: е с грешна дължина (трябва да бъде %{count} символа) + other_than: "трябва да бъде различно от %{count}" + template: + body: 'Имаше проблеми със следните полета:' + header: + one: 1 грешка възпрепятства запазването на този %{model} + other: '%{count} грешки възпрепятстват запазването на този %{model} ' + embed: + load_from_remote: "Получи се грешка при зареждането на тази публикация." + activemodel: + errors: + <<: *errors + topic_invite: + user_exists: "Съжеляваме, но този потребител е вече поканен. Вие можете да каните потребител за дадена тема само веднъж." + backup: + 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: "Сайтът в режим само за четене. Действията са непозволени." + reading_time: "Време за четене" + likes: "Харесвания" + too_many_replies: + one: Съжаляваме, но новите потребители са временно са ограничени до 1 отговор във същата публикация. + other: Съжаляваме, но новите потребители са временно са ограничени до %{count} отговори в същата публикация. + embed: + start_discussion: "Започване на дискусия " + continue: "Продължаване на дискусия" + more_replies: + one: още един отговор + other: '%{count} повече отговори' + loading: "Зареждане на дискусия..." + permalink: "Постоянен адрес" + imported_from: "Това е упътваща дискусионна тема за първоначалното влизане в %{link}" + in_reply_to: "▶ %{username}" + replies: + one: 1 отговор + other: '%{count} отговори' + no_mentions_allowed: "Съжаляваме, не може да споменавате други потребители." + too_many_mentions: + one: Съжеляваме, можете да споменавате само един потребител в публикация. + other: Съжаляваме, можете да споменете само %{count} потребители в публикацията. + no_mentions_allowed_newuser: "Съжаляваме, новите потребите не могат да споменават други потребители." + too_many_mentions_newuser: + one: Съжаляваме, новите потребители могат да споменават само един друг потребител в публикацията. + other: Съжаляваме, новите потребители могат да споменават само %{count} потребители в публикацията. + no_images_allowed: "Съжаляваме, новите потребители не могат да поставят изображения в публикациите." + too_many_images: + one: Съжаляваме, новите потребители могат да поставят само едно изображение в публикацията. + other: Съжаляваме, новите потребители могат да поставят само по %{count} изображения в публикацията. + no_attachments_allowed: "Съжаляваме, новите потребители не могат да поставят приставки в публикациите." + too_many_attachments: + one: Съжаляваме, новите потребители могат да поставят само по една приставка в публикацията. + other: Съжаляваме, новите потребители могат да поставят %{count} приставки в публикацията. + no_links_allowed: "Съжаляваме, новите потребители не могат да поставят линкове в публикациите." + links_require_trust: "Съжаляваме, не може да включвате линкове в публикациите си." + too_many_links: + one: Съжаляваме, новите потребители могат да поставят само по един линк в публикация. + other: Съжаляваме, новите потребители могат да поставят само %{count} линкове в публикация. + contains_blocked_words: "Публикацията ви съдържа непозволена дума: %{word}" + spamming_host: "Съжаляваме, не можете да публикувате линк на този хост." + user_is_suspended: "Отстранените потребители нямат право да публикуват." + topic_not_found: "Нещо не е наред. Може би тази тема е била затворена или изтрита, докато я гледате." + just_posted_that: "твърде подобно е на това което скоро сте публикували" + invalid_characters: "съдържа невалидни знаци" + next_page: "следваща страница →" + prev_page: "← предишна страница" + page_num: "Страница %{num}" + home_title: "Начало" + 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: "Прочети цялата тема" + private_message_abbrev: "Съобщение" + rss_description: + latest: "Последни теми" + hot: "Горещи теми" + top: "Топ теми" + top_all: "Топ теми за всички времена" + top_yearly: "Годишни топ теми" + top_quarterly: "Тримесечни топ теми" + top_monthly: "Месечни топ теми" + top_weekly: "Седмични топ теми" + top_daily: "Дневни топ теми" + 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: "Изтрит чрез опашката за медериране на публикации." + groups: + errors: + 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: "персонал" + 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: + one: 1 публикация + other: '%{count} публикации' + 'new-topic': | + Добре дошли в %{site_name} — **Благодарим ви за създаването на нова тема!** + + - Заглавието и звучи ли ви интересно като го прочетете на глас?Достатъчно описващо ли е? + + - На кого би била интересна тази тема? Защо е важна за обсъждане? Каква реакция от останалите потребители очаквате? + + - Постарайте се да включите в заглавието лесни за намиране думи/фрази. Изберете подходяща по смисъл категория към която вашата тема да принадлежи. + + За повече информация, вижте нашето [ръководство на потребителя] (/guidelines). Този панел ще изчезне след като създадете първата си публикация %{education_posts_text}. + 'new-reply': | + Добре дошли в %{site_name} — **Благодарим Ви за съдействието!** + + - Вашият отговор допринася ли за разговора по някакъв начин? + + - Бъдете любезен с вашите колеги от общността. + + - Конструктивната критика е добре дошла, но когато се критикуват *идеи*, не хора. + + За повече информация [виж Правилата на Общността](/guidelines). Този панел ще бъде видим до вашето първо %{education_posts_text}. + activerecord: + attributes: + category: + name: "Име на категорията" + topic: + title: 'Заглавие' + post: + raw: "Тяло" + user_profile: + bio_raw: "За мен" + errors: + <<: *errors + models: + topic: + attributes: + base: + too_many_users: "Можете да изпращате предупреждения само до един потребител в даден момент." + no_user_selected: "Трябва да изберете валиден потребител." + user: + attributes: + password: + common: "е една от 10000 най-често използвани пароли. Моля използвайте по-сигурна парола." + same_as_username: "е същата като вашето потребителско име. Моля използвайте по-сигурна парола." + same_as_email: "е същата като вашия email. Моля използвайте по-сигурна парола." + ip_address: + signup_not_allowed: "Вписването не е разрешено от този акаунт." + color_scheme_color: + attributes: + hex: + invalid: "този цвят не е валиден " + user_profile: + no_info_other: "
    %{name} в полето За мен на техния профил все още не е въвъдено нищо
    " + vip_category_name: "Салон" + vip_category_description: "Категоята е само за членове с ниво на доверие 3 и по-високо." + meta_category_name: "Заявка към сайта" + meta_category_description: "Дискусия за сайта, неговата организация, как той работи, и как можем да го подобрим." + staff_category_name: "Персонал" + staff_category_description: "Частна категория за дискусии на персонала. Темите са видими само за админи и модератори." + lounge_welcome: + title: "Добре дошли в Салона" + body: |2 + + Честито! :confetti_ball: + + Ако можете да видите тази тема, вие сте повишен в **редовен** (trust level 3) + + Сега Вие можете … + + * Да променяте заглавието на всяка тема + * Да сменяте категорията на всяка тема + * Имате си свои последователи ([automatic nofollow](http://en.wikipedia.org/wiki/Nofollow) is removed) + * Имате достъп до частната Lounge категория, видима само за потребители от trust level 3 и по-високо + * Скриване на спама с един сигнал + + Ето и [current list of fellow regulars](/badges/3/regular). Не забравяйте да кажете здрасти. + + Благодарим Ви за това, че сте важна част от тази общност! + + (За повече информация относно trust levels, [see this topic][trust]. Моля имайте впредвид, че редовни остават само членовете, които с течение на времето продължават да отговарят на изискванията.) + + [trust]: https://meta.discourse.org/t/what-do-user-trust-levels-do/4924 + category: + topic_prefix: "За %{category} категория" + errors: + uncategorized_parent: "Некатегоризиран не може да има основна категория" + self_parent: "Една подкатегория не може да бъде родител сама на себе си." + depth: "Не можете да създадете една подкатегория под друга такава" + 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: + one: Не можете да изтриете тази категория, защото има 1 тема. Най-старата тема е %{topic_link}. + other: 'Не можете да изтриете тази категория, защото има %{count} теми. Най-старата тема е %{topic_link}. ' + topic_exists_no_oldest: "Не можете да изтриете тази категория, защото броят на темите е %{count}." + trust_levels: + newuser: + title: "нов потребител" + basic: + title: "основен потребител" + member: + title: "потребител" + regular: + title: "редовен" + leader: + title: "лидер" + change_failed_explanation: "Опитахте се да понижите %{user_name} на '%{new_trust_level}'. Обаче тяхното ниво на доверие е вече '%{current_trust_level}'. %{user_name} ще остане на '%{current_trust_level}' - ако искате да понижите потребителското ниво, ниво на доверие първо" + rate_limiter: + by_type: + 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: + one: 1 час + other: '%{count} часове ' + minutes: + one: 1 минута + other: '%{count} минути ' + seconds: + one: 1 секунда + other: '%{count} секунди ' + datetime: + distance_in_words: + half_a_minute: "< 1m" + less_than_x_seconds: + one: < 1с + 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_months: + one: '1mon ' + other: '%{count}mon' + x_months: + one: '1mon ' + other: '%{count}mon ' + about_x_years: + one: '1y ' + other: '%{count}y ' + over_x_years: + one: '> 1y ' + other: '> %{count}y ' + almost_x_years: + one: 1y + other: '%{count}y' + distance_in_words_verbose: + half_a_minute: "преди малко" + less_than_x_seconds: + one: преди малко + other: преди малко + x_seconds: + one: преди 1 секунда + other: преди %{count} секунди + less_than_x_minutes: + one: по малко от 1 минута + other: преди по-малко от %{count} минути + x_minutes: + one: преди 1 минута + other: преди %{count} минути + about_x_hours: + one: преди 1 час + other: преди %{count} часа + x_days: + one: преди 1 ден + other: преди %{count} дни + about_x_months: + one: преди около 1 месец + other: преди около %{count} месеца + x_months: + one: преди 1 месец + other: преди %{count} месеца + about_x_years: + one: преди около 1 година + other: 'преди около %{count} години ' + over_x_years: + one: 'преди повече от 1 година ' + other: 'преди повече от %{count} години ' + almost_x_years: + one: преди почти 1 година + other: преди почти %{count} години + password_reset: + update: 'Обновете паролата' + save: 'Задайте парола' + title: 'Смяна на паролата' + success: "Вие успешно променихте вашата парола и в момента сте логнати." + success_unapproved: "Вие успешно променихте вашата парола." + change_email: + confirmed: "Вашият имейл беше актуализиран." + please_continue: "Продължете към %{site_name}" + error: "Възникна грешка при промяната на вашия имейл адрес. Може би адресът вече се използва?" + authorizing_old: + title: "Благодаря че потвърдихте имейл адреса си" + activation: + action: "Кликнете тук, за да активирате вашия профил" + already_done: "Съжаляваме, този линк за потвърждаване на акаунта вече е невалиден. Може би вашият акаунт е вече активен?" + please_continue: "Вашият нов акаунт е вече потвърден; ще бъдете пренасочени към началната страница." + continue_button: "Продължете към %{site_name}" + welcome_to: "Добре дошли в %{site_name}!" + approval_required: "Акаунтът Ви трябва да бъде одобрен от модератор преди да получите достъп до този форум. Ще получите имейл когато акаунтът Ви е одобрен!" + post_action_types: + off_topic: + title: 'Оф-топик' + description: 'Тази публикация не е уместна за текущата дискусия, нейното заглавие и първа публикация, и трябва да бъде преместена на друго място.' + long_form: 'Маркирахте това като оф-топик' + spam: + title: 'Спам' + long_form: 'маркирахте това като спам' + email_title: '"%{title}" беше маркиран като спам' + email_body: "%{link}\n\n%{message}" + inappropriate: + title: 'Неприлично' + description: 'Този пост има съдържание, което всеки разумен човек би сметнал за обидно и оскърбително of Правилата на Общността.' + long_form: 'Маркирахте това като неприлично' + notify_user: + title: 'Изпрати съобщение до @{{username}}' + long_form: 'оведомен потребител' + email_title: 'Вашата публикация в "%{title}"' + email_body: "%{link}\n\n\n%{message}" + notify_moderators: + title: "Нещо друго" + long_form: 'сигнал до шефовете' + email_title: 'Постът "%{title}" изисква вниманието на човек от екипа' + email_body: "%{link}\n\n%{message}" + bookmark: + title: 'Отметка' + description: 'Добавете тази публикация в Отметки' + long_form: 'Добавихте тази публикация в Отметки' + like: + title: 'Харесвам' + description: 'Харесайте тази публикация' + long_form: 'харесаха това' + vote: + title: 'Гласуване' + description: 'Гласувайте за тази публикация' + long_form: 'Вие гласувахте за тази публикация' + topic_flag_types: + spam: + title: 'Спам' + description: 'Този пост е реклама.Той е промоционален, не е полезен или не се отнася към текущата тема.' + long_form: 'маркирахте това като спам' + inappropriate: + title: 'Неприлично' + description: 'Този пост има съдържание, което всеки разумен човек би сметнал за обидно и оскърбително , или нарушава of виж Правилата на Общността.' + long_form: 'Маркирано като неприлично' + notify_moderators: + title: "Нещо друго" + long_form: 'сигнал до модератор' + email_title: 'Постът "%{title}" изисква вниманието на модератор' + email_body: "%{link}\n\n\n%{message}" + flagging: + user_must_edit: '

    За тази публикация беше сигнализирано от общността и е временно скрита. .

    ' + archetypes: + regular: + title: "Редовна Тема" + banner: + title: "Банер тема" + message: + make: "Тази тема сега е банер. Тя ще се появява най-отгоре на всяка страница докато не бъде премахната от потребителя." + remove: "Тази тема вече не е банер. Тя няма да се появява повече най-отгоре на всяка страница." + reports: + visits: + title: "Потребителски посещения " + xaxis: "Ден" + yaxis: "Брой на посещенията" + signups: + xaxis: "Ден" + profile_views: + title: "Гледания на потребителският профил" + xaxis: "Ден" + yaxis: "Брой на видяни потребителски профили" + topics: + title: "Теми" + xaxis: "Ден" + yaxis: "Брой нови теми." + posts: + title: "Публикации" + xaxis: "Ден" + yaxis: "Брой нови публикации." + likes: + title: "Харесвания" + xaxis: "Ден" + yaxis: "Брой нови харесвания" + flags: + title: "Сигнали" + xaxis: "Ден" + yaxis: "Брой сигнали" + bookmarks: + title: "Отметки" + xaxis: "Ден" + yaxis: "Брой нови отметки" + starred: + title: "Любими" + xaxis: "Ден" + yaxis: "Брой нови любими теми" + users_by_trust_level: + title: "Потребители с Ниво на доверие" + xaxis: "Ниво на Доверие" + yaxis: "Брой потребители" + emails: + title: "Имейлите са изпратени" + xaxis: "Ден" + yaxis: "Брой имейли" + user_to_user_private_messages: + 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: "Потребител" + num_clicks: "Кликвания" + num_topics: "Теми" + top_traffic_sources: + title: "Топ източници на трафик " + xaxis: "Домейн" + num_clicks: "Кликвания" + num_topics: "Теми" + num_users: "Потребители" + top_referred_topics: + title: "Top Посочени Теми " + xaxis: "Тема" + num_clicks: "Кликвания" + page_view_anon_reqs: + title: "Анонимен" + xaxis: "Ден" + page_view_logged_in_reqs: + title: "Вписани" + xaxis: "Ден" + page_view_crawler_reqs: + title: "Роботи" + xaxis: "Ден" + page_view_total_reqs: + xaxis: "Ден" + page_view_logged_in_mobile_reqs: + xaxis: "Ден" + page_view_anon_mobile_reqs: + xaxis: "Ден" + http_background_reqs: + title: "Фон" + xaxis: "Ден" + yaxis: "Заявки използвани за обновяване и проследяване в реално време" + http_2xx_reqs: + title: "Статус 2xx (OK)" + xaxis: "Ден" + yaxis: "Успешни заявки (Статус 2xx)" + http_3xx_reqs: + title: "HTTP 3xx (Redirect)" + xaxis: "Ден" + yaxis: "Редирект заявки (Status 3xx)" + http_4xx_reqs: + title: "HTTP 4xx (Client Error)" + xaxis: "Ден" + yaxis: "Client Errors (Status 4xx)" + http_5xx_reqs: + title: "HTTP 5xx (Server Error)" + xaxis: "Ден" + yaxis: "Server Errors (Status 5xx)" + http_total_reqs: + title: "Общо" + xaxis: "Ден" + yaxis: "Общо заявки" + time_to_first_response: + title: "Време до първия отговор" + xaxis: "Ден" + yaxis: "Средно време (часове)" + topics_with_no_response: + title: "Теми без отговор" + xaxis: "Ден" + yaxis: "Общо" + mobile_visits: + title: "Потребителски посещения " + xaxis: "Ден" + yaxis: "Брой на посещенията" + dashboard: + rails_env_warning: "Вашият сървър е в % {env} режим." + host_names_warning: "Вашият config/database.yml файл използва по подразбиране localhost за hostname. Обновете, за да използва името на вашия сайт за hostname. " + gc_warning: 'Вашият сървър използва default ruby garbage collection parameters, които не Ви гарантират най-добрата производителност. Прочетете тази тема за настройки Tuning Ruby and Rails for Discourse.' + sidekiq_warning: 'Sidekiq не работи. Много задачи, като изпращане на имейли, се изпълняват несинхронизирано от sidekiq. Моля убедете се, че поне един процес sidekiq работи. Научете повече за Sidekiq тук.' + memory_warning: 'Вашият сървър използва по-малко от 1 ГБ от общата памет. Препоръчва се най-малко 1 ГБ.' + google_oauth2_config_warning: 'Сървърът е конфигуриран да позволи регистрация и вписване с Google OAuth2 (enable_google_oauth2_logins), но client id и client secret values не са определени. Отидете на Настройките на сайта и актуализирайте настройките. За повече информация вижте тук.' + facebook_config_warning: 'Сървърът е конфигуриран да позволи регистрация и вписване с Facebook (enable_facebook_logins), app id и app secret values не са изпратени. Отидете на Настройките на сайта и обновете настройките.За повече информация вижте тук.' + twitter_config_warning: 'Сървърът е конфигуриран да позволи регистрация и вписване със Twitter (enable_twitter_logins),но the key and secret values не са изпратени. Отидете на Настройките на сайта и обновете настройките. За повече информация вижте тук.' + github_config_warning: 'Сървърът е конфигуриран да позволи регистрация и вписване с GitHub (enable_github_logins), но client id и secret values не са изпратени. Отидете на Настройките на сайта и обновете настройкитеЗа повече информация вижте тук.' + image_magick_warning: 'Сървърът е конфигуриран за създаване на умалени изображения на оригиналните, но ImageMagick не е инсталиран. Инсталирайте ImageMagick използвайки вашия системен мениджър или изтеглете най-новата версия.' + subfolder_ends_in_slash: "Вашата настройка за подпапка е неправилна; DISCOURSE_RELATIVE_URL_ROOT завършва с наклонена черта." + site_settings: + censored_words: "Думите които ще бъдат автоматично заменени с ■■■■" + delete_old_hidden_posts: "Автоматично изтриване на всички скрити постове, които остават скрити за повече от 30 дни." + allow_user_locale: "Позволи на потребителите да избират език на интерфейса" + min_post_length: "Минимално допустимо количество символи в едно съобщение" + min_first_post_length: "Минимално допустими символи в първата публикация (тялото на темата)." + max_post_length: "Максимално допустимо количество символи в едно съобщение" + min_topic_title_length: "Минимално допустимо количество символи в името на темата" + max_topic_title_length: "Максимално допустимо количество символи в името на темата" + min_search_term_length: "Минимално допустимо количество символи в заявката за търсене" + allow_uncategorized_topics: "Позволи създаването на теми без категория. ВНИМАНИЕ: Ако има някакви не категоризирани теми, трябва да ги категоризирате, преди да изключите тази опция." + allow_duplicate_topic_titles: "Позволи теми с идентични, дублиращи се заглавия." + unique_posts_mins: "Колко минути са необходими, за да може потребителя да направи отново публикация със същото съдържание" + educate_until_posts: "Когато потребителят започне да пише своите първи (n) публикации, покажи поп-ъп панела за \"обучение на нови потребители\" в \"composer\" панела. " + title: "Наименованието на този сайт , както е използвано в заглавния маркер." + site_description: "Опишете този сайт с едно изречение като използвате мета описателен таг." + contact_url: "Контакт URL за този сайт. Използва се в /about контакт формата при спешни случаи." + crawl_images: "Възстановете изображенията от отдалечения URLs, за да въведете размери с правилната дължина и ширина." + download_remote_images_to_local: "Конвертирайте отдалечените изображения в местни изображения като ги свалите; това ще предотврати повредата им." + download_remote_images_threshold: "Минимум необходимо дисково пространство за изтеглянето на отдалечените изображения ( в проценти)" + disabled_image_download_domains: "Отдалечените изображения никога няма да бъдат изтеглени от тези домейни. Разделен със знака \"|\" списък." + post_edit_time_limit: "Авторът може да промени или изтрие своя пост (n) минути след публикацията. Задайте 0 за постоянно." + edit_history_visible_to_public: "Позволи на всички потребители да видят предишните версии на публикацията. Ако е деактивитано, историята на публикациите ще бъде видима само за членовете на персонала. " + delete_removed_posts_after: "Публикации, които са премахнати от автор ще бъдат автоматично изтрити след (n) часа. Ако е зададено 0, публикациите ще бъдат изтрити веднага." + max_image_width: "Максимална ширина на умалените изображения в публикацията" + max_image_height: "Максимална височина на умалените изображения в публикаципта" + fixed_category_positions: "Ако е отметнато, ще можете да подредите категориите в определен ред. Ако не е, категориите ще бъдат подредени според нивото им на активност." + fixed_category_positions_on_create: "Ако е избрано, подредвата на категориите ще се запази и в диалоговия прозорец за създаване на тема (изисква fixed_category_positions)." + add_rel_nofollow_to_user_content: "Добави \"rel nofollow\" към всички връзки с изключение на вътрешните ( включително домейн майките). Промяната на тази настройка изисква актуализация на всички публикации със \"rake posts:rebake\"" + post_excerpt_maxlength: "Максимална дължина на откъс / резюме от публикацията." + post_onebox_maxlength: "Максимална дължина на oneboxed Discourse публикация в писмени знаци." + apple_touch_icon_url: "Иконата се използва за Apple сензорни устройства. Препоръчителният размер е 144px по 144px" + notification_email: "Подател: имейлът се използва при изпращане на всички системни съобщения. Посоченият тук домейн трябва да се конфигурира правилно със SPF, DKIM и PTR данни за успешна доставка." + email_custom_headers: "Разделен със знака \"|\" списък от персонализирани имейл хедъри. " + email_subject: "Персонализиран формат на темата за стандартни имейли. Виж https://meta.discourse.org/t/customize-subject-format-for-standard-emails/20801" + summary_score_threshold: "Минимална оценка необходима за една публикация, за да бъде включена в \"Обобщи тази тема\"" + summary_posts_required: "Минимум публикации в темата преди \"Обобщи тази тема\" да бъде активирано" + summary_likes_required: "Минимум харесвания в темата преди \"Обобщи тази тема\" да бъде активирано" + summary_percent_filter: "Когато потребителят кликне върху \"Обобщи тази тема\", се показват % от най-добрите публикации " + summary_max_results: "Максимум публикации върнати от \"Обобщи тази тема\"" + enable_long_polling: "Системата за обработка на известия, да използва long polling - заявки с дълго изчакване / дълъг интервал " + long_polling_base_url: "Основен URL използван за long polling - проверка на дълги интервали (когато се използва CDN за динамично съдръжание, уверете се, че тази стойност е настроена към основното съдържание) Например: http://origin.site.com" + long_polling_interval: "Времето, през което сървърът трябва да изчака преди да отговори на клиентите, когато няма данни за изпращане (влезли потребители само)" + polling_interval: "Когато няма \"long polling\", колко често логнатите потребители трябва да правят заявка към сървъра в милисекунди" + anon_polling_interval: "Колко често трябва анонимни клиенти да правят заявка към сървъра в милисекунди" + background_polling_interval: "Колко често трябва клиентите да правят заявка към сървъра в милисекунди (когато прозорецът е на заден план)" + cooldown_minutes_after_hiding_posts: "Брой минути, през които потребителя трябва да чака, преди да може да редактира скрита заради потребителско сигнализиране публикация " + tl2_additional_likes_per_day_multiplier: "Увеличи лимита от харесвания на ден за tl2 (member) до" + tl3_additional_likes_per_day_multiplier: "Увеличи лимита от харесвания на ден за tl3 (regular) до" + tl4_additional_likes_per_day_multiplier: "Увеличи лимита от харесвания на ден за tl4 (leader) до" + flag_sockpuppets: "Ако нов потребител отговори на тема от същия IP адрес като на новия потребител, който е започнал темата, маркирайте и двете публикации като потенциален спам." + traditional_markdown_linebreaks: "Използвайте стандартния метод за пренасяне на нов ред в Markdown, който изисква два интервала за пренасянето на нов ред." + post_undo_action_window_mins: "Брой минути, през които потребителите могат да отменят своите действия в публикацията ( харесване, сигнал, и т.н.) " + must_approve_users: "Персоналът трябва да одобри всички нови потребителски акаунти, преди да им бъде разрешен достъп до сайта. ВНИМАНИЕ: Включвайки тази функция, достъпът до сайта ще бъде разрешен само за персонала на сайта!" + ga_universal_tracking_code: "Google универсален анализ (analytics.js) проследяващ код, напр.: UA-12345678-9; see http://google.com/analytics" + ga_universal_domain_name: "Google универсален анализ (analytics.js) име на домейн, напр.: mysite.com; вижте http://google.com/analytics" + allow_moderators_to_create_categories: "Позволи на модераторите да създават нови категории" + cors_origins: "Позволени източници за cross-origin requests (CORS). Всеки източник трябва да включва http:// или https://. \nПроменливата за DISCOURSE_ENABLE_CORS env трябва да бъде правилно настроена за да позволи CORS." + top_menu: "Определете кои елементи да се показват в навигацията на началната страница, и в какъв ред. Например последни|нови|непрочетени|категории|топ|прочетени|публикувани|отметки" + post_menu: "Определете кои елементи да се появяват в менюто на публикацията, и в какъв ред. Например like|edit|flag|delete|share|bookmark|reply" + post_menu_hidden_items: "Меню елементите над публикацията, които трябва да се скриват и появяват при натискане на бутона с многоточието." + share_links: "Определете кои елементи да се появяват в споделен диалог и в какъв ред. " + track_external_right_clicks: "Абонирането за външни връзки с кликане на десен бутон (например: отвори в нов прозорец) е изключено по подразбиране, защото пренаписва URL-тата" + site_contact_username: "Валидно потребителско име на член от персонала за изпращане на автоматизираните съобщения. Ако оставите празно, ще бъде използвано потребителско име по подразбиране." + send_welcome_message: "Изпращай съобщение за добре дошли към всички нови потребители с инструкции за бързо започване." + suppress_reply_directly_below: "Не показвай брояча на отговорите когато има само един отговор точно под тази публикация." + suppress_reply_directly_above: "Не показвай разширяемо \"в отговор до\" на публикация когато има само един отговор директно над нея." + suppress_reply_when_quoting: "Не показвай в разширен вид отговора на публикацията, когато публикацията е цитирана в отговора." + max_reply_history: "Максимален брой отговори за подробно представяне при подробно представяне в отговора" + topics_per_period_in_top_summary: "Брой на най-добрите теми, показвани по подразбиране в резюмето с най-добрите теми." + topics_per_period_in_top_page: "Брой на най-добрите видими теми в показваните подробно \"Покажи повече\" топ теми." + redirect_users_to_top_page: "Автоматично пренасочване на нови и дълго отсъстващи потребители към началната страница." + show_email_on_profile: "Покажи имейлите на потребителите на техните профили (видими само за тях и за персонала) " + email_token_valid_hours: "Забравена парола / символите за активиране на акаунта са валидни (n) часа." + enable_badges: "Активирай системата за значки" + allow_index_in_robots_txt: "Посочете в robots.txt, че е позволено този сайт да бъде индексиран от търсачките." + email_domains_blacklist: "Разделен със знака \"|\" списък на имейл домейните, от които потребителите нямат право да се регистрират. Например: mailinator.com|trashmail.net " + email_domains_whitelist: "Разделен със знака \"|\" списък на имейл домейните, от които потребителите трябва да се регистрират. ВНИМАНИЕ: Потребители с имейл домейни, различни от тези в списъка, няма да бъдат допуснати!" + log_out_strict: "При изход, да се прекратяват ВСИЧКИ сесии на този потребител на всички устройства " + version_checks: "Следи Discourse Hub за актуализации и показвай съобщение за нова версия на /admin таблото." + new_version_emails: "Изпратете имейл до contact_email адрес когато има нова версия на Discourse." + invite_expiry_days: "Колко дълго са валидни ключовете за покана, в дни" + login_required: "Изисква разпознаване за прочит на съдържанието на сайта, не е разрешен анонимен достъп." + min_password_length: "Минимална дължина на парола." + min_admin_password_length: "Минимална дължина на парола за Админ." + block_common_passwords: "Не са разрешени паролите, които са в топ 10,000 от най-често използваните." + enable_sso: "Активиране на SSO чрез външен сайт (ВНИМАНИЕ: Имейл адресите на потребителите трябва да бъдат потвърдени от външния сайт!)" + verbose_sso_logging: "Запис на дебъг съобщенията свързани със SSO в папка /logs" + enable_sso_provider: "Имплементиране на Discourse SSO протокол в /session/sso_provider крайна точка, изисква sso_secret да бъде настроен" + sso_secret: "Таен стринг използван за криптографско удостоверяване на SSO информацията, уверете се, че е минимум 10 символа" + sso_overrides_email: "Заместване на локалния имейл с друг от външен сайт от SSO доставчика при всяко влизане, и предотвратяване на локални промени. (ВНИМАНИЕ: могат да настъпят несъответствия поради нормализирането на локалните имейли)" + sso_overrides_username: "Заместване на локалното потребителско име с друго от външен сайт от SSO доставчика при всяко влизане, и предотвратяване на локални промени. (ВНИМАНИЕ: могат да настъпят несъответствия поради нормализирането на потребителското име с дължината/изискванията)" + sso_overrides_name: "Сменете потребителското име с това, което е предоставено от SSO доставчика." + sso_overrides_avatar: "Заместване на потребителския аватар с друг от външен сайт от SSO payload. Ако е разрешено деактивирането на allow_uploaded_avatars е препоръчително" + sso_not_approved_url: "Пренасочване на неодобрените SSO акаунти към този URL" + allow_new_registrations: "Позволи регистрация на нови потребители. Махни отметката, за да не може никой да създаде нов акаунт." + enable_yahoo_logins: "Активиране на Yahoo удостоверяване" + enable_google_oauth2_logins: "Активиране на Google Oauth2 удостоверяване. Това е начина на удостоверяване, който се поддържа от Google в момента. Изисква key и secret." + google_oauth2_client_id: "Client ID за Google приложение." + google_oauth2_client_secret: "Client secret за Google приложение." + enable_twitter_logins: "Активиране на Twitter удостоверяване, изисква twitter_consumer_key и twitter_consumer_secret" + enable_facebook_logins: "Активиране на Facebook удостоверяване изисква facebook_app_id и facebook_app_secret " + facebook_app_id: "App id за Facebook удостоверяване, регистрирано на https://developers.facebook.com/apps" + facebook_app_secret: "App secret за Facebook удостоверяване, регистрирано на https://developers.facebook.com/apps" + enable_github_logins: "Разрешете Github удостоверяване, изисква github_client_id и github_client_secret" + github_client_id: "Client id за Github удостоверяване, регистрирано на https://github.com/settings/applications" + github_client_secret: "Client secret за Github удостоверяване, регистриран на https://github.com/settings/applications" + allow_restore: "Позволи възстановяване, което може да замени ВСИЧКИ данни на сайта! Оставете го погрешно освен ако не планирате да възстановите бекъпа" + maximum_backups: "Максимално количество бекъпи, които могат да бъдат съхранени на диска. По-старите бекъпи са автоматично изтрити" + enable_s3_backups: "Качи бекъпи на S3 когато е пълен. ВАЖНО: изисква валидни S3 правомощия въведени в настройките на файловете." + s3_backup_bucket: "Remote bucket за съхранение на бекъпи. ВНИМАНИЕ: Бъдете сигурни, че това е remote bucket." + active_user_rate_limit_secs: "Колко често обновяваме полето the 'last_seen_at', в секунди " + verbose_localization: "Покажи разширени локализационни съвети в потребителския интерфейс " + previous_visit_timeout_hours: "Колко дълго трябва да продължи посещението на сайта, за да се счита за \"предишно\" посещение, в часове" + rate_limit_create_topic: "След създаването на тема, потребителите трябва да изчакат (n) секунди преди да създадат друга тема." + rate_limit_create_post: "След публикуване, потребителите трябва да изчакат (n) секунди преди да направят друга публикация." + rate_limit_new_user_create_topic: "След създаването на тема, новите потребители трябва да изчакат (n) секунди преди да създадат друга тема." + rate_limit_new_user_create_post: "След публикуване, новите потребители трябва да изчакат (n) секунди преди да направят друга публикация." + max_likes_per_day: "Максимален брой харесвания на потребител на ден." + max_flags_per_day: "Максимален брой сигнали на потребител на ден." + max_bookmarks_per_day: "Максимален брой отметки на потребител на ден." + max_edits_per_day: "Максимален брой редактирания на потребител на ден." + max_topics_per_day: "Максимален брой теми, които потребител може да създаде на ден." + max_invites_per_day: "Максимален брой покани на потребител за ден." + max_topic_invitations_per_day: "Максимален брой покани за теми, които потребител може да изпрати за един ден." + suggested_topics: "Брой на предложените теми, показани в долната част на една тема." + limit_suggested_to_category: " В списъка с предложените теми покажи теми, само от текущата категория." + clean_up_uploads: "Прамахни грубите непубликувани качени файлове, за да бъде предотвратен незаконен хостинг. ВАЖНО: може би искате да направите резервно копие на тази директория преди да разрешите тази настройка." + clean_orphan_uploads_grace_period_hours: "Гратисен период (в часове) преди непубликуваните прикачени файлове да бъдат премахнати." + purge_deleted_uploads_grace_period_days: "Гратисен период (в дни) преди изтритите качвания да бъдат заличени." + enable_s3_uploads: "Постави качените файлове на Amazon S3 storage. ВАЖНО: изисква валидни S3 идентификационни данни (both access key id & secret access key)." + s3_upload_bucket: "Име на Amazon S3 bucket в което ще се качват файловете. ВНИМАНИЕ: трябва да съдържа само малки букви, без разстояния и долни черти." + s3_access_key_id: "Amazon S3 secret access key който ще се използва за качването на изображения." + s3_secret_access_key: "Amazon S3 secret access key който ще се използва за качването на изображения." + s3_region: "The Amazon S3 region name който ще се използва за качването на изображения." + s3_cdn_url: "URL адресът на URL да се използва за всички s3 авоари (например: https://cdn.somewhere.com). ВНИМАНИЕ: след промяната на тази настройка трябва да преработите всичките си публикации." + avatar_sizes: "Списък от автоматично генерираните размери на аватари" + enable_flash_video_onebox: "Разрешаване на ембедване на swf и flv (Adobe Flash) линкове в oneboxes. ВНИМАНИЕ: това може да създаде проблеми със сигурността." + default_invitee_trust_level: "По подразбиране ниво на доверие (0-4) за невалидни потребители." + default_trust_level: "Ниво на доверие (0-4) по подразбиране за всички нови потребители. ВНИМАНИЕ! Промяната на това ще ви постави в сериозен риск за спам." + tl1_requires_topics_entered: "Колко теми трябва да отвори нов потребител, за да премине към ниво на доверие 1." + tl1_requires_read_posts: "Колко публикации трябва да прочете нов потребител, за да премине към ниво на доверие 1." + tl1_requires_time_spent_mins: "Колко минути трябва да чете публикации нов потребител, за да премине към ниво на доверие 1." + tl2_requires_topics_entered: "Колко теми трябва да отвори нов потребител, за да премине към ниво на доверие 2." + tl2_requires_read_posts: "Колко публикации трябва да прочете нов потребител, за да премине към ниво на доверие 2." + tl2_requires_time_spent_mins: "Колко минути трябва да чете публикации нов потребител, за да премине към ниво на доверие 2." + tl2_requires_days_visited: "Колко дни трябва потребителя да посещава сайта, за да премине към ниво на доверие 2." + tl2_requires_likes_received: "Колко харесвания трябва да има потребител, за да премине към ниво на доверие 2." + tl2_requires_likes_given: "Колко харесвания трябва да направи потребител, за да премине към ниво на доверие 2." + tl2_requires_topic_reply_count: "На колко теми трябва да отговори потребител, за да премине към ниво на доверие 2." + tl3_time_period: "Изисквания за Ниво на доверие 3 във времеви период (в дни)" + tl3_requires_topics_viewed_all_time: "Общ минимален брой теми, които потребителят трябва да прегледа, за да се класира за ниво на доверие 3." + tl3_requires_posts_read_all_time: "Общ минимален брой публикации, които потребителят трябва да прочете, за да се класира за ниво на доверие 3." + tl3_promotion_min_duration: "Минимален брой дни, през които трае повишението на ниво на доверие 3 преди потребителят да бъде понижен обратно на ниво на доверие 2." + tl3_links_no_follow: "Не премахвайте rel=nofollow от линковете, публикувани от потребители с ниво на доверие 3." + min_trust_to_create_topic: "Минимално ниво на доверие изисквано за създаване на нова тема" + min_trust_to_edit_wiki_post: "Минимално ниво на доверие изисквано за редактиране на wiki." + 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, които един потребител може да направи." + create_thumbnails: "Създадените миниатюри и Lightbox изображения са прекалено големи, за да се поберат в една публикация." + email_time_window_mins: "Изчакайте (n) минути преди да изпратите уведомителни имейли, за да дадете шанс на потребителите да редактират и финализират своите публикации." + email_posts_context: "Колко предишни отговори да бъдат включени като контекст в уведомителните имейли." + flush_timings_secs: "Колко често данните за време се записват на сървъра, в секунди" + title_max_word_length: "Малсимално разрешена дължина на думата в символи в заглавието на темата" + title_min_entropy: "Минимална ентропия ( уникални символи, тези които не са английски се броят за повече) изисквана за заглавието на темата." + body_min_entropy: "Минимална ентропия ( уникални символи, тези които не са английски се броят за повече) изисквана за текста на публикацията." + title_fancy_entities: "Конвертирайте обикновените ASCII символи в луксозните HTML символи в заглавията на темите, ala SmartyPants http://daringfireball.net/projects/smartypants/" + min_title_similar_length: "Минимална дължина на заглавието на темата, като тя ще бъде проверена за наличие на подобна." + min_body_similar_length: "Минимална дължина на съдържанието на публикацията, при което то ще бъде проверено за наличие на подобно." + category_colors: "Списък от шестнадесетични цветови стойности разрешени за категориите." + category_style: "Визуален стил за категорията със значки." + max_image_size_kb: "Максимален размер за качване на избражение в kB. Това също трябва да се конфигурира в nginx конфигурацията (client_max_body_size), apache или прокси сървъра." + max_attachment_size_kb: "Максимална големина на прикачените файлове в kB. Това също трябва да се конфигурира в nginx (client_max_body_size), apache или прокси сървъра." + authorized_extensions: "Списък от разширения на файлове разрешени за качване (използвайте '*' за да разрешите всички)" + max_similar_results: "Брой подобни теми показвани на потребителя при създаването на нова тема. Сравнението е базирано на заглавието и текста на темата." + title_prettify: "Предотврати разпространението на печатни грешки, грешки включващи главни букви, малки букви, излишни ! и ? в края на изречението и т.н." + topic_views_heat_low: "След толкова много прегледи, полето на прегледаните ще бъде леко подчертано." + topic_views_heat_medium: "След толкова много прегледи, полето на прегледаните ще бъде умерено подчертано." + topic_views_heat_high: "След толкова много прегледи, полето на прегледаните ще бъде силно подчертано." + cold_age_days_low: "След толкова много дни на разговори, последната дата с активност ще бъде леко бледа" + cold_age_days_medium: "Толкова много дни след последната активност в разговора, последната дата е умерено подчертана." + cold_age_days_high: "Толкова много дни след последната активност в разговора, последната дата е силно подчертана." + history_hours_low: "Публикация, редактирана в рамките на толкова много часове, ще бъде индикирана като леко подчертана" + history_hours_medium: "Публикация, редактирана в рамките на толкова много часове, ще бъде индикирана като умерено подчертана." + history_hours_high: "Публикация, редактирана в рамките на толкова много часове, ще бъде индикирана като силно подчертана" + topic_post_like_heat_low: "След харесване: ако съотношението на публикации надхвърля това съотношение, полето с броя на публикациите ще е леко подчертано. " + topic_post_like_heat_medium: "След харесване: ако съотношението на публикациите надхвърля това съотношение, полето с броя на публикации ще е умерено подчертано." + topic_post_like_heat_high: "След харесване:ако съотношението на публикациите надхвърля това съотношение, полето с броя на публикациите ще е силно подчертано." + faq_url: "Въведете пълен URL към страницата FAQ, ако искате да използвате собствена версия." + tos_url: "Ако имате документ с \"Правила за ползване\" който се хоства някъде другаде и желаете да го използвате, въведете пълния път до URL адреса тук. " + privacy_policy_url: "Ако имате документ \"Декларация за поверителност\", който се хоства някъде другаде и желаете да го използвате, въведете пълния път до URL адреса тук. " + white_listed_spam_host_domains: "Списък с домейните изключени от спам хост теста. Новите потребители никога няма да бъдат ограничавани в създаването на публикации с линкове към тези домейни." + staff_like_weight: "Колко допълнителна тежест да се дава за харесвания от екипа." + levenshtein_distance_spammer_emails: "Колко символа разлика в съвпадението може да има, когато се проверява имейла за спам, за да има приблизително съвпадение." + max_new_accounts_per_registration_ip: "Ако вече има (n) в ниво на доверие 0 акаунта от това IP (и никой не е от екипа или от по-високо ниво на доверие 2), спри да приемаш нови регистрации от този IP адрес." + min_ban_entries_for_roll_up: "Когато щракнете на бутона Сливане, ще създадете нов бан на подмрежа, ако в същата има повече от (N) записа." + max_age_unmatched_emails: "Изтриване на несъвпадащите пресяти имейл записи след (N) дни." + max_age_unmatched_ips: "Изтрий несъчетаните пресяти IP вписвания след (N) дни." + num_flaggers_to_close_topic: "Минимален брой уникални сигнализации, които се изискват за спиране на темата" + num_flags_to_close_topic: "Минимален брой активни сигнали, които се изискват за спиране на темата" + auto_respond_to_flag_actions: "Активиране на автоматичен отговор с помощта на сигналите на сайта." + reply_by_email_enabled: "Позволи отговори в темите чрез имейл." + reply_by_email_address: "Шаблон за отговор по имейла на входящ имейл адрес, например: %{reply_key}@reply.example.com or replies+%{reply_key}@example.com" + disable_emails: "Забрани Discoursе да изпраща каквито и да е имейли " + strip_images_from_short_emails: "Премахни от имейлите по-малките от 2800 байта изображения" + short_email_length: "Колко байта имейл се счита за кратък" + pop3_polling_enabled: "Проверка чрез POP3 за имейл отговорите." + pop3_polling_ssl: "Използвай SSL при свързване със сървъра POP3. (Препоръчително) " + pop3_polling_period_mins: "Срок в минути за проверката на POP3 акаунта за имейл. ЗАБЕЛЕЖКА: изисква рестарт." + pop3_polling_port: "Порт за проверка на POP3 акаунт." + pop3_polling_host: "Хост за проверка на имейла чрез POP3." + pop3_polling_username: "Потребителско име за POP3 акаунт за проверка на имейла." + pop3_polling_password: "Парола за POP3 акаунт за проверка на имейла. " + email_in_min_trust: "Минимално ниво на доверие, което потребителя трябва да притежава, за да публикува нови теми чрез имейл." + email_prefix: " [label] се използва като тема на имейлите. Ако не бъде определено, ще бъде използвано \"заглавие\" по подразбиране." + email_site_title: "Заглавието на сайта се използва като подател на имейлите от сайта. Ако не бъде определено, ще бъде използвано \"заглавие\" по подразбиране. Ако вашето \"заглавие\" съдържа символи, които не са позволени, използвайте тази настройка." + minimum_topics_similar: "Колко теми трябва да съществуват преди да бъдат представени подобни теми при създаването на нови." + relative_date_duration: "Брой дни след публикацията, през които датата на публикуването ще бъде показвана като относителна ( 7д) вместо абсолютна ( 20 Фев.)." + delete_user_max_post_age: "Забрани изтриване на потребители, чиято първа публикация е по-стара от (x) дни." + delete_all_posts_max: "Максимален брой публикации, които могат да бъдат изтрити наведнъж с бутона за изтриване на всички публикации. Ако потребителят има по-голям брой публикации от този, то те не могат да бъдат изтрити наведнъж, следователно и потребителя не може да бъде изтрит." + email_editable: "Разреши на потребителите да променят техния имейл адрес след регистрация." + allow_uploaded_avatars: "Позволи на потребителите да качват свои снимки на профилите си." + allow_animated_thumbnails: "Създай анимирани миниатюри на анимираните GIF изображения." + default_avatars: "URL за аватари, които ще бъдат използвани по подразбиране за нови потребители, преди те да ги променят" + automatically_download_gravatars: "Свали Gravatar за потребителите преди създаването на профил или промяна на имейла." + max_daily_gravatar_crawls: "Максимален брой сваляния на аватари с Gravatar за ден" + public_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 минути след последния пост на потребителя, след като той излезе, ще бъде създаден анонимен акаунт." + allow_profile_backgrounds: "Позволи на потребителите да качват фонове на профилите си." + enable_mobile_theme: "Мобилните устройства използват адаптирана тема с възможност за преминаване към нормален изглед. Забранете тази настройка, ако искате да използвате свой собствен стил за мобилните устройства." + dominating_topic_minimum_percent: "Какъв процент публикации може да направи един потребител преди да бъде предупреден за доминиране в тема." + suppress_uncategorized_badge: "Не показвай значката в списъците с теми за тези, които не са категоризирани. " + global_notice: "Покажи МНОГО ВАЖНО, СПЕШНО съобщение на всички посетители. Премахване на съдържанието, за да бъде скрито ( HTML позволено)." + disable_edit_notifications: "Забрани редактирането на уведомления от системните потребители когато 'download_remote_images_to_local' е активно." + full_name_required: "Полето 'Пълно име' е задължително в потребителския профил" + enable_names: "Покажи пълното име на потребителите на техните профили, потребителски карти, и имейли. Деактивирай за скриване на пълното име навсякъде." + display_name_on_posts: "Покажи пълните имена на потребителите в техните публикации като допълнение към потребителските им имена @username." + show_time_gap_days: "Ако двете публикации са направени през такъв дълъг период, покажи разликата във времето в темата." + short_progress_text_threshold: "След достигането на определен брой публикации в темата, в лентата за напредъка ще бъде видим само броят на текущите публикации. Ако промените ширината на лентата за напредъка, може да се наложи да промените тази стойност. " + default_code_lang: "Подчертаване на езиковия синтаксис по подразбиране е приложен за GitHub code blocks (lang-auto, ruby, python etc.) " + warn_reviving_old_topic_age: "Когато някой започне да пише в тема, където последният отговор е от преди много време, ще се покаже предупреждение. Изключи с 0. " + autohighlight_all_code: "Оцветявай всички предварително форматирани кодови блокове, дори когато няма изрично посочен език." + embed_truncate: "Премахване на вградените публикации." + embed_post_limit: "Максимален брой публикации за вграждане." + show_create_topics_notice: "Ако на сайта има по-малко от 5 теми, покажи на персонала съобщение с молба за създаване на още теми." + delete_drafts_older_than_n_days: Изтрий чернови по-стари от (n) дни. + prevent_anons_from_downloading_files: "Предотврати свалянето на приложения от анонимни потребители. ВНИМАНИЕ: това ще попречи на работата на всички авоари ,които са публикувани на сайта като приложения без изображения. " + slug_generation_method: "Изберете метод за генериране на URL. 'кодирано' ще използва букви URL, кодирани с проценти. 'не' ще откаже генерацията като цяло." + enable_emoji: "Разреши емотикони" + emoji_set: "Как бихте искали да е вашата емотикона?" + enforce_square_emoji: "Направи квадратни всички емотикони." + approve_unless_trust_level: "Постовете на потребители с по-ниско от това ниво на доверие трябва да бъдат одобрени" + default_email_direct: "Изпращай имейл по подразбиране, когато някой цитира, отговаря на публикацията или споменава името на потребителя." + default_email_mailing_list_mode: "Изпращай ми имейл по подразбиране за всяка нова публикация." + default_email_always: "Изпращай ми имейл известия по подразбиране, дори когато потребителя е активен на сайта." + 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_categories_watching: "Списък с категории, които са прегледани, по подразбиране." + default_categories_tracking: "Списък с категории, които са следени, по подразбиране." + default_categories_muted: "Списък с категории, които са заглушени, по подразбиране." + errors: + invalid_email: "Невалиден имейл адрес." + invalid_username: "Няма потребител с такова потребителско име." + invalid_integer_min_max: "Стойността трябва да мъде между %{min} и %{max}." + invalid_integer_min: "Стойността трябва да бъде %{min} или по-голяма" + invalid_integer_max: "Стойността не може да бъде по-голяма от %{max}." + invalid_integer: "Стойността трябва да бъде число." + regex_mismatch: "Стойноста не съвпада с необходимия формат." + must_include_latest: "Заглавното меню трябва да включва таб-а \"последни\"." + invalid_string: "Невалидна стойност." + invalid_string_min_max: "Трябва да бъде между %{min} и %{max} символа." + invalid_string_min: "Трябва да бъде минимум %{min} символа." + invalid_string_max: "Трябва да не бъде с повече от %{max} символа." + invalid_reply_by_email_address: "Стойността трябва да съдържа '%{reply_key}' и да бъде различна от известяващия имейл." + search: + within_post: "#%{post_number} от %{username}" + types: + category: 'Категории' + topic: 'Резултати' + user: 'Потребители' + original_poster: "Автор" + most_posts: "Повечето мнения" + most_recent_poster: "Последен Автор" + frequent_poster: "Частен Автор" + redirected_to_top_reasons: + new_user: "Добре дошли в нашата общност! Това са най-популярните последни теми. " + not_seen_in_a_month: "Добре дошли отново! Това са най-популярните теми за времето, през което Ви нямаше." + change_owner: + post_revision_text: "Собствеността е прехвърлена от %{old_user} към %{new_user}" + deleted_user: "изтрит потребител" + topic_statuses: + archived_enabled: "Тази тема в момента е в архив. Тя е замразена и не може да се променя по никакъв начин." + archived_disabled: "Тази тема е разархивирана. Вече не е замразена и може да се променя." + closed_enabled: "Тази тема е затворена. Вече не е разрешено да се отговаря в нея." + closed_disabled: "Тази тема сега е отворена. Новите отговори са разрешени." + autoclosed_enabled_days: + one: Тази тема ще се затвори автоматично след 1 ден. Нови отговори вече не се допускат. + other: Тази тема ще се затвори автоматично след %{count} дни. Нови отговори вече не се допускат. + autoclosed_enabled_hours: + one: Тази тема ще се затвори автоматично след 1 час. Нови отговори не се допускат. + other: Тази тема ще се затвори автоматично след %{count} часа. Нови отговори не се допускат. + autoclosed_enabled_minutes: + one: Тази тема ще се затвори автоматично след 1 минута. Нови отговори не се допускат. + other: Тази тема ще се затвори автоматично след %{count} минути. Нови отговори не се допускат. + autoclosed_enabled_lastpost_days: + one: Тази тема беше автоматично затворена 1 ден след последния отговор. Нови отговори вече не са разрешени. + other: Тази тема беше автоматично затворена след %{count} дни след последния отговор. Нови отговори вече не са разрешени. + autoclosed_enabled_lastpost_hours: + one: Тази тема беше автоматично затворена 1 час след последния отговор. Отговорите в нея вече са забранени. + other: 'Тази тема беше автоматично затворена %{count} часа след последния отговор. Отговорите в нея вече са забранени. ' + autoclosed_enabled_lastpost_minutes: + one: 'Тази тема беше автоматично затворена 1 минута след последния отговор. Отговорите в нея вече са забранени. ' + other: 'Тази тема беше автоматично затворена %{count} минути след последния отговор. Отговорите в нея вече са забранени. ' + autoclosed_disabled: "Тази тема сега е отворена. Новите отговори са разрешени." + autoclosed_disabled_lastpost: "Тази тема сега е отворена. Новите отговори са разрешени." + pinned_enabled: "Тази тема сега е закована. Тя ще се появява най-отгоре на категорията си и на всички списъци с теми, докато не бъде откована от член на персонала или индивидуално от потребителите." + pinned_disabled: "Тази тема вече не е закована. Повече няма да се появява най-отгоре на категорията." + pinned_globally_enabled: "Тази тема сега е закована глобално. Тя ще се появява най-отгоре на категорията си и на всички списъци с теми, докато не бъде откована от член на персонала или индивидуално от потребителите." + pinned_globally_disabled: "Тази тема вече не е закована. Повече няма да се появява най-отгоре на категорията." + visible_enabled: "Темата е вписана. Тя ще се почви в списъка с темите." + visible_disabled: "Тази тема е отписана. Тя вече няма да бъде видима в нито един списък с теми“ Единствения начин за достъп до нея е чрез директен линк." + login: + not_approved: "Вашият профил все още не е одобрен. Ще бъдете уведомени с имейл когато е възможно влизането Ви. " + incorrect_username_email_or_password: "Грешно потребителско име, имейл или парола." + wait_approval: "Благодарим Ви за регистрацията. Ще Ви уведомим когато вашият профил е одобрен." + active: "Профилът ви е активиран и готов за употреба." + not_activated: "Не можете да влезете все още. Ще ви изпратим имейл за активация. Моля следвайте инструкциите, за да активирате вашия профил." + not_allowed_from_ip_address: "Вие не може да влезете като %{username} от този IP адрес." + admin_not_allowed_from_ip_address: "Вие не може да влезете като админ от този IP адрес." + suspended: "Вие не може да влизате до %{date}." + suspended_with_reason: "Профилът е отстранен докато %{date}: %{reason}" + errors: "%{errors}" + not_available: "Не е налично. Опитайте %{suggestion}?" + something_already_taken: "Нещо се случи, вероятно потребителското име или имейл адреса са вече регистрирани. Опитайте да използвате връзката за забравена парола." + omniauth_error: "Съжаляваме, възникна грешка при потвърждението на вашия профил. Може би не сте приели потвърждението?" + omniauth_error_unknown: "Нещо се обърка докато Ви вписваме, моля опитайте отново." + new_registrations_disabled: "В момента новите регистации са забранени." + password_too_long: "Паролата е ограничена до 200 символа." + reserved_username: "Това потребителско име не е разрешено." + missing_user_field: "Вие не сте попълнили всички потребителски полета." + auth_complete: "Удостоверяването е завършено." + click_to_continue: "Кликнете тук, за да продължите." + already_logged_in: "Ами сега, изглежда, че се опитвате да приемете покана за друг потребител. Ако не сте %{current_user}, моля, излезте от профила си и опитайте отново." + second_factor_title: "Удостоверяване с два фактора" + second_factor_description: "Моля, въведете необходимият код за удостоверяване от приложението си:" + user: + no_accounts_associated: "Няма свързани профили" + username: + short: "трябва да бъде минимум %{min} символа." + long: "трябва да не е повече от %{max} символа." + unique: "Трябва да бъде уникално" + blank: "Трябва да присъства" + email: + not_allowed: "не е разрешено от този имейл доставчик. Моля използвайте друг имейл адрес." + blocked: "не е разрешено" + ip_address: + blocked: "Не са разрешени нови регистрации от вашия IP адрес." + max_new_accounts_per_registration_ip: "Не са разрешени нови регистрации от вашия IP адрес (достигнали сте лимита). Свържете се с член на персонала." + flags_reminder: + subject_template: + one: 1 сигнал чакащ за обработка + other: '%{count} сигнала налични за обработка ' + invite_mailer: + text_body_template: | + %{inviter_name} ви покани да се присъедините към дискусията + + > **%{topic_title}** + > + > %{topic_excerpt} + + на + + > %{site_title} -- %{site_description} + + Ако се интересувате, кликнете на линка по-долу: + + %{invite_link} + custom_invite_mailer: + text_body_template: | + %{inviter_name} ви покани да се присъедините към дискусията + + > **%{topic_title}** + > + > %{topic_excerpt} + + на + + > %{site_title} -- %{site_description} + + Със тази бележка + + > %{user_custom_message} + + Ако се интересувате, кликнете на линка по-долу: + + %{invite_link} + invite_forum_mailer: + text_body_template: | + %{inviter_name} ви кани да се присъедините към + + > **%{site_title}** + > + > %{site_description} + + Ако се интересувате, кликнете на линка по-долу: + + %{invite_link} + custom_invite_forum_mailer: + text_body_template: | + %{inviter_name} ви покани да се присъедините към + + > **%{site_title}** + > + > %{site_description} + + Със тази бележка + + > %{user_custom_message} + + Ако се интересувате, кликнете на линка по-долу: + + %{invite_link} + invite_password_instructions: + subject_template: "Сложете парола за вашият %{site_name} акаунт" + flag_reasons: + off_topic: "За вашата публикация беше сигнализирано като **оф-топик**: общността смята, че не се вписва в темата, впредвид заглавието на темата и първата публикация. " + inappropriate: "За вашата публикация беше сигнализирано като **неуместна**: общността счита, че е обидна, оскърбителна или нарушение на [виж Правилата на Общността](/guidelines)." + spam: "За вашата публикация беше сигнализирано като **спам**: общността счита, че е реклама, че е по скоро с рекламна цел, отколкото полезна и уместна за темата." + notify_moderators: "За вашата публикация беше сигнализирано като **сигнал до модератор**: общността счита, че е необходима лична намеса от член на персонала." + flags_dispositions: + agreed: "Благодарим Ви за информацията. Съгласни сме, че има проблем и вече го разглеждаме." + agreed_and_deleted: "Благодарим Ви, за информацията. Съгласни сме, че има проблем и ще премахнем публикацията." + disagreed: "Благодарим Ви за информацията. Вече разглеждаме проблема." + deferred: "Благодарим Ви за информацията. Вече разглеждаме проблема. " + deferred_and_deleted: "Благодарим,Ви за информацията. Вече премахнахме публикацията." + system_messages: + welcome_user: + subject_template: "Добре дошли в %{site_name}!" + welcome_invite: + subject_template: "Добре дошли в %{site_name}!" + backup_succeeded: + subject_template: "Бекъпа завърши успещно." + backup_failed: + subject_template: "Бекъпа се провали" + restore_succeeded: + subject_template: "Възстановяването завърши успешно." + restore_failed: + subject_template: "Възстановяването се провали" + bulk_invite_succeeded: + subject_template: "Груповата потребителска покана e обработена успешно" + text_body_template: "Вашата групова потребителска покана от файл е обработена, %{sent} имейл покани бяха изпратени." + bulk_invite_failed: + subject_template: "Груповата потребителска покана завърши с грешки" + csv_export_failed: + subject_template: "Изходящите данни се провалиха " + email_reject_parsing: + text_body_template: | + Съжаляваме, но вашето съобщение до %{destination} (titled %{former_title}) не може да бъде обработено. + + Не намираме вашия отговор в съобщението. **Уверете се, че вашият отговор в горната част на съобщението** -- не можем да обработим инлайн отговори. + pending_users_reminder: + subject_template: + one: 1 потребител чака одобрение + other: '%{count} потребители чакат одобрение' + text_body_template: | + Има нови потребителски регистрации, които чакат да бъдат одобрени (отхвърлени) преди да получат достъп до този форум. + + [Please review them in the admin section](%{base_url}/admin/users/list/pending). + download_remote_images_disabled: + subject_template: "Изтеглянето на отдалечение изображения е забранено" + text_body_template: " `download_remote_images_to_local` настройка беше спряна защото лимита за дисково пространство в `download_remote_images_threshold` беше достигнат." + subject_re: "Ре: " + subject_pm: "[ЛС] " + user_notifications: + previous_discussion: "Предишни Отговори" + in_reply_to: "В отговор до" + unsubscribe: + title: "Отписвам" + description: "Не сте заинтересувани от тези имейли? Няма проблем! Кликнете по-долу, за да се отпишете веднага:" + posted_by: "Публикувано от &{username} на %{post_date}" + user_replied: + title: "Потребителят е отговорил" + digest: + why: "Кратко резюме на %{site_link} след последното Ви посещение на %{last_seen_at}" + click_here: "кликнете тук" + signup_after_approval: + subject_template: "Вие бяхте одобрени на %{site_name}!" + page_not_found: + popular_topics: "Популярни" + recent_topics: "Скорошни" + see_more: "Повече" + search_title: "Търси този сайт" + search_google: "Google" + terms_of_service: + title: "Правила за ползване" + signup_form_message: 'Аз прочетох и приемам правилата за ползване.' + deleted: 'изтрит' + upload: + edit_reason: "изтеглено локално копие на изображенията" + unauthorized: "Съжеляваме, Файлът е забранен за качване (разрешени разширения : %{authorized_extensions})." + pasted_image_filename: "Публикувани изображения" + store_failure: "Грешка при зареждане на #%{upload_id} за потребителя #%{user_id}." + attachments: + too_large: "Съжaляваме, файлът който се опитвате да качите е много голям (максималния позволен размер е %{max_size_kb}%KB)." + images: + too_large: "Съжаляваме, изображението, което се опитвате да качите е прекалено голямо (максималният размер е %{max_size_kb}%KB), моля преоразмерете го и опитайте отново. " + size_not_found: "Съжаляваме, но не можем да определим размера на изображението. Възможно ли е изображението да е повредено?" + email_log: + no_user: "Няма потребител с id %{user_id}" + anonymous_user: "Потребителя е анонимен" + suspended_not_pm: "Бла бля бля\nБла бля бля" + seen_recently: "Потребителят скоро е забелязан " + post_not_found: "Няма публикация с id %{post_id}" + notification_already_read: "Уведомлението, за което е този имейл вече беше прочетено" + topic_nil: "post.topic is nil" + post_deleted: "публикацията беше изтрита от автора" + user_suspended: "потребителят е деактивиран" + already_read: "потребителят вече е прочел тази публикация" + message_blank: "message е празно" + message_to_blank: "message.to е празно" + text_part_body_blank: "text_part.body е празно" + body_blank: "съдържанието е празно" + color_schemes: + base_theme_name: "Основа" + about: "Относно" + guidelines: "Насоки" + privacy: "Поверителност" + edit_this_page: "Редактирайте тази страница" + csv_export: + boolean_yes: "Да" + boolean_no: "Не" + static_topic_first_reply: | + Редактирайте първата публикация в тази тема за да промените съдаржанието на страница %{page_name}. + guidelines_topic: + title: "FAQ/Насоки" + tos_topic: + title: "Правила за ползване" + privacy_topic: + title: "Декларация за поверителност" + badges: + autobiographer: + long_description: | + Тази значка се предоставя за попълване на потребителския ви профил и за избор на профилна снимка. Дайте възможност на общността да научи малко повече за това кой сте и какво ви интересува, за да допринесете за създаването на една по-добра, по-свързана общност. Присъединете се към нас! + 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: Покани потребител + long_description: | + Тази значка се предоставя, когато каните някого да се присъедини към общността чрез бутона за покани на потребителската ви страница или под тема. Поканването на приятели, които биха могли да се интересуват от конкретни дискусии, е чудесен начин да въведете нови хора в нашата общност, така че благодарим! + campaigner: + name: Участник в кампанията + champion: + name: Шампион + description: Поканени са 5 члена + first_share: + name: Първо споделяне + description: Споделена публикация + first_link: + name: Първа връзка + description: Добавена връзка към друга тема. + first_quote: + name: Първи цитат + description: Цитирана публикация + read_guidelines: + name: Прочетени напътствия + reader: + name: Прочел + popular_link: + name: Популярна връзка + hot_link: + name: Гореща връзка + famous_link: + name: Известена връзка + long_description: | + Тази значка се предоставя, когато споделена от вас връзка получи 1000 кликвания. Еха! Публикувахте връзка, която значително подобри разговора чрез добавяне на основни детайли, контекст и информация. Чудесна работа! + appreciated: + name: Оценено + description: Получено 1 харесване на 20 публикации + long_description: | + Тази значка се връчва, когато получавате поне едно харесване на 20 различни публикации. Общността се радва на вашия принос към разговорите тук! + respected: + name: Уважаван + description: Получени 2 харесвания на 100 публикации + admired: + description: Получил 5 харесвания за 300 публикации + crazy_in_love: + name: Луди от любов + thank_you: + name: Благодарим ти + first_emoji: + name: Първа емотикона + first_mention: + name: Първо споменаване + first_reply_by_email: + name: Първи отговор по имейл + description: Отговорено на публикация по имейл + new_user_of_the_month: + name: "Нов потребител на месеца" + enthusiast: + name: Ентусиаст + description: Посещавал 10 дни + long_description: "Тази значка се дава за посещение в 10 последователни дни. Благодарим Ви, че сте били с нас повече от седмица!" + aficionado: + name: Любител + description: Посещавал 100 дни + devotee: + name: Отдаден + description: Посещавал 365 дни + long_description: "Тази значка се дава за посещение в 365 последователни дни. Еха, цяла година!" + admin_login: + success: "Изпратен имейл" + errors: + unknown_email_address: "Неизвестен имейл адрес" + invalid_token: "Невалиден жетон" + email_input: "Админ имейл" + submit_button: "Изпрати имейл" + performance_report: + initial_post_raw: Тази тема съдържа дневните репорти за производителноста на твоя сайт. + initial_topic_title: Репорти за производителноста на сайта + tags: + title: "Тагове" + staff_tag_disallowed: "Тагът \"%{tag}\" може да бъде приложен само от персонала." + staff_tag_remove_disallowed: "Тагът \"%{tag}\" може да бъде премахнат само от персонала." + minimum_required_tags: "Трябва да изберете поне %{count} тагове." + finish_installation: + register: + button: "Регистриране" + title: "Регистриране на Админ акаунт" + help: "регистрирайте нов профил за да започнете" + confirm_email: + title: "Потвърдете имейл адреса си" + resend_email: + title: "Изпрати отново активационен имейл " + safe_mode: + title: "Влизане в безопасен режим" + wizard: + step: + contact: + fields: + contact_url: + label: "Уеб страница" + site_contact: + label: "Автоматизирани съобщения" + corporate: + title: "Организация" + fields: + company_short_name: + label: "Име на компанията" + colors: + fields: + theme_id: + description: "Предпочитате ли да започнете с лека или тъмна цветова схема? Можете допълнително да персонализирате външния вид на вашия сайт чрез Админ, Персонализация." + choices: + default: + label: "Опростено светло" + dark: + label: "Опростено тъмно" + logos: + title: "Логота" + fields: + logo_url: + label: "Главно лого" + logo_small_url: + label: "Компактно лого" + icons: + title: "Икони" + fields: + favicon_url: + label: "Малка икона" + homepage: + title: "Начална страница" + fields: + homepage_style: + choices: + latest: + label: "Последни теми" + categories: + label: "Категории" + emoji: + title: "Емотикони" + description: "Какъв стил Емотикони предпочитате за вашата общност? Можете да добавите още персонализирани Емотикони по-късно чрез Админ, Персонализация, Емотикони." + invites: + title: "Поканете персонал" + finished: + title: "Вашият Discourse е готов!" + search_logs: + graph_title: "Брой търсения" + discourse_push_notifications: + 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}' + private_message: '%{username} ви изпрати лично съобщение "%{topic}" - %{site_title}' + linked: '%{username} е сложил връзка към вашата публикация в "%{topic}" - %{site_title}' + confirm_title: 'Включени известявания - %{site_title}' + confirm_body: 'Успех! Известяването е включено.' diff --git a/config/locales/server.bs_BA.yml b/config/locales/server.bs_BA.yml index 7268afb07a..d69122cb1d 100644 --- a/config/locales/server.bs_BA.yml +++ b/config/locales/server.bs_BA.yml @@ -267,9 +267,7 @@ bs_BA: xaxis: "Day" yaxis: "Number of visits" signups: - title: "Users" xaxis: "Day" - yaxis: "Number of new users" profile_views: xaxis: "Dan" topics: diff --git a/config/locales/server.ca.yml b/config/locales/server.ca.yml index 0c2c8373f2..09192ca98a 100644 --- a/config/locales/server.ca.yml +++ b/config/locales/server.ca.yml @@ -611,9 +611,7 @@ ca: xaxis: "Dia" yaxis: "Quantitat de visites" signups: - title: "Noves persones usuàries" xaxis: "Dia" - yaxis: "Quantitat de noves persones usuàries" profile_views: title: "Vistes de perfils de persones usuàries" xaxis: "Dia" diff --git a/config/locales/server.cs.yml b/config/locales/server.cs.yml index 7802b42bf7..97356c287c 100644 --- a/config/locales/server.cs.yml +++ b/config/locales/server.cs.yml @@ -674,9 +674,7 @@ cs: xaxis: "Den" yaxis: "Počet návštěv" signups: - title: "Noví uživatelé" xaxis: "Den" - yaxis: "Počet nových uživatelů" profile_views: title: "Zobrazení uživatelských profilů" xaxis: "Den" diff --git a/config/locales/server.da.yml b/config/locales/server.da.yml index a8ef9a8534..9d08804942 100644 --- a/config/locales/server.da.yml +++ b/config/locales/server.da.yml @@ -636,9 +636,7 @@ da: xaxis: "Dag" yaxis: "Antal besøg" signups: - title: "Nye brugere" xaxis: "Dag" - yaxis: "Antal nye brugere" profile_views: title: "Bruger Profil Visninger" xaxis: "Dag" diff --git a/config/locales/server.de.yml b/config/locales/server.de.yml index 88db9831a3..f248ea16ef 100644 --- a/config/locales/server.de.yml +++ b/config/locales/server.de.yml @@ -68,6 +68,7 @@ de: 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 wir keinen Textkörper extrahieren konnten und keine Anhänge gefunden wurden." no_sender_detected_error: "Kommt vor, wenn wir keine gültige E-Mail-Adresse im From-Header finden konnten." + from_reply_by_address_error: "Passiert wenn der From-Header mit der Antwort E-Mail-Adresse übereinstimmt." inactive_user_error: "Passiert wenn der Sender nicht aktiv ist." silenced_user_error: "Kommt vor, wenn der Absender stummgeschaltet wurde." bad_destination_address: "Passiert wenn keine der E-Mail Adressen in den Feldern To/Cc/Bcc zu einer konfigurierten Eingangs-E-Mail-Adresse passt." @@ -776,7 +777,8 @@ de: dau_by_mau: title: "TAB/MAB" xaxis: "Tag" - yaxis: "TAB/MAJ" + yaxis: "TAB/MAB" + description: "Anzahl der Mitglieder, die sich am vergangenen Tag angemeldet haben, geteilt durch die Anzahl der Mitglieder, die sich im letzten Monat angemeldet haben – liefert eine Prozentzahl, die das „Klebeverhalten“ der Community angibt. Erstrebenswert sind 30 % oder mehr." daily_engaged_users: title: "Täglich engagierte Benutzer" xaxis: "Tag" @@ -830,7 +832,7 @@ de: labels: term: Begriff searches: Suchen - click_through: Klickrate + click_through: CTR emails: title: "Gesendete E-Mails" xaxis: "Tag" @@ -840,7 +842,7 @@ de: xaxis: "Tag" yaxis: "Anzahl der Nachrichten" user_to_user_private_messages_with_replies: - title: "Benutzer-an-Benutzer (mit Antworten)" + title: "Benutzer-zu-Benutzer (mit Antworten)" xaxis: "Tag" yaxis: "Anzahl der Nachrichten" system_private_messages: @@ -887,6 +889,7 @@ de: xaxis: "Tag" yaxis: "Aufrufe durch Suchmaschinen" page_view_total_reqs: + title: "Seitenaufrufe" xaxis: "Tag" yaxis: "Seitenaufrufe insgesamt" page_view_logged_in_mobile_reqs: @@ -1676,7 +1679,7 @@ de: revoked: "Sende keine E-Mails an '%{email}' bis %{date}." ip_address: 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." + max_new_accounts_per_registration_ip: "Weitere Registrierungen sind von deiner IP-Adresse aus nicht gestattet (maximale Anzahl erreicht). Kontaktiere einen Administrator mit dem Problem damit er dir helfen kann." website: domain_not_allowed: "Webseite ist ungültig. Erlaubte Domains sind: %{domains}" auto_rejected: "Automatisch abgelehnt aufgrund des Alters. Siehe Seiteneinstellung auto_handle_queued_age." @@ -2999,9 +3002,9 @@ de: ## [Welche Informationen sammeln wir?](#collect) - Wir sammeln Informationen von dir, wenn du dich auf unserer Seite registrierst, und erfassten Daten, wenn du dich hier am Forum durch Lesen, Schreiben und Bewertung der geteilten Inhalte beteiligst. + Wir sammeln Informationen von dir, wenn du dich auf unserer Seite registrierst, und erfassen Daten, wenn du dich hier am Forum durch Lesen, Schreiben und Bewertung der geteilten Inhalte beteiligst. - Wenn du dich auf unserer Seite registrierst, wirst du möglicherweise gebeten, deinen Namen und deine E-Mail-Adresse einzugeben. Du kannst unsere Seite jedoch möglicherweise auch ohne Registrierung besuchen. Deine E-Mail-Adresse wird durch eine E-Mail verifiziert, die einen eindeutigen Link enthält. Wenn der Link aufgerufen wird, wissen wir, dass du die Kontrolle über die E-Mail-Adresse hast. + Wenn du dich auf unserer Seite registrierst, wirst du möglicherweise gebeten, deinen Namen und deine E-Mail-Adresse einzugeben. Du kannst unsere Seite jedoch auch ohne Registrierung besuchen. Deine E-Mail-Adresse wird durch eine E-Mail verifiziert, die einen eindeutigen Link enthält. Wenn der Link aufgerufen wird, wissen wir, dass du die Kontrolle über die E-Mail-Adresse hast. Wenn du registrierst bist und etwas schreibst, erfassen wir die IP-Adresse, von der der Beitrag stammt. Wir behalten möglicherweise Serverprotokolle, die die IP-Adresse jeder Anfrage an unseren Server enthält. @@ -3011,7 +3014,7 @@ de: Jede der Informationen, die wir von dir sammeln, kann auf eine der folgenden Arten genutzt werden: - * Um deine Erfahrung zu personalisieren — deine Information hilft uns dabei, besser auf deine individuellen Bedürfnise einzugehen. + * Um deine Erfahrung zu personalisieren — deine Information hilft uns dabei, besser auf deine individuellen Bedürfnisse einzugehen. * Um unsere Seite zu verbessern — wir streben kontinuierlich dazu, das Angebot unserer Seite auf Grundlage der Informationen und des Feedbacks zu verbessern, das wir von dir erhalten. * Um unseren Kundendienst zu verbessern — deine Information hilft uns, effizienter auf deine Anfragen an den Kundendienst und deine Hilfsbedürfnisse einzugehen. * Um wiederkehrende E-Mails zu senden — Die E-Mail-Adresse, die du angibst, kann genutzt werden, um dir Informationen und Benachrichtigungen zu senden, die du zu Änderungen an Themen oder in Bezug auf deinen Benutzernamen angefordert hast, um dir auf Nachfragen, Anfragen oder Fragen zu antworten. @@ -3024,18 +3027,18 @@ de: - ## [Was sehen eure Bestimmungen zur Datenaufbewahrung aus?](#data-retention) + ## [Wie sehen unsere Bestimmungen zur Datenaufbewahrung aus?](#data-retention) Wir bemühen uns nach bestem Wissen und Gewissen: - * Serverprotokolle, die IP-Adressen aller Anfragen an unseren Server erhalten, nicht länger als 90 Tage zu speichern. + * Serverprotokolle, die IP-Adressen aller Anfragen an unseren Server enthalten, nicht länger als 90 Tage zu speichern. * IP-Adressen, die mit registrierten Benutzern und ihren Beiträgen verknüpft sind, nicht länger als 5 Jahre zu speichern. ## [Verwenden wir Cookies?](#cookies) - Ja. Cookies sind kleine Dateien, die eine Seite bzw. ihr Dienstleister über einen Browser auf die Festplatte deines Computers überträgst (sofern du zustimmst). Diese Cookies erlauben es der Seite, deinen Browser wiederzuerkennen und, sofern du ein registriertes Konto hast, diesen deinem registrierten Konto zuzuordnen. + Ja. Cookies sind kleine Dateien, die eine Seite bzw. ihr Dienstleister über einen Browser auf die Festplatte deines Computers überträgt (sofern du zustimmst). Diese Cookies erlauben es der Seite, deinen Browser wiederzuerkennen und, sofern du ein registriertes Konto hast, diesen deinem registrierten Konto zuzuordnen. Wir verwenden Cookies, um deine Einstellungen für deine nächsten Besuche zu verstehen und zu speichern und um aggregierte Daten über unseren Internetverkehr und Interaktionen auf der Seite zu berechnen, damit wir in der Zukunft eine bessere Seitenerfahrung und bessere Werkzeuge anbieten können. Wir beauftragen möglicherweise Drittanbieter, die uns dabei unterstützen, unsere Seitenbesucher besser zu verstehen. Diese Dienstleister sind nicht befugt, unsere gesammelten Informationen anders zu verwenden als zur Unterstützung und Verbesserung unseres Geschäfts. @@ -3043,39 +3046,39 @@ de: ## [Geben wir irgendwelche Informationen an Dritte weiter?](#disclose) - Weder verkaufen oder handeln wir deine personenbezogenen Daten noch übermitteln wir diese an Dritte. Dies schließt nicht Drittanbieter ein, die uns beim Betrieb unserer Seite, bei der Durchführung unseres Geschäfts oder dir helfen, solange diese Parteien einwilligen, diese Informationen vertraulich zu behandeln. We geben deine Informationen möglicherweise frei, wenn wir glauben, dass die Freigabe zweckmäßig ist, um das Gesetz einzuhalten, unsere Seitenrichtlinien durchzusetzen oder unsere oder fremde Rechte, Werte oder Sicherheit zu schützen. Nicht-personenbezogene Daten werden möglcherweise anderen Parteien für Marketing, Werbung und andere Zwecke zugänglich gemacht. + Weder verkaufen oder handeln wir deine personenbezogenen Daten noch übermitteln wir diese an Dritte. Dies schließt nicht Drittanbieter ein, die uns beim Betrieb unserer Seite, bei der Durchführung unseres Geschäfts oder dir helfen, solange diese Parteien einwilligen, diese Informationen vertraulich zu behandeln. Wir geben deine Informationen möglicherweise frei, wenn wir glauben, dass die Freigabe zweckmäßig ist, um das Gesetz einzuhalten, unsere Nutzungsbedingungen durchzusetzen oder unsere oder fremde Rechte, Werte oder Sicherheit zu schützen. Nicht-personenbezogene Daten werden möglicherweise anderen Parteien für Marketing, Werbung und andere Zwecke zugänglich gemacht. - ## [Linsk auf fremde Webseiten](#third-party) + ## [Links auf fremde Webseiten](#third-party) - Gelegentlich können wir Produkte oder Dienste von Dritten nach unserer Wahl auf unserer Seite einbinden oder darauf bewerben. Diese Drittanbieter haben eigene und unabhängige Datenschutzbestimmungen. Wir übernehmen daher keine Verantwortung oder Haftung für den Inhalt und die Aktivitäten dieser verknüpften Seite. Dennoch sind wir bemüht, die Integrität unserer Seite zu schützen und freuen uns über jedes Feedback zu diesen Seiten. + Gelegentlich können wir Produkte oder Dienste von Dritten nach unserer Wahl auf unserer Seite einbinden oder darauf bewerben. Diese Drittanbieter haben eigene und unabhängige Datenschutzrichtlinien. Wir übernehmen daher keine Verantwortung oder Haftung für den Inhalt und die Aktivitäten dieser verknüpften Seite. Dennoch sind wir bemüht, die Integrität unserer Seite zu schützen und freuen uns über jedes Feedback zu diesen Seiten. ## [Gesetz zum Schutz der Privatsphäre von Kindern im Internet](#coppa) - Unsere Seite, Produkte und Dienstleistungen richten sich alle an Menschen, die mindestens 13 Jahre oder älter sind. Wenn sich dieser Server in der USA befindet und du unter 13 Jahre alt bist, so benutze diese Seite gemäß der Anforderungen des COPPA-Gesetzes ([Children's Online Privacy Protection Act](https://de.wikipedia.org/wiki/Children%E2%80%99s_Online_Privacy_Protection_Act)) nicht. + Unsere Seite, Produkte und Dienstleistungen richten sich alle an Menschen, die mindestens 13 Jahre oder älter sind. Wenn sich dieser Server in der USA befindet und du unter 13 Jahre alt bist, so benutze diese Seite gemäß der Anforderungen des COPPA-Gesetzes ([Children's Online Privacy Protection Act](https://de.wikipedia.org/wiki/Children%27ss_Online_Privacy_Protection_Act)) nicht. - ## [Online-Datenschutzbestimmungen](#online) + ## [Online-Datenschutzrichtlinie](#online) - Diese Online-Datenschutzbestimmungen gilt nur für Informationen, die durch unsere Seite gesammelt werden, und nicht für offline erfasste Informationen. + Diese Online-Datenschutzrichtlinie gilt nur für Informationen, die durch unsere Seite gesammelt werden, und nicht für offline erfasste Informationen. ## [Deine Zustimmung](#consent) - Indem du unsere Seite benutzt, stimmst du den Datenschutzschutzbestimmungen unserer Webseite zu. + Indem du unsere Seite benutzt, stimmst du der Datenschutzrichtlinie unserer Webseite zu. - ## [Änderungen unserer Datenschutzbestimmungen](#changes) + ## [Änderungen unserer Datenschutzrichtlinie](#changes) - Wenn wir uns dazu entscheiden, unsere Datenschutzbestimmungen zu ändern, werden wir diese Änderungen auf dieser Seite veröffentlichen. + Wenn wir uns dazu entscheiden, unsere Datenschutzrichtlinie zu ändern, werden wir diese Änderungen auf dieser Seite veröffentlichen. - Dieses Dokument ist als CC-BY-SA lizensiert. Es wurde zuletzt aktualisiert am am 31. Mai 2013. + Dieses Dokument ist als CC-BY-SA lizenziert. Es wurde zuletzt aktualisiert am 31. Mai 2013. badges: editor: name: Bearbeiter diff --git a/config/locales/server.el.yml b/config/locales/server.el.yml index ad10228e5b..0f5432017e 100644 --- a/config/locales/server.el.yml +++ b/config/locales/server.el.yml @@ -684,9 +684,7 @@ el: xaxis: "Ημέρα" yaxis: "Αριθμός επισκέψεων" signups: - title: "Νέοι Χρήστες" xaxis: "Ημέρα" - yaxis: "Αριθμός νέων χρηστών" profile_views: title: "Προβολές Προφίλ Χρήστη" xaxis: "Ημέρα" diff --git a/config/locales/server.en.yml b/config/locales/server.en.yml index d67781b656..43d12c2588 100644 --- a/config/locales/server.en.yml +++ b/config/locales/server.en.yml @@ -89,6 +89,7 @@ en: 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 were no attachments." no_sender_detected_error: "Happens when we couldn't find a valid email address in the From header." + from_reply_by_address_error: "Happens when the From header matches the reply by email address." inactive_user_error: "Happens when the sender is not active." silenced_user_error: "Happens when the sender has been silenced." bad_destination_address: "Happens when none of the email addresses in To/Cc/Bcc fields matched a configured incoming email address." @@ -843,10 +844,10 @@ en: xaxis: "Day" yaxis: "Number of visits" signups: - title: "New Users" + title: "Signups" xaxis: "Day" - yaxis: "Number of new users" - description: "New registrations for this period" + yaxis: "Number of signups" + description: "New account registrations for this period" new_contributors: title: "New Contributors" xaxis: "Day" @@ -855,8 +856,8 @@ en: dau_by_mau: title: "DAU/MAU" xaxis: "Day" - yaxis: "DAU/MAY" - description: "DAU / MAU – no. of members that logged in in the last day divided by no. of members that logged in in the last month – returns a %" + yaxis: "DAU/MAU" + description: "No. of members that logged in in the last day divided by no of members that logged in in the last month – returns a % which indicates community 'stickiness'. Aim for >30%." daily_engaged_users: title: "Daily Engaged Users" xaxis: "Day" diff --git a/config/locales/server.es.yml b/config/locales/server.es.yml index e736c0a67e..ec146fd0a3 100644 --- a/config/locales/server.es.yml +++ b/config/locales/server.es.yml @@ -34,40 +34,41 @@ es: 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" remove_posts_deleted_by_author: "Eliminado por su autor" - redirect_warning: "No hemos podido comprobar que el enlace que has seleccionado haya sido publicado en el foro. Si quieres continuar aun así, selecciona el enlace abajo." + redirect_warning: "No pudimos verificar que el enlace que seleccionó se haya publicado en el foro. Si desea continuar de todos modos, seleccione el enlace a continuación." themes: bad_color_scheme: "No puedes actualizar theme, esquema de color inválido" other_error: "Algo salió mal actualizando el theme" - error_importing: "Error al clonar el repositorio de git. El acceso ha sido denegado o el repositorio no se encuentra." + error_importing: "Error al clonar el repositorio de git, acceso denegado o no se encuentra el repositorio" settings_errors: - invalid_yaml: "El YAML no es válido." - data_type_not_a_number: "El tipo de ajuste `%{name}` no está soportado. Los tipos soportados son `integer`, `bool`, `list` y `enum`" - name_too_long: "Hay un ajuste con un nombre demasiado largo. La longitud máxima es 255" - default_value_missing: "El ajuste `%{name}` no tiene un valor por defecto" - default_not_match_type: "El tipo del valor por defecto del ajuste `%{name}` no coincide con el tipo del ajuste" - default_out_range: "El valor por defecto del ajuste `%{name}` no está en el rango especificado." - enum_value_not_valid: "El valor seleccionado no es una de las opciones" - number_value_not_valid: "El nuevo valor está fuera del rango permitido" + invalid_yaml: "YAML provisto es inválido." + data_type_not_a_number: "Tipo de ajuste `%{name}` no está soportado. Tipos soportados: `integer`, `bool`, `list` and `enum`" + name_too_long: "Hay un ajuste con un nombre muy largo. Cantidad máxima de caracteres es 255" + default_value_missing: "Ajuste `%{name}`` no tiene valor por defecto" + default_not_match_type: "Tipo de valor por defecto para el ajuste `%{name}` no coincide con el tipo de ajuste." + default_out_range: "Valor por defecto del ajuste `%{name}` no está en el rango específico." + enum_value_not_valid: "El valor seleccionado no es una de las opciones enumeradas." + number_value_not_valid: "El nuevo valor no está dentro del rango permitido." number_value_not_valid_min_max: "Debe ser entre %{min} y %{max}." number_value_not_valid_min: "Debe ser mayor o igual que %{min}." - number_value_not_valid_max: "Debe ser más pequeño o igual que %{max}." - string_value_not_valid: "La longitud del nuevo valor está fuera del rango permitido." - string_value_not_valid_min_max: "Debe tener entre %{min} y %{max} caracteres de longitud." - string_value_not_valid_min: "Debe tener al menos %{min} caracteres." - string_value_not_valid_max: "Debe tener al menos %{max} caracteres de longitud." + number_value_not_valid_max: "Debe ser menor o igual que %{max}." + string_value_not_valid: "La nueva longitud del valor no está dentro del rango permitido." + string_value_not_valid_min_max: "Debe ser entre %{min} y %{max} de longitud de caracteres." + string_value_not_valid_min: "Debe ser al menos de %{min} caracteres de longitud." + string_value_not_valid_max: "Debe ser como máximo de %{max} caracteres de longitud." emails: incoming: default_subject: "Este tema necesita un título" show_trimmed_content: "Mostrar contenido recortado" maximum_staged_user_per_email_reached: "Alcanzado el número máximo de usuarios provisionales creados por email." - no_subject: "(sin asunto)" - no_body: "(sin contenido)" + no_subject: "(sin título)" + no_body: "(sin mensaje)" 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." no_sender_detected_error: "Sucede cuando no podemos encontrar una dirección de email válida desde el encabezado From." + from_reply_by_address_error: "Ocurre cuando el encabezado From coincide con la respuesta por dirección de correo electrónico." inactive_user_error: "Sucede cuando el emisor no está activo." silenced_user_error: "Ocurre cuando el remitente ha sido silenciado." 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." @@ -101,7 +102,7 @@ es: has_already_been_used: "ya se está utilizando" inclusion: no está incluido en la lista invalid: no es válido - is_invalid: "parece poco claro, ¿es una oración completa?" + is_invalid: "parece poco claro, es una oración completa?" contains_censored_words: "contiene las siguientes palabras censuradas: %{censored_words}" less_than: "debe ser menor que %{count}" less_than_or_equal_to: "debe ser menor o igual que %{count}" @@ -109,8 +110,8 @@ es: not_an_integer: debe ser un valor entero odd: debe ser impar record_invalid: 'Error en la validación: %{errors}' - max_emojis: "no puedes tener más de %{max_emojis_count} emojis" - ip_address_already_screened: "ya está incluido en una regla existente" + max_emojis: "no puede tener más de %{max_emojis_count} emoji" + ip_address_already_screened: "ya se está incluido en una regla existente" restrict_dependent_destroy: one: "No se pudo eliminar el registro porque existe otro %{record} dependiente" many: "No se puede eliminar el registro porque existen otros %{record} dependientes" @@ -132,18 +133,27 @@ es: embed: load_from_remote: "Hubo un error al cargar ese post." site_settings: + invalid_choice: + one: Has especificado la opción inválida %{name} + other: Has especificado las opciones inválidas %{name} min_username_length_exists: "No se puede establecer una longitud mínima para nombre de usuario mayor que el nombre de usuario más corto ya existente." min_username_length_range: "No se puede establecer el mínimo por encima del máximo." max_username_length_exists: "No se puede establecer una longitud máxima de nombre de usuario menor que el nombre de usuario más largo ya existente." max_username_length_range: "No puedes poner el máximo por debajo del mínimo." default_categories_already_selected: "No se puede seleccionar una categoría ya utilizada en otra lista." s3_upload_bucket_is_required: "No se pueden activar las subidas a S3 a menos que se haya proporcionado un valor a 's3_upload_bucket'." - conflicting_google_user_id: 'La ID de la cuenta de Google para esta cuenta ha cambiado; por motivos de seguridad, hace falta que un miembro del staff intervenga. Por favor, ponte en contacto con el staff y mándales a
    https://meta.discourse.org/t/76575' + conflicting_google_user_id: 'El ID de la cuenta Google para esta cuenta ha cambiado; el staff debe intervenir por razones de seguridad. Por favor, póngase en contacto con miembros del staff y envíe esta referencia
    https://meta.discourse.org/t/76575' activemodel: errors: <<: *errors invite: not_found: "El código de la invitación es inválido. Por favor, ponte en contacto con un administrador." + not_found_template: | +

    Tu invitación a %{site_name} ya ha sido redimida.

    + +

    Si recuerdas tu contraseña puedes Ingresar.

    + +

    O bien, por favor Resetear Contraseña.

    user_exists: "No hay necesidad de invitar a %{email}, ya tiene una cuenta!" bulk_invite: file_should_be_csv: "El archivo subido debería ser de formato csv." @@ -155,7 +165,7 @@ es: backup_file_should_be_tar_gz: "El archivo de la copia de seguridad debería ser del tipo .tar.gz" not_enough_space_on_disk: "No hay espacio suficiente en el disco para subir esta copia de seguridad." invalid_filename: "El nombre de archivo del backup contiene caracteres no válidos. Los válidos son a-z 0-9 . - _." - invalid_params: "Has incluido parámetros no válidos a la solicitud: %{message}" + invalid_params: "Proporcionó parámetros no válidos para la solicitud: %{message}" not_logged_in: "Tienes que iniciar sesión para hacer eso." not_found: "No se ha podido encontrar la URL o recurso solicitado." invalid_access: "No tienes permiso para ver el recurso solicitado." @@ -167,8 +177,8 @@ es: 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. embed: - start_discussion: "Empezar debate" - continue: "Continuar debate" + start_discussion: "Empezar discusión" + continue: "Continuar discusión" error: "Error al insertar" referer: "Referente:" mismatch: "El referente no ha coincidido con ninguno de los siguientes hosts:" @@ -192,7 +202,7 @@ es: too_many_mentions_newuser: 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_trust: "Lo sentimos, pero no puedes incluir imágenes en tus mensajes en estos momentos" + no_images_allowed_trust: "Lo sentimos, no puedes poner imágenes en una publicación" no_images_allowed: "Lo sentimos, pero los usuarios nuevos no pueden poner imágenes en los mensajes." too_many_images: one: Lo sentimos, pero los usuarios nuevos solo pueden poner una imagen por post. @@ -202,11 +212,11 @@ es: 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." - links_require_trust: "Lo sentimos, pero no puedes incluir enlaces en tus mensajes en estos momentos" + links_require_trust: "Lo sentimos, no puedes incluir enlaces en tus posts." too_many_links: 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. - contains_blocked_words: "Tu mensaje contiene una palabra no permitida: %{word}" + contains_blocked_words: "Tu post contiene una palabra que no está permitida: %{word}" 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 ha sido cerrado o eliminado mientras estabas lo estabas mirando?" @@ -214,7 +224,7 @@ es: max_pm_recepients: "Lo sentimos, puedes enviar un mensaje a un máximo de %{recipients_limit} destinatarios." just_posted_that: "es demasiado parecido a lo que has publicado recientemente" invalid_characters: "contiene caracteres no válidos" - is_invalid: "parece poco claro, ¿es una oración completa?" + is_invalid: "parece poco claro, es una oración completa?" next_page: "siguiente página →" prev_page: "← página anterior" page_num: "Página %{num}" @@ -238,7 +248,7 @@ es: top_weekly: "Semanal: Temas Top" top_daily: "Diario: Temas Top" posts: "Últimos posts" - private_posts: "Últimos mensajes personales" + private_posts: "Últimos mensajes privados" group_posts: "Últimos posts de %{group_name}" group_mentions: "Últimas menciones de %{group_name}" user_posts: "Posts recientes por @%{username}" @@ -249,16 +259,19 @@ es: 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 cola de moderación de posts" - not_found: "Post no encontrado o ya actualizado." + delete_reason: "Eliminado vía moderación" + not_found: "Post no encontrado o ya se actualizó." groups: success: bulk_add: - one: '%{count} usuario ha sido añadido al grupo.' - other: '%{count} usuarios han sido añadidos al grupo.' + one: '%{count} usuario ha sido agregado al grupo.' + other: '%{count} usuarios han sido agregados al grupo.' errors: - grant_trust_level_not_valid: "'%{trust_level}' no es un nivel de confianza válido" + grant_trust_level_not_valid: "'%{trust_level}' no es un nivel de confianza válido." can_not_modify_automatic: "No se puede modificar un grupo automático" + member_already_exist: + one: '''%{username}'' ya es miembro de este grupo.' + other: 'Los siguientes usuarios ya son miembros de éste grupo: %{username}' 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}'." @@ -281,7 +294,7 @@ es: one: 1 post other: '%{count} posts' 'new-topic': | - Bienvenido a %{site_name} — **¡gracias por empezar una nueva conversación!** + Bienvenido a %{site_name} — **¡gracias por comenzar una nueva conversación!** - ¿El título describe de forma precisa tu tema? ¿Suena interesante? @@ -303,11 +316,11 @@ es: avatar: | ### Por qué no una imagen para tu cuenta? - Has publicado unos cuantos temas y respuestas, pero tu imagen de perfil no es único como lo eres tú., es sólo una letra. + Has publicado pocos temas y respuestas, pero tu imagen de perfil no es único como lo eres tú., es sólo una letra. - ¿Has considerado **[visitar tu perfil](%{profile_path})** y subir una imagen que te represente? + Has considerado **[visitar tu perfil](%{profile_path})** y subir una imagen que te represente? - ¡Es más fácil seguir debates y encontrar personas interesantes en las conversaciones cuando todos tienen una imagen de perfil única! + Es más fácil seguir debates y encontrar personas interesantes en las conversaciones cuando todos tienen una imagen de perfil única! sequential_replies: | ### Considera la posibilidad de responder a varios posts a la vez @@ -327,7 +340,7 @@ es: Has respondido %{count} veces a @%{reply_username} sólo en este tema. - ¿Has considerado que puedes responder a las *otras* personas en el debate también? Una buena conversación incluye muchas respuestas y perspectivas. + Has considerado que puedes responder a las *otras* personas en el debate también? Una buena conversación incluye muchas respuestas y perspectivas. Si necesitas mantener la conversación con ese usuario en particular, puedes [enviarle un mensaje privado](/u/%{reply_username}). too_many_replies: | @@ -339,9 +352,9 @@ es: reviving_old_topic: | ### ¿Revivir este tema? - La última respuesta a este tema fue **%{time_ago}**. Tu respuesta revivirá el tema y lo subirá al principio de la lista, notificando a los que hayan participado anteriormente. + La última respuesta a este tema fue hace **%{time_ago}**. Tu post reactivará el tema subiéndolo a las primeras posiciones de la lista y notificará a aquellos involucrados previamente en la conversación. - ¿Seguro que quieres continuar esta conversación antigua? + ¿Estás seguro de que quieres continuar esta conversación antigua? activerecord: attributes: category: @@ -359,12 +372,12 @@ es: topic: attributes: base: - warning_requires_pm: "Solo puedes adjuntar advertencias a mensajes personales." + warning_requires_pm: "Solamente puedes enviar advertencias por mensajes privado." too_many_users: "Solamente puedes enviar advertencias a un usuario a la vez." - cant_send_pm: "Lo sentimos, no puedes enviarle mensajes personales a ese usuario." + cant_send_pm: "Lo sentimos, no puedes enviar un mensaje personal a este usuario." no_user_selected: "Debes seleccionar un usuario válido." reply_by_email_disabled: "Respuestas por email han sido desactivadas." - target_user_not_found: "Uno de los usuarios a los que le estás enviando el mensaje no ha sido encontrado." + target_user_not_found: "No se pudo encontrar uno de los usuarios a los que envía este mensaje." featured_link: invalid: "es inválido. La dirección debería incluir http:// o https://." invalid_category: "no puede ser editado en esta categoría." @@ -373,7 +386,7 @@ es: password: common: "es una de las 10000 contraseñas más comunes. Por favor usa una contraseña más segura" same_as_username: "es la misma que tu nombre de usuario. Por favor, escoge una contraseña más segura." - same_as_email: "es la misma que tu email. Por favor, utiliza una contraseña más segura." + same_as_email: "es el mismo que tu email. Por favor, utiliza una contraseña más segura." same_as_current: "es la misma que tu contraseña actual." unique_characters: "tiene demasiados caracteres repetidos. Por favor usa una contraseña más segura." ip_address: @@ -381,7 +394,7 @@ es: user_email: attributes: user_id: - reassigning_primary_email: "No se puede reasignar un correo primario a otro usuario." + reassigning_primary_email: "Reasignar un email primario a otro usuario no está permitido." color_scheme_color: attributes: hex: @@ -419,9 +432,9 @@ es: staff_category_name: "Staff" staff_category_description: "Categoría privada para debates entre moderadores y administradores. Los temas solo serán visibles para miembros del staff." assets_topic_title: "Recursos para el diseño del sitio" - assets_topic_body: "Este tema, visible únicamente para miembros del staff, tiene como fin el almacenar las imágenes y archivos utilizados en el diseño del sitio. ¡No lo elimines!\n\n\nCómo hacerlo:\n\n\n1. Responde a este tema.\n2. Sube todas las imágenes que desees para los logos, favicons y demás aquí. (Usa el icono de la barra de herramientas en el editor o arrastra y suelta las imágenes o pégalas). \n3. Publica tu respuesta.\n4. Haz clic con el botón derecho en las imágenes de tu nuevo post para obtener la ruta donde están subidas, o haz clic en el icono de editar para ver estas rutas en el panel de edición. Copia las rutas.\n5. Pega las rutas a las imágenes en [ajustes básicos](/admin/site_settings/category/required).\n\n\nSi necesitas habilitar la subida de diferentes tipos de archivo, edita `authorized_extensions` en las opciones de [archivos](/admin/site_settings/category/files)." + assets_topic_body: "Este tema, es visible únicamente para miembros del staff, con el fin de almacenar las imágenes y archivos utilizados en el diseño del sitio. ¡No lo elimines!\n\n\nCómo hacerlo:\n\n\n1. Responde a este tema.\n2. Sube todas las imágenes que desees para los logos, favicons y demás aquí. (Usa el icono de la barra de herramientas en el editor o arrastra y suelta las imágenes o pégalas). \n3. Publica tu respuesta.\n4. Haz clic con el botón derecho en las imágenes de tu nuevo post para obtener la ruta donde están subidas, o haz clic en el icono de editar para ver estas rutas en el panel de edición. Copia las rutas.\n5. Pega las rutas a las imágenes en [ajustes básicos](/admin/site_settings/category/required).\n\n\nSi necesitas habilitar la subida de diferentes tipos de archivo, edita `authorized_extensions` en las opciones de [archivos](/admin/site_settings/category/files)." discourse_welcome_topic: - title: "Te damos la bienvenida a Discourse" + title: "Bienvenido a Discourse" body: |2 El primer párrafo de este tema destacado (tema fijo) será visible para todos los usuarios como mensaje de bienvenida en tu página principal. Es importante! @@ -460,7 +473,7 @@ es: [trust]: https://meta.discourse.org/t/what-do-user-trust-levels-do/4924 category: - topic_prefix: "Acerca de la categoría %{category}" + topic_prefix: "Definición de la categoría %{category}" 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: @@ -497,22 +510,22 @@ es: broken: "Esta imagen está rota" rate_limiter: slow_down: "Has realizado esta acción muchas veces, por favor inténtalo de nuevo más tarde." - too_many_requests: "Has realizado esta acción demasiadas veces. Por favor, espera %{time_left} antes de volverlo a intentar." + too_many_requests: "Has realizado esta acción muchas veces. Por favor espera %{time_left} antes de intentar nuevamente." 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 mensajes demasiado rápido. Por favor espera %{time_left} antes de intentarlo de nuevo." - public_group_membership: "Estás uniéndote o saliendo de grupos con mucha frecuencia. Por favor, espera %{time_left} antes de volver a intentarlo." - topics_per_day: "Has llegado al límite de nuevos temas. Por favor, espera %{time_left} antes de intentarlo de nuevo." - pms_per_day: "Has llegado al límite de mensajes. Por favor, espera %{time_left} antes de intentarlo de nuevo." - create_like: "Has llegado al límite de Me gusta. Por favor, espera %{time_left} antes de intentarlo de nuevo." - create_bookmark: "Has llegado al límite de marcadores. Por favor, espera %{time_left} antes de intentarlo de nuevo." - edit_post: "Has llegado al límite de ediciones. 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 favor, espera %{time_left} antes de intentarlo de nuevo." - topic_invitations_per_day: "Has alcanzado el máximo de invitaciones a temas. Por favor, espera %{time_left} antes de intentarlo de nuevo." + first_day_replies_per_day: "Has alcanzado el número máximo de respuestas que un nuevo usuario puede publicar en su primer día. Por favor espera %{time_left} antes de intentar de nuevo." + first_day_topics_per_day: "Has alcanzado el número máximo de temas que un nuevo usuario puede publicar en su primer día. Por favor espera %{time_left} antes de intentar de nuevo." + create_topic: "Has creado temas muy rápido. Por favor espera %{time_left} antes de intentar de nuevo." + create_post: "Has respondido muy rápido. Por favor espera %{time_left} antes de intentar de nuevo." + delete_post: "Estás borrando posts muy rápido. Por favor espera %{time_left} antes de intentar de nuevo." + public_group_membership: "Estás ingresando/saliendo de grupos muy frecuentemente. Por favor espera %{time_left} antes de intentar de nuevo." + topics_per_day: "Has alcanzado el número máximo de nuevos temas. Por favor espera %{time_left} antes de intentar de nuevo." + pms_per_day: "Has alcanzado el número máximo de mensajes. Por favor espera %{time_left} antes de intentar de nuevo." + create_like: "Has alcanzado el número máximo de likes. Por favor espera %{time_left} antes de intentar de nuevo." + create_bookmark: "Has alcanzado el número máximo de favoritos. Por favor espera %{time_left} antes de intentar de nuevo." + edit_post: "Has alcanzado el número máximo de ediciones. Por favor espera %{time_left} antes de intentar de nuevo." + live_post_counts: "Estás pidiendo recuentos de posts en vivo muy rápido. Por favor espera %{time_left} antes de intentar de nuevo." + unsubscribe_via_email: "Has alcanzado el número máximo de desuscripciones por email. Por favor espera %{time_left} antes de intentar de nuevo." + topic_invitations_per_day: "Has alcanzado el número máximo de invitaciones al tema. Por favor espera %{time_left} antes de intentar de nuevo." hours: one: 1 hora other: '%{count} horas' @@ -544,20 +557,20 @@ es: one: 1d other: '%{count}d' about_x_months: - one: 1mes - other: '%{count}mes' + one: 1mon + other: '%{count}mon' x_months: - one: 1mes - other: '%{count}mes' + one: 1mon + other: '%{count}mon' about_x_years: - one: 1a - other: '%{count}a' + one: 1y + other: '%{count}y' over_x_years: - one: '> 1a' - other: '> %{count}a' + one: '> 1y' + other: '> %{count}y' almost_x_years: - one: 1a - other: '%{count}a' + one: 1y + other: '%{count}y' distance_in_words_verbose: half_a_minute: "ahora mismo" less_than_x_seconds: @@ -596,15 +609,15 @@ es: password_reset: no_token: "Lo sentimos, ese enlace para cambiar la contraseña es demasiado antiguo. Haz clic en el botón Iniciar sesión y utiliza el 'olvidé mi contraseña' para obtener un nuevo enlace. " choose_new: "Escoge una nueva contraseña" - choose: "Escoge una contraseña" + choose: "Escoge una contraseñ" update: 'Actualizar contraseña' save: 'Establecer contraseña' title: 'Restablecer contraseña' success: "Has cambiado tu contraseña correctamente y ahora has iniciado sesión." success_unapproved: "Has cambiado tu password correctamente." email_login: - invalid_token: "Lo sentimos, este enlace de inicio de sesión por email es demasiado antiguo. Selecciona el botón de Iniciar sesión y usa la opción 'Olvidé mi contraseña' para obtener un nuevo enlace. " - title: "Inicio de sesión con email" + invalid_token: "Lo sentimos, ese enlace de inicio de sesión de correo electrónico es demasiado viejo. Seleccione el botón Iniciar sesión y use 'Olvidé mi contraseña' para obtener un nuevo enlace." + title: "Email login" change_email: confirmed: "Tu email ha sido actualizado." please_continue: "Continuar a %{site_name}" @@ -619,22 +632,22 @@ es: already_done: "Lo sentimos, este link de confirmación de cuenta ya no es válido. ¿Quizás tu cuenta ya está activa?" please_continue: "Tu nueva cuenta está confirmada; se te redirigirá a la página de inicio." continue_button: "Continuar a %{site_name}" - welcome_to: "¡Te damos la bienvenida a %{site_name}!" - approval_required: "Un moderador o moderadora debe aprobar manualmente tu nueva cuenta antes de que puedas acceder a este foro. ¡Recibirás un email cuando tu cuenta sea aprobada!" - missing_session: "No hemos podido detectar si tu cuenta ha sido creada. Por favor, asegúrate de tener activadas las cookies en tu navegador." + welcome_to: "Bienvenido a %{site_name}!" + approval_required: "Un moderador debe aprobar manualmente tu nueva cuenta antes de que puedas acceder a este foro. ¡Recibirás un email cuando tu cuenta sea aprobada!" + missing_session: "No hemos podido detectar si tu cuenta fue creada. Por favor, asegúrate de tener activadas las cookies en tu navegador." activated: "Disculpa, esta cuenta ya ha sido activada." admin_confirm: - title: "Confirmar cuenta administrativa" + title: "Confirmar Cuenta Administrador" description: "Estás seguro que quieres que %{target_username} sea un administrador?" - grant: "Conceder acceso de administración" + grant: "Conceder acceso de Admin" complete: "%{target_username} es ahora un administrador." back_to: "Volver al %{title}" post_action_types: off_topic: - title: 'Fuera de tema' + title: 'Off-Topic' description: 'Este post se desvía demasiado o no es relevante para el tema en cuestión (definido por el título del tema y su primer post), probablemente debería ser movido a otro hilo.' - short_description: 'No es relevante para el debate' - long_form: 'reportado como fuera de tema' + short_description: 'No es relevante para la discusión' + long_form: 'reportado como off-topic' spam: title: 'Spam' description: 'Este post es publicidad, o vandalismo. No es útil o relevante para el tema.' @@ -649,8 +662,8 @@ es: long_form: 'reportado como inapropiado' notify_user: title: 'Enviar un mensaje a @{{username}}' - description: 'Quiero hablar con esta persona de forma directa y personal sobre su mensaje.' - short_description: 'Quiero hablar con esta persona de forma directa y personal sobre su mensaje.' + description: 'Quiero hablar con esta persona directa y personalmente sobre su post.' + short_description: 'Quiero hablar con esta persona directa y personalmente sobre su post.' long_form: 'usuario notificado vía mensaje' email_title: 'Tu publicación en "%{title}"' email_body: "%{link}\n\n%{message}" @@ -667,7 +680,7 @@ es: short_description: 'Guarda este post' long_form: 'Post marcado' like: - title: 'Me gusta' + title: 'Like' description: 'Te gusta este post' short_description: 'Te gusta este post' long_form: 'Te gusta esto' @@ -675,7 +688,7 @@ es: title: 'Vota' description: 'Vota por este post' short_description: 'Vota por este post' - long_form: 'votado por este post' + long_form: 'Votado para este post' user_activity: no_default: self: "No tienes actividad aún." @@ -711,15 +724,15 @@ es: regular: title: "Tema normal" banner: - title: "Tema de encabezado" + title: "Tema de Encabezado" message: make: "Este tema se utiliza ahora como banner. Aparecerá en la parte superior de cada página hasta que sea descartada por el usuario." remove: "Este tema ya no se utiliza como banner. Ya no aparecerá en la parte superior de cada página." unsubscribed: title: "¡Suscripción cancelada!" - description: "%{email} se ha desuscrito. Para cambiar la configuración del email, visita las preferencias del usuario." + description: "%{email} ha sido desuscrito. Para cambiar la configuración del email visita las preferencias del usuario." topic_description: "Para volver a suscribirte a %{link}, utiliza el desplegable de notificación al pie o en la parte derecha del tema." - private_topic_description: "Para volver a suscribirte, usa el control de notificaciones en la parte de abajo a la derecha del tema." + private_topic_description: "Para volver a suscribirte, use el control de notificación al pie o en la parte derecha del tema." unsubscribe: title: "Cancelar suscripción" stop_watching_topic: "Dejar de vigilar este tema, %{link}" @@ -752,13 +765,25 @@ es: xaxis: "Día" yaxis: "Número de visitas" signups: - title: "Nuevos usuarios" + title: "Registros" xaxis: "Día" - yaxis: "Número de usuarios nuevos" + yaxis: "Número de Registros" + description: "Nuevos registros de cuentas para este periodo" new_contributors: - title: "Nuevos contribuyentes" + title: "Nuevos Colaboradores" xaxis: "Día" - yaxis: "Número de nuevos contribuyentes" + yaxis: "Número de nuevos colaboradores" + description: "Número de usuarios quienes hicieron su primer post en este periodo" + dau_by_mau: + title: "UAD/UAM" + xaxis: "Día" + yaxis: "UAD/UAM" + description: "Nro. de miembros que se loguearon en el último día dividido el núm. de miembros que se loguearon en el último mes – devuelve un % que indica la 'adhesión' de la comunidad. Apunta al >30%." + daily_engaged_users: + title: "Usuarios comprometidos a diario" + xaxis: "Día" + yaxis: "Usuarios Comprometidos" + description: "Número de usuarios que le han gustado o publicado en el último día" profile_views: title: "Visitas a perfil de usuario" xaxis: "Día" @@ -767,10 +792,12 @@ es: title: "Temas nuevos" xaxis: "Día" yaxis: "Número de topics nuevos" + description: "Nuevos temas creados durante este período" posts: title: "Nuevos posts" xaxis: "día" yaxis: "Número de posts nuevos" + description: "Nuevos posts creados durante este periodo" likes: title: "Me gusta" xaxis: "Día" @@ -792,27 +819,30 @@ es: xaxis: "Día" yaxis: "Número de usuarios" users_by_type: - title: "Usuarios por tipo" - xaxis: "Tip" - yaxis: "Número de usuarios" + title: "Usuarios por Tipos" + xaxis: "Tipo" + yaxis: "Número de Usuarios" xaxis_labels: - admin: Administrador + admin: Admin moderator: Moderador - suspended: Suspendido - silenced: Silenciado + suspended: Suspendidos + silenced: Silenciados trending_search: - title: Tendencias de búsqueda + title: Trending search labels: term: Término searches: Búsquedas + click_through: CTR emails: title: "Correos enviados" xaxis: "Día" yaxis: "Número de correos" user_to_user_private_messages: + title: "Usuario a usuario (respuestas excluidas)" xaxis: "Día" yaxis: "Número de mensajes" user_to_user_private_messages_with_replies: + title: "Usuario a usuario (con respuestas)" xaxis: "Día" yaxis: "Número de mensajes" system_private_messages: @@ -859,6 +889,7 @@ es: xaxis: "Día" yaxis: "Páginas vistas de rastreadores web" page_view_total_reqs: + title: "Páginas vistas" xaxis: "Día" yaxis: "Total páginas vistas" page_view_logged_in_mobile_reqs: @@ -906,8 +937,8 @@ es: xaxis: "Día" yaxis: "Número de visita" web_crawlers: - title: "Solicitudes de crawlers" - xaxis: "Agente del usuario" + title: "Solicitudes de Rastreadores Web" + xaxis: "User Agent" yaxis: "Páginas vistas" dashboard: rails_env_warning: "Tu servidor está funcionando en modo de %{env}." @@ -928,28 +959,28 @@ es: 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. - missing_mailgun_api_key: "El servidor está configurado para enviar emails con Mailgun pero no has añadido una clave de API para verificar los mensajes de webhook." + missing_mailgun_api_key: "El servidor está configurado para enviar correos electrónicos a través de Mailgun pero no ha proporcionado una clave API utilizada para verificar los mensajes de webhook." bad_favicon_url: "El favicon está dando fallos en su carga. Revisa la opción favicon_url en Ajustes del sitio." poll_pop3_timeout: "La conexión al servidor POP3 está rebasando el tiempo de espera. Los emails entrantes no han podido ser recogidos. Por favor revisa los ajustes de POP3 y tu proveedor de servicio." poll_pop3_auth_error: "La conexión al servidor POP3 está fallando debido a un error de autenticación. Por favor revisa los ajustes POP3." - force_https_warning: "La página está usando SSL, pero el ajuste `force_https` no está activado." + force_https_warning: "Tu sitio web está usando SSL. Pero `force_https` no está aún habilitado en la configuración de tu sitio." 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 este sitio de Discourse" + default_locale: "El idioma por defecto para esta instancia de Discourse " 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)" - support_mixed_text_direction: "Aceptar mezcla de textos tanto de derecha a izquierda como de izquierda a derecha." + support_mixed_text_direction: "Admite direcciones mixtas de texto de izquierda a derecha y de derecha a izquierda." 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_personal_message_post_length: "La longitud mínima en caracteres para los mensajes personales" + min_personal_message_post_length: "Longitud mínima permitida de publicación en caracteres para mensajes" max_post_length: "Extensión máxima de los posts, en número de caracteres" topic_featured_link_enabled: "Activar publicar temas a partir de un enlace." show_topic_featured_link_in_digest: "Mostrar el enlace destacado por el tema en el email de resumen." min_topic_title_length: "Extensión mínima del título de los temas, en número de caracteres" max_topic_title_length: "Extensión máxima del título de los temas, en número de caracteres" - min_personal_message_title_length: "La longitud mínima en caracteres para los títulos de los mensajes personales" - max_emojis_in_title: "Número máximo de emojis que se pueden incluir en el título de un tema" + min_personal_message_title_length: "Longitud mínima permitida del título para un mensaje en caracteres" + max_emojis_in_title: "Emojis máximos permitidos en el título del tema" 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" search_prefer_recent_posts: "Si la búsqueda en tu foro gigante es lenta, esta opción prueba primero un índice de posts más recientes" @@ -970,9 +1001,9 @@ es: download_remote_images_max_days_old: "No descargar imágenes remotas de posts que sean más antiguos de n días." disabled_image_download_domains: "Las imágenes remotas que provengan de estos dominios no serán descargadas. Lista delimitada por barras." 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." - editing_grace_period_max_diff: "El número de caracteres que se permitirán cambiar en el periodo de gracia de edición, si se cambian más se creará una nueva revisión (niveles de confianza 0 y 1)" - editing_grace_period_max_diff_high_trust: "El número de caracteres que se permitirán cambiar en el periodo de gracia de edición, si se cambian más se creará una nueva revisión (niveles de confianza 2 y superiores)" - staff_edit_locks_post: "Los mensajes serán bloqueados y no podrán ser editados por usuarios si son editados por miembros del staff." + editing_grace_period_max_diff: "Número máximo de cambios de caracteres permitidos en el período de gracia de edición, si hay más cambios, almacene otra revisión de publicación (nivel de confianza 0 y 1)" + editing_grace_period_max_diff_high_trust: "Número máximo de cambios de caracteres permitidos en el período de gracia de edición, si hay más cambios, almacene otra revisión de publicación (nivel de confianza 2 y superior)" + staff_edit_locks_post: "Se bloqueará la publicación de las publicaciones si son editadas por miembros del staff." 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." @@ -1007,7 +1038,9 @@ 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_system_message_replies: "Permitir a los usuarios responder a mensajes del sistema incluso si los mensajes personales están desactivados" + enable_personal_messages: "Permitir que los usuarios con nivel de confianza 1 (configurable a través del mínimo nivel de confianza para enviar mensajes) crear mensajes y responder a ellos. Tenga en cuenta que el staff siempre puede enviar mensajes pase lo que pase." + enable_system_message_replies: "Permite a los usuarios responder a los mensajes del sistema, incluso si los mensajes privados están inhabilitados." + enable_personal_email_messages: "Permita que el nivel de confianza 4 (configurable a través del nivel mínimo de confianza para enviar mensajes) envíe mensajes de correo electrónico privados. Tenga en cuenta que el personal siempre puede enviar mensajes, pase lo que pase." 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)." @@ -1028,8 +1061,9 @@ es: notify_mods_when_user_silenced: "Si un usuario es silenciado 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." - enable_markdown_linkify: "Tratar como enlaces el texto que parezca uno automáticamente: www.sitio.com y http://sitio.com serán enlazados automáticamente" - markdown_linkify_tlds: "Lista de dominios de nivel superior que serán tratados automáticamente como enlaces" + enable_markdown_typographer: "Utilice reglas de tipografía para mejorar la legibilidad de texto: remplace citas rectas 'con comillas', (c) (tm) con símbolos, - con emdash -, etc." + enable_markdown_linkify: "Trate automáticamente el texto que se ve como un enlace como un enlace: www.site.com y http://site.com se vincularán automáticamente" + markdown_linkify_tlds: "Lista de dominios de nivel superior que se tratan automáticamente como enlaces" 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." @@ -1045,6 +1079,10 @@ es: blacklist_ip_blocks: "Una lista de IPs bloqueadas privadas que nunca deberían ser rastreadas por Discourse" whitelist_internal_hosts: "Una lista con hosts internos que discourse puede rastrear de forma segura para oneboxing y otros propósitos" allowed_iframes: "Una lista de dominios para iframe src donde discourse pueda permitir de forma segura en mensajes" + whitelisted_crawler_user_agents: 'User agents de rastreadores web a los que se debe permitir el acceso al sitio.' + blacklisted_crawler_user_agents: 'Palabra única insensible a mayúsculas y minúsculas en la cadena del user agent que identifica rastreadores web a los que no se debe permitir el acceso al sitio. No se aplica si se define una lista blanca.' + slow_down_crawler_user_agents: 'User agents de rastreadores web a los que se debe aplicar una tarifa limitada en robots.txt utilizando la directiva de retardo de rastreo' + slow_down_crawler_rate: 'Si slow_down_crawler_user_agents es especificado, este ratio aplicará para todos los crawlers (la solicitud demora número de segundos)' 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." @@ -1062,7 +1100,7 @@ es: 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)" prioritize_username_in_ux: "Mostrar username primero en la página de usuario, tarjeta de usuario y mensajes (cuando el nombre ha sido desactivado se muestra primero)" - enable_rich_text_paste: "Activar la conversión automática de HTML a Markdown al pegar texto en el editor. (Experimental)" + enable_rich_text_paste: "Habilitar conversión automática de HTML a Markdown cuando pegues texto en el compositor. (Experimental)" email_token_valid_hours: "Los tokens para restablecer contraseña olvidada / activar cuenta son válidos durante (n) horas." enable_badges: "Activar el sistema de distintivos" enable_whispers: "Permitir a los miembros del staff comunicarse privadamente entre ellos en temas públicos." @@ -1089,20 +1127,28 @@ es: sso_url: "URL del endpoint para el single sign on (debe incluir http:// o https://)" sso_secret: "Cadena secreta utilizada para autenticar criptográficamente la información del SSO, asegúrate de que es de 10 caracteres o más" sso_overrides_bio: "Sobreescribe la bio del usuario en su perfil y deshabilita que pueda cambiarla" + sso_overrides_groups: "Sincronice toda la membresía del grupo manual con los grupos especificados en el atributo sso de grupos (ADVERTENCIA: si no especifica grupos, todos los miembros del grupo manual serán borrados para el usuario)" sso_overrides_email: "Sobreescribe el email local con el email que provea sitio externo desde el payload del SSO en cada registro, y previene cambios locales. (AVISO: pueden ocasionarse discrepancias debido a la normalización de los emails locales)" sso_overrides_username: "Sobreescribe el usuario local con el usuario que provea el payload del SSO en cada registro, y previene cambios locales. (AVISO: pueden ocasionarse discrepancias debido a las diferencias en los requirimientos/longitud del usuario)" sso_overrides_name: "Sobreescribe el nombre completo con el que provee el payload del SSO en cada registro, y previene cambios locales." sso_overrides_avatar: "Sustituye el avatar de usuario con el avatar proveniente del sitio externo configurado para el SSO. Si se activa esta opción, se recomienda encarecidamente deshabilitar allow_uploaded_avatars" + sso_overrides_profile_background: "Sobrescribe el fondo del perfil del usuario con el avatar del sitio externo desde SSO payload." + sso_overrides_card_background: "Sobrescribe el fondo de la tarjeta de usuario con el avatar de sitio externo desde SSO payload." sso_not_approved_url: "Redireccionar cuentas SSO sin aprobar a esta URL" sso_allows_all_return_paths: "No restringe el dominio para return_paths provisto por SSO (por defecto, el return_paths debe ser sobre el sitio actual)." - enable_local_logins_via_email: "Permitir a los usuarios solicitar un enlace de un solo uso para iniciar sesión rápidamente, que les será enviado por email" + enable_local_logins: "Habilite las cuentas locales de inicio de sesión con nombre de usuario y contraseña. Esto debe estar habilitado para que las invitaciones funcionen. ADVERTENCIA: si está deshabilitado, es posible que no pueda iniciar sesión si no ha configurado previamente al menos un método de inicio de sesión alternativo." + enable_local_logins_via_email: "Permitir a los usuarios que soliciten un enlace de inicio de sesión con un solo clic que se les enviará por correo electrónico." allow_new_registrations: "Permitir el registro de nuevos usuarios. Desactiva esta opción para prevenir que nadie pueda crear una nueva cuenta." enable_signup_cta: "Mostrar un aviso a los usuarios anónimos que vuelvan a visitar el sitio animándoles a registrarse." enable_yahoo_logins: "Activar autenticación por Yahoo" enable_google_oauth2_logins: "Habilita la autenticación con Google Oauth2. Este es el método de autenticación a la que Google da soporte actualmente. Requiere de una clave de cliente y una clave secreta." google_oauth2_client_id: "Client ID de tu aplicación Google." google_oauth2_client_secret: "Client secret de tu aplicación Google." + google_oauth2_prompt: "Una lista delimitada por espacios de valores de cadena que especifica si el servidor de autorizaciones solicita al usuario la reautenticación y el consentimiento. Consulte https://developers.google.com/identity/protocols/OpenIDConnect#prompt para conocer los valores posibles." + google_oauth2_hd: "Dominio hospedado de Google Apps al que se limitará el inicio de sesión. Consulte https://developers.google.com/identity/protocols/OpenIDConnect#hd-param para obtener más detalles." enable_twitter_logins: "Activar autenticación por Twitter, requiere una twitter_consumer_key y un twitter_consumer_secret" + twitter_consumer_key: "Clave del consumidor para la autenticación de Twitter, registrado en https://apps.twitter.com/" + twitter_consumer_secret: "Secreto del consumidor para la autenticación de Twitter, registrado en https://apps.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" @@ -1113,11 +1159,11 @@ es: github_client_id: "Client id para la autenticación por Github, registrado en https://github.com/settings/applications" github_client_secret: "Client secret para la autenticación por Github, registrado en https://github.com/settings/applications" readonly_mode_during_backup: "Habilitar el modo de 'solo-lectura' mientras se hace el backup" - enable_backups: "Permitir a los administradores crear copias de seguridad del foro" + enable_backups: "Permitir a los administradores crear backups del foro" allow_restore: "Permitir restauración, la cual puede sobreescribir TODOS los datos del sitio! Dejela en falso a menos que tenga planeado recuperar sus datos desde una copia de respaldo. " maximum_backups: "La cantidad máxima de copias de seguridad a tener en el disco. Las copias de seguridad más antiguas se eliminan automáticamente" automatic_backups_enabled: "Ejecutar backups automáticos definidos por la opción de frecuencia de backups" - backup_frequency: "Número de días entre copias de seguridad." + backup_frequency: "El número de días entre backups." 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." @@ -1130,6 +1176,7 @@ es: 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)`" rebake_old_posts_count: "Número de publicaciones antiguas objeto de rebake cada 15 minutos." + enable_safe_mode: "Permitir a los usuarios ingresar al modo seguro para depurar plugins." 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." @@ -1139,7 +1186,7 @@ es: max_bookmarks_per_day: "Máximo número de marcadores por usuario y día." max_edits_per_day: "Máximo número de ediciones por usuario y día." max_topics_per_day: "Máximo número de temas que un usuario puede crear al día." - max_personal_messages_per_day: "Máximo número de mensajes personales que los usuarios pueden crear por día." + max_personal_messages_per_day: "Número máximo de mensajes que los usuarios pueden crear por 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." max_logins_per_ip_per_hour: "Máximo número de inicios de sesión permitidos por direcciones IP por hora." @@ -1155,6 +1202,7 @@ es: purge_deleted_uploads_grace_period_days: "Período de gracia (en días) antes de que una subida eliminada sea borrada totalmente." purge_unactivated_users_grace_period_days: "Periodo de gracia (en días) antes de que un usuario que no ha activado su cuenta sea borrado. Configurar a 0 para que nunca se purgue a usuarios no activados." enable_s3_uploads: "Coloca los archivos subidos en el almacén Amazon S3. IMPORTANTE: requiere de credenciales de S3 validas. (ambas clave de acceso y clave de acceso secreta)." + s3_use_iam_profile: 'Utilice un perfil de instancia de AWS EC2 para otorgar acceso al S3 bucket. NOTA: habilitar esto requiere que Discourse se ejecute en una instancia EC2 configurada apropiadamente, y anula las configuraciones de "clave de acceso s3" y "clave secreta s3".' s3_upload_bucket: "El nombre del bucket Amazon S3 donde se subirán los archivos. AVISO: debe ser en minúsculas, sin puntos ni guiones bajos." s3_access_key_id: "La clave id de acceso de Amazon S3 que se utilizará para subir imágenes." s3_secret_access_key: "La clave secreta de acceso de Amazon S3 que se utilizará para subir imágenes." @@ -1196,16 +1244,17 @@ es: 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." - trusted_users_can_edit_others: "Permitir a usuarios con niveles de confianza altos editar contenido de otros usuarios" + trusted_users_can_edit_others: "Permitir usuarios con alto nivel de confianza editar contenido de otros usuarios" min_trust_to_create_topic: "El mínimo nivel de confianza requerido para crear un nuevo tema." - allow_flagging_staff: "Si se activa, los usuarios pueden reportar mensajes publicados por miembros del staff" + allow_flagging_staff: "Si está habilitado, los usuarios pueden reportar las publicaciones de las cuentas del staff." min_trust_to_edit_wiki_post: "El mínimo nivel de confianza requerido para editar un post marcado como wiki." min_trust_to_edit_post: "El mínimo nivel de confianza requerido para editar posts." 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: "El nivel de confianza mínimo necesario para crear nuevos mensajes personales." - min_trust_to_flag_posts: "El nivel de confianza mínimo necesario para reportar posts" - min_trust_to_post_links: "El nivel de confianza mínimo necesario para incluir enlace en posts" - min_trust_to_post_images: "El nivel de confianza mínimo necesario para incluir imágenes en un post" + min_trust_to_send_messages: "El mínimo nivel de confianza requerido para crear nuevos mensajes personales." + min_trust_to_send_email_messages: "El nivel de confianza mínimo necesario para enviar nuevos mensajes privados por correo electrónico (a los usuarios staged)." + min_trust_to_flag_posts: "El mínimo nivel de confianza requerido para reportar posts" + min_trust_to_post_links: "El mínimo nivel de confianza requerido para incluir enlaces en posts" + min_trust_to_post_images: "El nivel mínimo de confianza requerido para incluir imágenes en una publicación" 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." @@ -1213,10 +1262,10 @@ es: 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 las notificaciones)" - enable_mentions: "Permitir a los usuarios mencionar a otros usuarios." + enable_mentions: "Permitir a usuarios mencionar a otros usuarios." 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." - personal_email_time_window_seconds: "Esperar (n) segundos antes de enviar notificaciones de nuevos mensajes personales por email para dar la oportunidad de editar y terminar sus mensajes a los usuarios." + personal_email_time_window_seconds: "Espera (n) segundos antes de enviar cualquier mensaje email personal 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." @@ -1232,7 +1281,7 @@ es: max_image_size_kb: "El tamaño máximo, en kB, para subir imágenes. Debe ser configurado también en nginx (client_max_body_size) / apache o proxy." max_attachment_size_kb: "El tamaño máximo, en kB, para adjuntar archivos. Debe ser configurado también en nginx (client_max_body_size) / apache o proxy." authorized_extensions: "Una lista de las extensiones de archivo permitidas para subir (usa \"*\" para habilitar todos los tipos de archivo)" - authorized_extensions_for_staff: "Una lista de extensiones de archivo que el staff puede subir además de la lista definida en el ajuste `authorized_extensions` (usar '*' para permitir todos los tipos de archivo)" + authorized_extensions_for_staff: "Una lista de las extensiones de archivo permitidas para subir por miembros del staff en adición a la lista definida en la configuración `authorized_extensions`. (Usa '*' para habilitar todos los tipos)" theme_authorized_extensions: "Una lista de las extensiones de archivo permitidas para subir (usa \"*\" para habilitar todos los tipos)" max_similar_results: "Cuántos temas similares se mostrarán encima del editor cuando estés creando un nuevo tema. La comparación se basa en el título y el cuerpo del tema." max_image_megapixels: "Máximo de megapíxeles permitidos por una imagen." @@ -1252,6 +1301,7 @@ es: faq_url: "Si tienes un documento de Preguntas Frecuentes alojado que quieras utilizar, introduce la URL completa aquí." tos_url: "Si tienes un documento de Condiciones de Servicio alojado en algún sitio quieras utilizar, facilita la URL aquí." privacy_policy_url: "Si tienes un documento de Preguntas Frecuentes alojado en algún sitio quieras utilizar, facilita la URL aquí." + log_anonymizer_details: "Si mantienes los detalles de un usuario en el log después de ser anonimizados. Al cumplir con GDPR, deberá apagarlo." newuser_spam_host_threshold: "¿Cuántas veces un nuevo usuario puede publicar un enlace al mismo host en `newuser_spam_host_threshold` posts antes de ser considerado spam." 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." @@ -1271,11 +1321,12 @@ es: auto_silence_fast_typers_max_trust_level: "Máximo nivel de confianza por debajo del cual se podrán silenciar usuarios que escriban demasiado rápido en su primer post" auto_silence_first_post_regex: "Expresión regular que no distingue mayúsculas y minúsculas que si es detectada hará que el primer post de un usuario sea silenciado y enviado a la cola de aprobación. Ejemplo: raging|a[bc]a hará que todos los posts que contengan gaging, aba o aca sean silenciados. Sólo tiene efecto en el primer mensaje de un usuario." flags_default_topics: "Mostrar temas reportados por defecto en la sección de administración" + min_flags_staff_visibility: "La cantidad mínima de reportes que una publicación debe tener antes de que el staff pueda verla en la sección de administración" reply_by_email_enabled: "Habilitar la respuesta a temas por email." reply_by_email_address: "Plantilla para la dirección de email que aparecerá al recibir correos con la función de respuesta por email: %{reply_key}@respuesta.ejemplo.com o respuestas+%{reply_key}@ejemplo.com" alternative_reply_by_email_addresses: "Lista de plantillas alternativa para las direcciones de respuesta por email. Ejemplo: %{reply_key}@reply.example.com|replies+%{reply_key}@example.com" - incoming_email_prefer_html: "Usar HTML en vez de texto para email entrante" - disable_emails: "Impedir que Discourse envíe cualquier tipo de emails" + incoming_email_prefer_html: "Usar el HTML en vez del texto para email entrante." + 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" @@ -1318,7 +1369,7 @@ es: relative_date_duration: "Número de días desde el último post antes de los cuales las fechas se mostrarán en formato relativo (7d) en vez de absoluto (20 Feb)." delete_user_max_post_age: "No permitir eliminar usuarios cuyo primer post tenga una antigüedad de (x) días." delete_all_posts_max: "El máximo número de posts que pueden ser eliminados a la vez con el botón \"Eliminar todos los posts\". Si un usuario tiene un mayor número de posts que este valor, éstos no podrán ser eliminados de una vez y el usuario no podrá ser eliminado." - username_change_period: "Número máximo de días después del registro en los que las cuentas pueden cambiar su nombre de usuario (0 para desactivar los cambios de usuario)." + username_change_period: "El número máximo de días después de registrarse entre los cuales una cuenta puede cambiar su nombre de usuario (0 para deshabilitar el cambio de nombre)" email_editable: "Permitir a los usuarios cambiar su dirección de email después de registrarse." logout_redirect: "Destino hacia donde redirigir el navegador después de cerrar sesión (ej: http://sitio.com/salida)" allow_uploaded_avatars: "Permitir a los usuarios subir imágenes de perfil personalizadas." @@ -1342,13 +1393,14 @@ es: staff_user_custom_fields: "Una lista con campos personalizados para el usuario que pueden ser mostrados a los moderadores o admin." enable_user_directory: "Proporcionar un directorio de usuarios" enable_group_directory: "Activa un directorio de grupos para explorar" + group_in_subject: "Configura %{optional_pm} en el título del email para nombrar el primer grupo en MP, ver: https://meta.discourse.org/t/customize-subject-format-for-standard-emails/20801" 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." - show_inactive_accounts: "Permitir a los usuarios con sesión iniciada ver perfiles de cuentas inactivas." + show_inactive_accounts: "Permitir a usuarios logueados visualizar perfiles de cuentas inactivas." hide_suspension_reasons: "No mostrar la razón de suspensión públicamente en el perfil de usuario." - log_personal_messages_views: "Registrar en el log cuando los Administradores vean mensajes personales de otros usuarios/grupos." + log_personal_messages_views: "Log de mensajes personales vistos por Admin para otros usuarios/grupos." user_website_domains_whitelist: "El sitio web del usuario será automáticamente verificado con estos dominios. Lista delimitada por barras |" allow_profile_backgrounds: "Permitir a los usuarios subir sus propios fondos de perfil personalizados." sequential_replies_threshold: "Número de mensajes que un usuario tiene que publicar seguidos antes de que se le recuerde sobre demasiadas respuestas consecutivas." @@ -1377,21 +1429,25 @@ es: 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: "Reglas de resaltado de sintaxis incluidas. (Aviso: incluir demasiados lenguajes puede afectar al rendimiento) mira: https://highlightjs.org/static/demo/ para ver una demo" embed_truncate: "Truncar los posts embebidos." + embed_support_markdown: "Soporte de formato Markdown para publicaciones incrustadas." allowed_href_schemes: "Esquemas permitidos en enlaces además de http y https." 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." + notify_about_flags_after: "Si hay reportes que no han sido revisados después de este número de horas, enviar un mensaje personal a los moderadores. Poner 0 para inhabilitar." 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. bootstrap_mode_min_users: "Mínimo número de usuarios requerido para desactivar el modo bootstrap (pon 0 para desactivar esta opción)" 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" - enable_emoji_shortcuts: "Los emoticonos comunes como :) :p :( serán convertidos automáticamente a emojis" + enable_emoji_shortcuts: "Texto común de emoticones como :) :p :( serán convertidos a emojis" 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 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" approve_new_topics_unless_trust_level: "Los nuevos temas de usuarios por debajo de este nivel de confianza deben ser aprobados" + approve_unless_staged: "Nuevos temas y mensajes de usuarios temporales deben ser aprovados" + notify_about_queued_posts_after: "Si hay publicaciones que han estado esperando para ser revisadas por más de este número de horas, enviar una notificación a todos los moderadores. Pon 0 para desactivar estas notificaciones." auto_close_messages_post_count: "Máximo número de publicaciones permitidas en un mensaje antes de que sea cerrado automáticamente (0 para desactivar)" auto_close_topics_post_count: "Máximo número de publicaciones permitidas en un tema antes de que sea cerrado automáticamente (0 para desactivar)" code_formatting_style: "El botón de código en el editor se establecerá por defecto a este estilo de formato de código" @@ -1399,6 +1455,7 @@ es: watched_words_regular_expressions: "Palabras observadas son expresiones regulares." default_email_digest_frequency: "Cuán a menudo recibirán los usuarios emails de resumen por defecto." default_include_tl0_in_digests: "Incluir temas de usuarios nuevos en los emails de resumen por defecto. Los usuarios pueden cambiar esto en sus preferencias." + default_email_personal_messages: "Enviar un correo electrónico cuando alguien envíe un mensaje al usuario de manera predeterminada." 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." default_email_mailing_list_mode_frequency: "Los usuarios que activen el modo lista de correo recibirán correos con esta frecuencia por defecto." @@ -1434,13 +1491,18 @@ es: show_filter_by_tag: "Mostrar un desplegable para filtrar una lista de temas por etiqueta." max_tags_in_filter_list: "Máximo número de etiquetas en el desplegable. Se mostrarán primero aquellas más utilizadas." tags_sort_alphabetically: "Mostrar etiquetas en orden alfabético. Por defecto se mostrarán por popularidad." + tags_listed_by_group: "Listar etiquetas por grupo de etiquetas en la página Etiquetas (/tags)." tag_style: "Estilo visual de las etiquetas." + allow_staff_to_tag_pms: "Permitir a los miembros del staff etiquetar cualquier mensaje personal" min_trust_level_to_tag_topics: "Nivel mínimo requerido para etiquetar temas" suppress_overlapping_tags_in_list: "Si alguna etiqueta coinciden con palabras en el título de los temas, ocultarla." remove_muted_tags_from_latest: "No mostrar temas con etiquetas silenciadas en la lista de temas recientes." company_short_name: "Nombre de la empresa (corto)" company_full_name: "Nombre de la empresa (largo)" company_domain: "Dominio de la empresa" + shared_drafts_category: "Habilite la característica de Borradores Compartidos designando una categoría para borradores de temas." + push_notifications_prompt: "Mostrar aviso del consentimiento del usuario." + push_notifications_icon_url: "El icono del distintivo que aparece en la esquina de notificaciones. El tamaño recomendado es 96px por 96px." errors: invalid_email: "Dirección de correo electrónico inválida. " invalid_username: "No existe ningún usuario con ese nombre de usuario. " @@ -1468,7 +1530,8 @@ es: enable_sso_disabled: "Debes activar primero 'enable sso' antes de activar esta opción." staged_users_disabled: "Primero debes habilitar 'staged users' antes, para habilitar esta configuración." reply_by_email_disabled: "Primero debes habilitar 'reply by email' antes de habilitar esta configuración." - sso_url_is_empty: "Debes establecer un valor en 'sso url' antes de activar este ajuste." + sso_url_is_empty: "Debe establecer una 'sso url' antes de habilitar esta configuración." + enable_local_logins_disabled: "Primero debes habilitar 'enable local logins'  antes de habilitar esta configuración." search: within_post: "#%{post_number} por %{username}" types: @@ -1489,8 +1552,8 @@ es: most_recent_poster: "Autor más reciente" frequent_poster: "Autor frecuente" redirected_to_top_reasons: - new_user: "¡Bienvenido a nuestra comunidad! Estos son los temas recientes más populares." - not_seen_in_a_month: "¡Bienvenido de vuelta! No te habíamos visto en un tiempo. Estos son los temas más populares desde estuviste por aquí." + new_user: "¡Bienvenido a nuestra comunidad! Estos son los temas recientes mas populares." + not_seen_in_a_month: "¡Bienvenido de vuelta! No te habíamos visto en un tiempo. Estos son los temas mas populares desde que no has estado." merge_posts: edit_reason: one: Un tema fue juntado por %{username} @@ -1567,7 +1630,7 @@ es: login: not_approved: "Tu cuenta aún no ha sido aprobada. Se te notificará por email cuando todo esté listo para iniciar sesión." incorrect_username_email_or_password: "Nombre de usuario, dirección de correo o contraseña incorrectos" - incorrect_password: "Contraseña incorrecta" + incorrect_password: "Password incorrecto" wait_approval: "Gracias por registrarte. Te notificaremos cuando tu cuenta haya sido aprobada." active: "Tu cuenta está activa y lista para usar." activate_email: "

    ¡Ya casi has terminado! Te enviamos un correo de activación a %{email}. Por favor sigue las instrucciones de ese correo para activar tu cuenta.

    Si no llega, mira en la carpeta de spam.

    " @@ -1590,11 +1653,11 @@ es: auth_complete: "Autenticación completa." click_to_continue: "Clic aquí 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." - second_factor_title: "Autentificación de dos factores" - second_factor_description: "Por favor, introduce el código de autentificación obtenido en tu aplicación:" - invalid_second_factor_code: "Código de autentificación no válido" + second_factor_title: "Autenticación Dos Factores" + second_factor_description: "Por favor ingrese el código de autenticación desde tu aplicación:" + invalid_second_factor_code: "Código de Autenticación inválido" user: - no_accounts_associated: "No hay cuentas asociadas" + no_accounts_associated: "No hay cuentas relacionadas." deactivated: "Ha sido desactivado a causa de muchos rebotes al email '%{email}'." deactivated_by_staff: "Desactivado por el staff" activated_by_staff: "Activado por el staff" @@ -1741,6 +1804,47 @@ es: test_mailer: title: "Mail de prueba" subject_template: "[%{email_prefix}] 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 configurar la dirección correctamente en los ajustes de tu sitio de `notification email`. **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. + + - Recomendamos **enviar un email de prueba a [mail-tester.com][mt]** para verificar que todo está funcionando correctamente. + + (La forma *fácil* es crear una cuenta gratuita en [Sendgrip][sg], [SparkPost][sp], [Mailgun][mg] o [Mailjet][mj], que proveen generosamente planes de mailing gratuitos 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]: https://www.mail-tester.com/spf-dkim-check + [8]: http://www.openspf.org/SPF_Record_Syntax + [sg]: https://goo.gl/r1WMF6 + [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: title: "Email de Nueva versión" subject_template: "[%{email_prefix}] Nueva versión de Discourse, actualización disponible" @@ -1797,32 +1901,32 @@ es: text_body_template: | Hola, - Esto es un mensaje automático de %{site_name} para hacerte saber que tu mensaje ha sido ocultado. + Este es un mensaje automático desde %{site_name} para notificarte que tu mensaje ha sido ocultado. <%{base_url}%{url}> %{flag_reason} - Varios miembros de la comunidad han reportado este mensaje antes de que fuera ocultado, por lo que por favor considera cómo podrías editar tu mensaje para reflejar sus comentarios. **Podrás editar tu mensaje en %{edit_delay} minutos, y será automáticamente desocultado**. + Varios miembros de la comunidad han reportado tu mensaje antes de que éste se haya ocultado, así que por favor considera cómo vas a editar tu mensaje. **Puedes editar tu mensaje después de %{edit_delay} minutos, y será automáticamente mostrado de nuevo.** - Sin embargo, si el mensaje es ocultado por la comunidad una segunda vez, se mantendrá oculto hasta que sea revisado por un miembro del staff. + Sin embargo, si el mensaje es ocultado por la comunidad por segunda vez, permanecerá en ese estado hasta que sea revisado por alguien del staff. - Para obtener más información sobre el comportamiento esperado, revisa por favor las [directrices de la comunidad](%{base_url}/guidelines). + Para aprender más, por favor leer nuestra [guía de la comunidad](%{base_url}/guidelines). post_hidden_again: title: "Mensaje ocultado de nuevo" - subject_template: "Mensaje ocultado por reportes de la comunidad, se ha notificado al staff" + subject_template: "Mensaje ocultado debido a reportes de la comunidad, staff notificado" text_body_template: | Hola, - Esto es un mensaje automático de %{site_name} para hacerte saber que tu mensaje ha vuelto a ser ocultado de nuevo. + Este es un mensaje automático desde %{site_name} para notificarte que tu mensaje ha sido ocultado nuevamente. <%{base_url}%{url}> %{flag_reason} - Varios miembros de la comunidad han reportado este mensaje antes de que se ocultara. **Debido a que este mensaje ha sido ocultado anteriormente, se mantendrá oculto hasta que sea revisado por un miembro del staff.** + Varios miembros de la comunidad han reportado tu mensaje antes de que éste se haya ocultado. **Porque este post ha sido ocultado más de una vez, permanecerá oculto hasta que personal del staff lo revise.** - Para más información, lee las [directrices de la comunidad](%{base_url}/guidelines). + Para aprender más, por favor leer nuestra [guía de la comunidad](%{base_url}/guidelines). usage_tips: text_body_template: | Si quieres unos consejos para empezar, [echa un vistazo a esta entrada de blog](https://blog.discourse.org/2016/12/discourse-new-user-tips-and-tricks/). @@ -1840,7 +1944,7 @@ es: ¡Disfruta de tu estancia! welcome_invite: - title: "Bienvenido, Invitado" + title: "Bienvenido Invitado" subject_template: "¡Bienvenido a %{site_name}!" text_body_template: | Gracias por aceptar tu invitación a %{site_name} -- ¡Te damos la bienvenida! @@ -1860,7 +1964,7 @@ es: [prefs]: %{user_preferences_url} backup_succeeded: title: "Copia de seguridad completada con éxito" - subject_template: "La copia de seguridad se ha completado con éxito" + subject_template: "La copia de seguridad se completo exitosamente" text_body_template: |+ Copia de seguridad realizada con éxito. @@ -1874,7 +1978,7 @@ es: backup_failed: title: "Error en la copia de seguridad" - subject_template: "La copia de seguridad ha fallado" + subject_template: "La copia de seguridad falló" text_body_template: | La copia de seguridad ha fallado. @@ -1885,7 +1989,7 @@ es: ``` restore_succeeded: title: "Restauración completada con éxito" - subject_template: "Restauración completada con éxito" + subject_template: "Restauración completada exitosamente." text_body_template: | La restauración se ha completado con éxito. @@ -1896,7 +2000,7 @@ es: ``` restore_failed: title: "Error en la restauración" - subject_template: "La restauración ha fallado." + subject_template: "La restauración falló." text_body_template: | La restauración ha fallado. @@ -1922,6 +2026,7 @@ es: ``` csv_export_succeeded: title: "Exportación de datos en CSV completada con éxito" + subject_template: "[%{export_title}] exportación de datos completa" text_body_template: | ¡Se han exportado tus datos correctamente! :dvd: @@ -2059,6 +2164,13 @@ es: Lo sentimos, pero tu email para %{destination} (titulado %{former_title}) no funcionó. Ninguna de las direcciones de emails ha sido reconocida, o el Message-ID de la cabecera en el email ha sido modificado. Por favor asegúrate de que estás enviando los correos a las direcciones correctas provistas por el staff. + email_reject_old_destination: + title: "Correo electrónico rechazo antiguo destino" + subject_template: "[%{email_prefix}] Problema con el correo -- Estás intentando responder a una notificación antigua" + text_body_template: | + Lo sentimos, pero tu mensaje de correo a %{destination} (titulado %{former_title}) no ha funcionado. + + Por razones de seguridad nosotros solo aceptamos respuestas a notificaciones originales para 90 días. Por favor [visita el tema](%{short_url}) para continuar esta conversación. email_reject_topic_not_found: title: "Email rechazado, tema no encontrado" subject_template: "[%{email_prefix}] Problema con el correo -- Tema no encontrado" @@ -2105,7 +2217,7 @@ es: Esto es un mensaje automático de %{site_name} para hacerte saber que tus mensajes han sido ocultados temporalmente porque han sido reportados muchas veces por la comunidad. - Como medida cautelar, tu cuenta nueva ha sido silenciada y no puede crear nuevas respuestas o debates hasta que un miembro del staff la revise. Sentimos las molestias ocasionadas. + Como medida cautelar, tu cuenta nueva ha sido silenciada de crear nuevas respuestas o debates hasta que un miembro del staff la revise tu cuenta. Sentimos las molestias ocasionadas. Para más información sobre lo que consideramos adecuado, lee las [directrices de la comunidad](%{base_url}/guidelines). too_many_tl3_flags: @@ -2114,13 +2226,13 @@ es: text_body_template: | Hola, - Este es un mensaje automático de %{site_name} para hacerte saber que tu cuenta ha sido retenida porque ha sido reportada muchas veces por la comunidad. + Esto es un mensaje automático de %{site_name} para hacerte saber que tu cuenta ha sido retenida porque ha sido reportada muchas veces por la comunidad. - Como medida cautelar, tu cuenta nueva ha sido silenciada y no puede crear nuevas respuestas o debates hasta que un miembro del staff la revise. Sentimos las molestias ocasionadas. + Como medida cautelar, tu cuenta nueva ha sido silenciada de crear nuevas respuestas o debates hasta que un miembro del staff la revise tu cuenta. Sentimos las molestias ocasionadas. Para más información, por favor lee las [directrices de la comunidad](%{base_url}/guidelines). silenced_by_staff: - title: "Silenciado por el Staff" + title: "Silenciado por Staff" subject_template: "Cuenta temporalmente retenida" text_body_template: | Hola, @@ -2142,23 +2254,23 @@ es: Esto puede ser cambiado con el ajuste `silence_new_user` en configuración del sitio. spam_post_blocked: - title: "Post spam bloqueado" - subject_template: "Bloqueado nuevo usuario %{username} debido a enlaces repetidos" + title: "Post con Spam Bloqueado" + subject_template: "Nuevo usuario %{username} posts bloqueados debido a repetición de enlaces." text_body_template: | Este es un mensaje automático. - El nuevo usuario [%{username}](%{user_url}) ha intentado crear múltiples posts con enlaces a %{domains}, pero han sido bloqueados para evitar spam. El usuario podrá seguir creando nuevos posts si no enlazan a %{domains}. + 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, [revisa el usuario](%{user_url}). + Por favor, [echa un vistazo al usuario](%{user_url}). - Esto puede ser modificado a través de los ajustes `newuser_spam_host_threshold` y `newuser_spam_host_threshold`. + Esto puede ser modificado con los ajustes `newuser_spam_host_threshold` y `white_listed_spam_host_domains`. unsilenced: title: "Dejar de silenciar" - subject_template: "Tu cuenta ya no está retenida" + subject_template: "Cuenta no retenida" text_body_template: | Hola, - Este es un mensaje automático de %{site_name} para informarte que tu cuenta ya no se encuentra retenida y ha sido revisada por miembros del staff. + Este es un mensaje automático desde %{site_name} para informarte que tu cuenta no se encuentra retenida debido a la revisión de miembros del staff. Ahora puedes crear temas, y responder a otros usuarios. Gracias por tu paciencia. pending_users_reminder: @@ -2185,7 +2297,7 @@ es: title: "¡Eres el Nuevo Usuario del Mes!" subject_template: "¡Eres el Nuevo Usuario del Mes!" text_body_template: | - ¡Felicitaciones, has ganado el **premio Nuevo Usuario del Mes para %{month_year}**. :trophy:! + ¡Felicitaciones, has ganado el **premio Nuevo Usuario del Mes para %{month_year}**. :trophy: ! Este premio solo lo ganan dos de los nuevos miembros por mes, y será visible permanentemente en [la página de distintivos](%{url}). @@ -2224,6 +2336,7 @@ es: visit_link_to_respond: "[Visita el tema](%{base_url}%{url}) para responder." visit_link_to_respond_pm: "[Visita el mensaje](%{base_url}%{url}) para responder." posted_by: "Publicado por %{username} el %{post_date}" + pm_participants: "Participantes:" invited_group_to_private_message_body: | %{username} te invitó en @%{group_name} al mensaje @@ -2344,6 +2457,17 @@ es: %{context} + %{respond_instructions} + user_mentioned_pm: + title: "Usuario Mencionado MP" + subject_template: "[%{email_prefix}] [MP] %{topic_title}" + text_body_template: | + %{header_instructions} + + %{message} + + %{context} + %{respond_instructions} user_group_mentioned: title: "Grupo del usuario mencionado" @@ -2425,14 +2549,14 @@ es: Si tienes alguna pregunta, [contactar a nuestro amigable staff](%{base_url}/about). account_second_factor_disabled: - title: "Autentificación de dos factores desactivada" - subject_template: "[%{email_prefix}] Autentificación de dos factores desactivada " + title: "Autenticación de dos factores inhabilitada" + subject_template: "[%{email_prefix}] Autenticación de dos factores inhabilitada" text_body_template: | - La autentificación de dos factores ha sido desactivada en tu cuenta de %{site_name}. Ahora puedes iniciar sesión solo con tu contraseña. No hace falta que nos facilites el código adicional al iniciar sesión. + La autenticación de dos factores de tu cuenta en %{site_name} ha sido inhabilitada. Puedes ingresar únicamente con tu contraseña; no será necesario que ingreses con el código de autenticación adicional. - Si no has elegido desactivar la autentificación de dos factores, alguien podría tener acceso no autorizado a tu cuenta. + Si no seleccionaste inhabilitar la autenticación de dos factores, alguien puede haber comprometido tu cuenta. - Si tienes alguna pregunta, [ponte en contacto con nuestro staff](%{base_url}/about). + Si tienes alguna pregunta. [contacta nuestro amigable staff](%{base_url}/about). digest: why: "Un breve resumen de %{site_link} desde tu última visita el %{last_seen_at}" since_last_visit: "Desde tu última visita" @@ -2464,14 +2588,14 @@ es: Haz clic en el siguiente enlace para cambiar tu contraseña: %{base_url}/u/password-reset/%{email_token} email_login: - title: "Iniciar sesión con enlace" - subject_template: "[%{email_prefix}] Iniciar sesión con enlace" + title: "Ingreso vía enlace" + subject_template: "[%{email_prefix}] Ingreso vía enlace" text_body_template: | - Aquí tienes tu enlace para iniciar sesión en [%{site_name}](%{base_url}). + Aquí tienes tu enlace para ingresar a [%{site_name}](%{base_url}). - Si no has solicitado este enlace, puedes ignorar sin problema este email. + Si no has solicitado este enlace, puedes simplemente ignorar este correo electrónico. - Haz clic en el siguiente enlace para iniciar sesión: + Clic en el siguiente enlace para ingresar: %{base_url}/session/email-login/%{email_token} set_password: title: "Pon una contraseña" @@ -2530,20 +2654,20 @@ es: title: "Entra después de ser aprobado" subject_template: "¡Tu solicitud ha sido aprobada en %{site_name}!" text_body_template: | - ¡Te damos la bienvenida a %{site_name}! + ¡Bienvenido a %{site_name}! - Un miembro del staff ha aprobado tu cuenta de %{site_name}. + Un miembro del staff aprobó tu cuenta en %{site_name}. - Ahora puedes acceder a ella iniciando sesión en: + Puedes ahora acceder a tu nueva cuenta ingresando en: %{base_url} - Si el enlace de arriba no funciona, prueba a copiarlo y pegarlo en la barra de direcciones de tu navegador web. + Si no puedes hacer clic en el enlace, intenta copiándolo y pegándolo en la barra de direcciones de tu navegador. %{new_user_tips} - Creemos en un [comportamiento civilizado de la comunidad](%{base_url}/guidelines) en todo momento. + Creemos en una comunidad con un [comportamiento civilizado](%{base_url}/guidelines). - ¡Disfruta de tu estancia! + ¡Disfruta tu estadía! signup: title: "Registrate" subject_template: "[%{email_prefix}] Confirma tu nueva cuenta" @@ -2562,8 +2686,8 @@ es: search_title: "Busca en este sitio" search_google: "Google" offline: - title: "No se ha podido cargar" - offline_page_message: "¡Parece que no tienes conexión! Por favor, revisa tu conexión a internet e inténtalo de nuevo." + title: "No carga app" + offline_page_message: "¡Parece que estás offline! Por favor revisa tu conexión a internet e intenta de nuevo." login_required: welcome_message: | ## [Bienvenido a %{title}](#welcome) @@ -2580,7 +2704,7 @@ es: store_failure: "Falló el almacenamiento de la subida #%{upload_id} para el usuario #%{user_id}." file_missing: "Lo sentimos, debes incluir un archivo a subir." empty: "Disculpa, pero el archivo que proporcionaste está vacío." - png_to_jpg_conversion_failure_message: "Ha ocurrido un error al convertir de PNG a JPG." + png_to_jpg_conversion_failure_message: "Ha ocurrido un error cuando se convertía desde PNG a JPG." attachments: too_large: "Lo sentimos, el archivo que estás intentando subir es demasiado grande (el tamaño máximo es %{max_size_kb}%KB)." images: @@ -2731,9 +2855,144 @@ es: 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 del servicio" + title: "Términos de Servicio" + body: | + Los siguientes términos y condiciones rigen el uso del sitio web %{company_domain} y todo el contenido, servicios y productos disponibles a través del sitio web, incluidos, entre otros, el software del foro %{company_domain}, el foro de soporte de %{company_domain} y el servicio de alojamiento de alojamiento ("Hosting") si existiese, (en conjunto, el sitio web). El sitio web pertenece y es operado por %{company_full_name} ("%{company_name}"). El sitio web se ofrece sujeto a su aceptación sin modificación de todos los términos y condiciones aquí contenidos y todas las demás reglas operativas y políticas (incluyendo, sin limitación, las [Política de privacidad](/privacy) y las [Guías de la Comunidad](/faq) de %{company_domain}) y los procedimientos que pueden publicarse de vez en cuando en este Sitio por %{company_name} (colectivamente, el "Acuerdo"). + + Lea este Acuerdo detenidamente antes de acceder o utilizar el sitio web. Al acceder o usar cualquier parte del sitio web, usted acepta quedar sujeto a los términos y condiciones de este acuerdo. Si no acepta todos los términos y condiciones de este acuerdo, entonces no podrá acceder al sitio web ni utilizar ningún servicio. Si estos términos y condiciones se consideran una oferta de %{company_name}, la aceptación está expresamente limitada a estos términos. El sitio web está disponible solo para personas que tienen al menos 13 años de edad. + + + + ## [1. Tu cuenta en %{company_domain}](#1) + + Si crea una cuenta en el sitio web, usted es responsable de mantener la seguridad de su cuenta y usted es totalmente responsable de todas las actividades que ocurran en la cuenta. Debe notificar de inmediato a %{company_name} cualquier uso no autorizado de su cuenta o cualquier otra violación de seguridad. %{company_name} no será responsable de ningún acto u omisión por su parte, incluidos los daños y perjuicios de cualquier tipo incurridos como resultado de dichos actos u omisiones. + + + ## [2. Responsabilidad de los Colaboradores](#2) + + Si publica material en el sitio web, ya sea publica enlaces en el sitio web o crea (o permite que un tercero lo haga) material disponible por medio del sitio web (cualquier material se considera "Contenido"), usted es completamente responsable del contenido y cualquier daño resultante de ese contenido. Este caso independientemente de si el Contenido en cuestión constituye texto, gráficos, un archivo de audio o software de computadora. Al hacer que el Contenido esté disponible, usted declara y garantiza que: + + * la descarga, copia y uso del Contenido no infringirá los derechos de propiedad, incluidos, entre otros, los derechos de autor, patente, marca comercial o secreto comercial de terceros; + * si su empleador tiene derechos de propiedad intelectual que usted crea, usted (i) ha recibido permiso de su empleador para publicar o poner a disposición el Contenido, incluido, entre otros, cualquier software, o (ii) ha obtenido una exención de su empleador como a todos los derechos en o al Contenido; + * usted ha cumplido completamente con las licencias de terceros relacionadas con el Contenido, y ha hecho todo lo necesario para transmitir con éxito a los usuarios finales los términos requeridos; + * el contenido no contiene ni instala virus, gusanos, malware, caballos de Troya u otro contenido dañino o destructivo; + * el contenido no es correo no deseado, no se genera de forma automática o aleatoria, y no contiene contenido comercial no ético o no deseado diseñado para dirigir el tráfico a sitios de terceros o aumentar la clasificación de motores de búsqueda de sitios de terceros o actos ilegales (como phishing) o engañar a los destinatarios sobre el origen del material (como spoofing); + * el Contenido no es pornográfico, no contiene amenazas ni incita a la violencia, y no viola los derechos de privacidad o publicidad de ningún tercero; + * su contenido no se anuncia a través de mensajes electrónicos no deseados, como enlaces de spam en grupos de noticias, listas de correo electrónico, blogs y sitios web, y métodos de promoción no solicitados similares; + * su contenido no se nombra de una manera que induzca a error a sus lectores a pensar que usted es otra persona o empresa; y + * usted tiene, en el caso de Contenido que incluye código de computadora, categorizado y/o descrito con precisión el tipo, naturaleza, usos y efectos de los materiales, ya sea que lo solicite %{company_name} o de otra manera. + + + + ## [3. Licencia de Contenido de Usuario](#3) + + Las contribuciones de los usuarios están autorizadas bajo una [Reconocimiento-NoComercial-CompartirIgual 3.0 Unported (CC BY-NC-SA 3.0)](https://creativecommons.org/licenses/by-nc-sa/3.0/deed.es_ES). Sin limitar ninguna de esas representaciones o garantías, %{company_name} tiene el derecho (aunque no la obligación) de, en el exclusivo criterio de %{company_name} (i) rechazar o eliminar cualquier contenido que en opinión razonable de %{company_name}, viola cualquier política de %{company_name} o es de alguna manera dañina u objetable, o (ii) cancela o niega el acceso y uso del sitio web a cualquier individuo o entidad por cualquier motivo, en la única propiedad de %{company_name} discreción. %{company_name} no tendrá obligación de proporcionar un reembolso de los montos pagados previamente. + + + + ## [4. Pago y Renovación](#4) + + ### Términos Generales + + Servicios pagos opcionales o actualizaciones pueden estar disponibles en el sitio web. Al utilizar un servicio o actualización pagada opcional, usted acepta pagar a %{company_name} las tarifas de suscripción mensuales o anuales indicadas. Los pagos se cobrarán de forma prepaga el día que comience a utilizar el servicio o la actualización, y cubrirá el uso de ese servicio o la actualización por un período de suscripción mensual o anual según lo indicado. Estas tarifas no son reembolsables. + + ### Renovación Automática + + A menos que notifique a %{company_name} antes del final del período de suscripción correspondiente que desea cancelar un servicio o una actualización, su suscripción se renovará automáticamente y usted nos autorizará a cobrar la tarifa de suscripción anual o mensual aplicable en ese momento (así como cualquier impuestos) utilizando cualquier tarjeta de crédito u otro mecanismo de pago que tengamos registrado para usted. Las suscripciones pueden cancelarse en cualquier momento. + + + + ## [5. Servicios](#5) + + ### Hosting, Servicios de Soporte + + Servicios opcionales de Hosting y Soporte pueden ser provistos por %{company_name} bajo los términos y condiciones para cada servicio. Al suscribirse a una cuenta de servicios de Hosting/Soporte o Soporte, acepta cumplir con dichos términos y condiciones. + + ### HTTPS + + Ofrecemos HTTPS como un complemento pago. Al registrarse y utilizar un dominio personalizado en %{company_domain}, nos autoriza a actuar en nombre del registrante del nombre de dominio (al solicitar los certificados necesarios, por ejemplo) con el único propósito de proporcionar HTTPS en su sitio. + + ### Enterprise + + Los servicios de Enterprise Hosting son provistos por %{company_name} bajo los términos y condiciones para cada servicio, que están determinados por un contrato específico del cliente. Al registrarse en una cuenta de Enterprise Hosting, acepta cumplir con dichos términos y condiciones. + + + + ## [6. Responsabilidad de los visitantes del sitio web](#6) + + %{company_name} no ha revisado, y no puede revisar, todo el material, incluido el software informático, publicado en el sitio web, y no puede ser responsable del contenido, uso o efectos de ese material. Al operar el sitio web, %{company_name} no representa ni implica que respalda el material allí publicado, o que considera que dicho material es preciso, útil o no dañino. Usted es responsable de tomar las precauciones necesarias para protegerse a usted mismo y a sus sistemas informáticos contra virus, gusanos, caballos de Troya y otros contenidos dañinos o destructivos. El sitio web puede contener contenido ofensivo, indecente u objetable, así como contenido que contenga inexactitudes técnicas, errores tipográficos y otros errores. El sitio web también puede contener material que viole los derechos de privacidad o publicidad, o que infrinja la propiedad intelectual y otros derechos de propiedad de terceros, o cuya descarga, copia o uso esté sujeto a términos y condiciones adicionales, establecidos o no. %{company_name} se exime de cualquier responsabilidad por cualquier daño que resulte del uso por parte de los visitantes del sitio web, o de cualquier descarga por parte de los visitantes del contenido allí publicado. + + + + ## [7. Contenido publicado en otros sitios web](#7) + + No hemos revisado, y no podemos revisar, todo el material, incluido el software de computadora, disponible a través de los sitios web y páginas web a los cuales %{company_domain} vincula, y ese enlace a %{company_domain}. %{company_name} no tiene ningún control sobre los sitios web y páginas web que no sean del %{company_domain}, y no es responsable de sus contenidos o su uso. Al vincular a un sitio web o página web que no sea de %{company_domain}, %{company_name} no representa ni implica que respalde dicho sitio web o página web. Usted es responsable de tomar las precauciones necesarias para protegerse a usted mismo y a sus sistemas informáticos contra virus, gusanos, caballos de Troya y otros contenidos dañinos o destructivos. %{company_name} no se responsabiliza por ningún daño derivado de su uso de sitios web y páginas web que no sean del %{company_domain}. + + + + ## [8. Infracción de derechos de autor y política de DMCA](#8) + + Como %{company_name} pide a los demás que respeten sus derechos de propiedad intelectual, respeta los derechos de propiedad intelectual de los demás. Si cree que el material ubicado en o vinculado a %{company_domain} infringe sus derechos de autor, y si este sitio web reside en los EE. UU., Le recomendamos que notifique a %{company_name} de acuerdo con %{company_name} [Digital Millennium Copyright Ley](http://en.wikipedia.org/wiki/Digital_Millennium_Copyright_Act) ("DMCA") Política. %{company_name} responderá a todos los avisos, incluidos los necesarios o apropiados, eliminando el material infractor o deshabilitando todos los enlaces al material infractor. %{company_name} dará por terminado el acceso y uso del visitante del sitio web si, bajo circunstancias apropiadas, se determina que el visitante es un infractor recurrente de los derechos de autor u otros derechos de propiedad intelectual de %{company_name} u otros. En el caso de dicha finalización, %{company_name} no tendrá obligación de proporcionar un reembolso de los montos pagados previamente a %{company_name}. + + + + ## [9. Propiedad Intelectual](#9) + + Este Acuerdo no transfiere de %{company_name} ninguna propiedad intelectual de %{company_name} o de terceros, y todos los derechos, títulos e intereses en y para dicha propiedad se mantendrán (entre las partes) únicamente con %{company_name}. %{company_name}, %{company_domain}, el logotipo de %{company_domain} y todas las demás marcas comerciales, marcas de servicio, gráficos y logotipos utilizados en relación con %{company_domain}, o el sitio web son marcas comerciales o marcas comerciales registradas de %{company_name} o los licenciantes de %{company_name}. Otras marcas comerciales, marcas de servicio, gráficos y logotipos utilizados en relación con el sitio web pueden ser marcas comerciales de otros terceros. Su uso del sitio web no le concede ningún derecho o licencia para reproducir o usar cualquier %{company_name} o marcas comerciales de terceros. + + + + ## [10. Atribución](#10) + + %{company_name} se reserva el derecho de mostrar vínculos de atribución como 'Desarrollado por %{company_domain},' autor del tema y atribución de fuentes en su pie de página de contenido. + + + + ## [11. Cambios](#11) + + %{company_name} se reserva el derecho, a su entera discreción, de modificar o reemplazar cualquier parte de este Acuerdo. Es su responsabilidad verificar este Acuerdo periódicamente para ver los cambios. Su uso continuo o acceso al sitio web después de la publicación de cualquier cambio en este Acuerdo constituye la aceptación de dichos cambios. %{company_name} también puede, en el futuro, ofrecer nuevos servicios y/o características a través del sitio web (incluido el lanzamiento de nuevas herramientas y recursos). Tales nuevas características y/o servicios estarán sujetos a los términos y condiciones de este Acuerdo. + + + + ## [12. Terminación](#12) + + %{company_name} puede finalizar su acceso a todo o a cualquier parte del sitio web en cualquier momento, con o sin causa, con o sin aviso, y con efecto inmediato. Si desea rescindir este Acuerdo o su cuenta de %{company_domain} (si tiene una), simplemente puede dejar de usar el sitio web. Todas las disposiciones de este Acuerdo que por su naturaleza deben seguir vigentes después de la terminación seguirán vigentes después de la terminación, incluidas, entre otras, las disposiciones de propiedad, los descargos de garantía, la indemnización y las limitaciones de responsabilidad. + + + + ## [13. Descargo de garantías](#13) + + El sitio web se proporciona "tal cual". %{company_name} y sus proveedores y licenciantes renuncian a todas las garantías de cualquier tipo, expresas o implícitas, incluidas, entre otras, las garantías de comerciabilidad, adecuación para un propósito particular y no infracción. Ni %{company_name} ni sus proveedores y licenciantes hacen ninguna garantía de que el sitio web esté libre de errores o que el acceso al mismo sea continuo o ininterrumpido. Usted entiende que la descarga u obtención de contenido o servicios a través del sitio web, a su propia discreción y riesgo. + + + + ## [14. Limitación de Responsabilidad](#14) + + En ningún caso %{company_name}, ni sus proveedores o licenciantes, serán responsables con respecto a cualquier tema de este acuerdo bajo ningún contrato, negligencia, responsabilidad estricta u otra teoría legal o equitativa para: (i) cualquier especial, incidental o daños generados; (ii) el costo de adquisición de productos o servicios sustitutos; (iii) por interrupción de uso o pérdida o corrupción de datos; o (iv) para cualquier cantidad que exceda las tarifas pagadas por usted a %{company_name} en virtud de este acuerdo durante el período de doce (12) meses anterior a la causa de la acción. %{company_name} no tendrá ninguna responsabilidad por cualquier falla o retraso debido a asuntos fuera de su control razonable. Lo anterior no se aplicará en la medida en que lo prohíba la ley aplicable. + + + + ## [15. Representación general y garantía](#15) + + Usted declara y garantiza que (i) su uso del sitio web será estrictamente de acuerdo con %{company_name} [Política de privacidad](/privacy), [Pautas de la comunidad](/guidelines), con este Acuerdo y con todas las leyes aplicables y normativas (incluidas, entre otras, leyes o normativas locales de su país, estado, ciudad u otra área gubernamental, relacionadas con la conducta en línea y el contenido aceptable, e incluidas todas las leyes aplicables relativas a la transmisión de datos técnicos exportados del país en el que se encuentra este sitio web reside o el país en el que usted reside) y (ii) su uso del sitio web no infringirá o mal apropiará los derechos de propiedad intelectual de ningún tercero. + + + + ## [16. Indemnización](#16) + + Usted acepta indemnizar y mantener indemne a %{company_name}, sus contratistas y sus licenciantes, y sus respectivos directores, funcionarios, empleados y agentes de y contra todos los reclamos y gastos, incluidos los honorarios de abogados, que surjan de su uso de el sitio web, incluyendo pero no limitado a su violación de este Acuerdo. + + + + ## [17. Diversos](#17) + + Este acuerdo constituye el acuerdo completo entre %{company_name} y usted con respecto al tema del presente documento, y solo se puede modificar mediante una enmienda escrita firmada por un ejecutivo autorizado de %{company_name}, o mediante la publicación por parte de %{company_name} de una versión revisada. Excepto en la medida en que la ley aplicable, de existir alguna, establezca lo contrario, este Acuerdo, cualquier acceso o uso del Sitio web se regirá por las leyes del estado de California, EE. UU., excluyendo las disposiciones sobre conflicto de leyes y el lugar adecuado para cualquier disputa que surja de o esté relacionada con cualquiera de los mismos será a los tribunales estatales y federales ubicados en el condado de San Francisco, California. A excepción de las reclamaciones por orden judicial o equitativo o reclamaciones relativas a los derechos de propiedad intelectual (que pueden ser llevados ante los tribunales competentes sin la fijación de un enlace), cualquier disputa que surja de este Acuerdo será resuelta de acuerdo con las Reglas completas de Arbitraje de la Judicial Arbitration and Mediation Service, Inc. ("JAMS") por tres árbitros designados de acuerdo con dichas Reglas. El arbitraje se llevará a cabo en San Francisco, California, en idioma inglés y la decisión de arbitraje se puede hacer cumplir en cualquier tribunal. La parte que prevalezca en cualquier acción o procedimiento para hacer cumplir este Acuerdo tendrá derecho a los costos y honorarios de abogados. Si alguna parte de este Acuerdo se considera inválida o no exigible, se interpretará que esa parte refleja la intención original de las partes, y las partes restantes permanecerán en pleno vigor y efecto. Una renuncia por cualquiera de las partes de cualquier término o condición de este Acuerdo o cualquier incumplimiento del mismo, en cualquier instancia, no renunciará a dicho término o condición o cualquier incumplimiento posterior de los mismos. Puede ceder sus derechos bajo este Acuerdo a cualquier parte que consienta y acuerde estar sujeto a sus términos y condiciones; %{company_name} puede asignar sus derechos bajo este Acuerdo sin condición. Este Acuerdo será vinculante y redundará en beneficio de las partes, sus sucesores y cesionarios permitidos. + + Este documento es CC-BY-SA. Se actualizó por última vez el 1 de enero de 2017. + + Originalmente adaptado de los [Términos del servicio de WordPress](http://en.wordpress.com/tos/) en inglés. privacy_topic: - title: "Política de privacidad" + title: "Políticas de Privacidad" body: | @@ -2919,7 +3178,7 @@ es: name: Promotor description: Invitó a un usuario long_description: | - Esta insignia se concede cuanto invitas a alguien a unirse a la comunidad a través del botón de invitar en tu página de usuario o al final de un tema. Invitar amigos que puedan estar interesados en debates específicos es una gran manera de traer gente nueva a la comunidad, así que ¡gracias! + Este distintivo se concede cuando invitas a alguien a unirse a la comunidad a través del botón de invitación en tu página del perfil o al final de un tema. Invitar a amigos que puedan estar interesados en debates específicos es la manera perfecta para introducirles a la comunidad, ¡así que gracias! campaigner: name: Paladín description: Invitó a 3 usuarios @@ -3019,7 +3278,7 @@ es: name: Primer emoji description: Utilizó un emoji en un post long_description: | - Esta insignia se te concede la primera vez que añades un Emoji a un mensaje :thumbsup:. Los Emoji te permiten mostrar tus emociones en tus mensajes: de alegría :smiley: a tristeza :anguished: o :angry: enfado, y todo lo que esté entre medias :sunglasses:. Basta con escribir : (dos puntos) o pulsar el botón de Emojis en el editor para seleccionar de cientos de opciones :ok_hand: + Este distintivo se concede la primera vez que añades un Emoji a tu post :thumbsup:. Los Emoji te permiten añadir emociones a tu publicación, desde felicidad :smiley: a tristeza :anguished: pasando por enfado :angry: o cualquier otra expresión :sunglasses: . Comienza escribiendo : (dos puntos) o haz clic en el botón Emoji de la barra del editor para seleccionar entre cientos de opciones :ok_hand: first_mention: name: Primera mención description: Mencionó a un usuario en un post @@ -3065,7 +3324,7 @@ es: title: "Etiquetas" staff_tag_disallowed: "La etiqueta \"%{tag}\" solo puede ser insertada por moderadores." staff_tag_remove_disallowed: "La etiqueta \"%{tag}\" solo puede ser eliminada por moderadores." - minimum_required_tags: "Debes seleccionar al menos %{count} etiquetas." + minimum_required_tags: "Debes seleccionar al menos %{count} etiquetas," rss_by_tag: "Temas con la etiqueta %{tag}" finish_installation: congratulations: "Enhorabuena, ¡has instalado Discourse!" @@ -3202,5 +3461,16 @@ es:

    Si alguna vez quieres cambiar alguno de estos ajustes, visita tu sección de administrador; la puedes encontrar el lado del icono de una llave inglesa en el menú de la página..

    Diviértete, y ¡buena suerte construyendo tu nueva comunidad!

    search_logs: - graph_title: "Número de búsquedas" - joined: "Se unió" + graph_title: "Cuenta de Búsquedas" + joined: "Registrado" + discourse_push_notifications: + popup: + mentioned: '%{username} te mencionó en "%{topic}" - %{site_title}' + group_mentioned: '%{username} te mencionó en "%{topic}" - %{site_title}' + quoted: '%{username} te cito en "%{topic}" - %{site_title}' + replied: '%{username} te respondió en "%{topic}" - %{site_title}' + posted: '%{username} publicó en "%{topic}" - %{site_title}' + private_message: '%{username} te envió un mensaje privado en "%{topic}" - %{site_title}' + linked: '%{username} enlazó tu publicación desde "%{topic}" - %{site_title}' + confirm_title: 'Notificaciones habilitadas - %{site_title}' + confirm_body: '¡Éxito! Las notificaciones han sido habilitadas.' diff --git a/config/locales/server.et.yml b/config/locales/server.et.yml index 6ee59cc2a2..988ae433cd 100644 --- a/config/locales/server.et.yml +++ b/config/locales/server.et.yml @@ -546,9 +546,7 @@ et: xaxis: "Päev" yaxis: "Külastajate arv" signups: - title: "Uued kasutajad" xaxis: "Päev" - yaxis: "Uute kasutajate arv" profile_views: title: "Kasutaja profiili vaatamisi" xaxis: "Päev" diff --git a/config/locales/server.fa_IR.yml b/config/locales/server.fa_IR.yml index ca681baeed..58f7cbb79b 100644 --- a/config/locales/server.fa_IR.yml +++ b/config/locales/server.fa_IR.yml @@ -663,9 +663,7 @@ fa_IR: xaxis: "روز" yaxis: "تعداد بازدید ها" signups: - title: "کاربران جدید" xaxis: "روز" - yaxis: "تعداد کاربران جدید" profile_views: title: "بازدید‌های نمایه کاربر" xaxis: "روز" diff --git a/config/locales/server.fi.yml b/config/locales/server.fi.yml index 96fa1f510e..67f0d1fee0 100644 --- a/config/locales/server.fi.yml +++ b/config/locales/server.fi.yml @@ -682,9 +682,7 @@ fi: xaxis: "Päivä" yaxis: "Vierailujen määrä" signups: - 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ä" diff --git a/config/locales/server.fr.yml b/config/locales/server.fr.yml index ba2ebe8ab9..12b43d0992 100644 --- a/config/locales/server.fr.yml +++ b/config/locales/server.fr.yml @@ -764,10 +764,7 @@ fr: xaxis: "Jour" yaxis: "Nombre de visites" signups: - title: "Nouveaux utilisateurs" xaxis: "Jour" - yaxis: "Nombre de nouveaux utilisateurs" - description: "Nouvelles inscriptions pour cette période" new_contributors: title: "Nouveaux contributeurs" xaxis: "Jour" @@ -776,8 +773,6 @@ fr: dau_by_mau: title: "DAU/MAU" xaxis: "Jour" - yaxis: "DAU/MAY" - description: "DAU / MAU – nombre d'utilisateurs qui se sont connectés dans la dernière journée, divisé par le nombre d'utilisateurs qui se sont connectés dans le dernier mois – en %" daily_engaged_users: title: "Utilisateurs impliqués au quotidien" xaxis: "Jour" @@ -831,7 +826,6 @@ fr: labels: term: Terme searches: Recherches - click_through: Taux de clics suivis emails: title: "Courriels envoyés" xaxis: "Jour" @@ -841,7 +835,6 @@ fr: xaxis: "Jour" yaxis: "Nombre de messages" user_to_user_private_messages_with_replies: - title: "Utilisateur à utilisateur (y compris réponses)" xaxis: "Jour" yaxis: "Nombre de messages" system_private_messages: diff --git a/config/locales/server.gl.yml b/config/locales/server.gl.yml index dd3ab2f7f0..2b9231fbf1 100644 --- a/config/locales/server.gl.yml +++ b/config/locales/server.gl.yml @@ -269,9 +269,7 @@ gl: 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" diff --git a/config/locales/server.he.yml b/config/locales/server.he.yml index 5bd9322171..a4f9cec205 100644 --- a/config/locales/server.he.yml +++ b/config/locales/server.he.yml @@ -91,14 +91,17 @@ he: one: "לא ניתן למחוק בגלל קיומה של רשומה תלויה %{record}" many: "לא ניתן למחוק רשומה בגלל קיומה של רשומה תלויה %{record}" too_long: + many: ארוך מידי (המקסימום האפשרי הוא %{count} תוים) one: ארוך מידי (המקסימום האפשרי הוא תו אחד) other: ארוך מידי (המקסימום האפשרי הוא %{count} תוים) two: ארוך מידי (המקסימום האפשרי הוא %{count} תוים) too_short: + many: קצר מידי (המינימום הנדרש הוא %{count} תוים) one: קצר מידי (המינימום הנדרש הוא תו אחד) other: קצר מידי (המינימום הנדרש הוא %{count} תוים) two: קצר מידי (המינימום הנדרש הוא %{count} תוים) wrong_length: + many: באורך שגוי (צריך להיות %{count} תוים) one: באורך שגוי (צריך להיות באורך תו אחד) other: באורך שגוי (צריך להיות %{count} תוים) two: באורך שגוי (צריך להיות %{count} תוים) @@ -106,6 +109,7 @@ he: template: body: 'היו בעיות עם השדות הבאים:' header: + many: '%{count} שגיאות מנעו מ-%{model} להישמר.' one: שגיאה מנעה מ-%{model} להישמר. other: '%{count} שגיאות מנעו מ-%{model} להישמר.' two: '%{count} שגיאות מנעו מ-%{model} להישמר.' @@ -141,6 +145,7 @@ he: reading_time: "זמן קריאה" likes: "לייקים" too_many_replies: + many: אנחנו מצטערים, אבל משתמשים חדשים מוגבלים זמנית ל-%{count} תגובות לאותו הנושא. one: אנחנו מצטערים, אבל משתמשים חדשים מוגבלים זמנית לתגובה אחת לאותו הנושא. other: אנחנו מצטערים, אבל משתמשים חדשים מוגבלים זמנית ל-%{count} תגובות לאותו הנושא. two: אנחנו מצטערים, אבל משתמשים חדשים מוגבלים זמנית ל-%{count} תגובות לאותו הנושא. @@ -153,6 +158,7 @@ he: no_hosts: "אף שרת לא הוגדר לשילוב." configure: "הגדרת שילוב (Embedding)" more_replies: + many: עוד %{count} תגובות one: עוד תגובה אחת other: עוד %{count} תגובות two: עוד %{count} תגובות @@ -161,31 +167,37 @@ he: imported_from: "זה נושא דיון מלווה לערך המקורי ב- %{link}" in_reply_to: "◄ %{username}" replies: + many: '%{count} תגובות' one: תגובה אחת other: '%{count} תגובות' two: '%{count} תגובות' no_mentions_allowed: "מצטערים, אך אינכם יכולים לאזכר משתמשים אחרים." too_many_mentions: + many: מצטערים, אתם יכולים לאזכר רק %{count} משתמשים בפוסט one: מצטערים, אתם יכולים לאזכר רק משתמש אחד בפוסט other: מצטערים, אתם יכולים לאזכר רק %{count} משתמשים בפוסט two: מצטערים, אתם יכולים לאזכר רק %{count} משתמשים בפוסט no_mentions_allowed_newuser: "מצטערים, משתמשים חדשים לא יכולים להזכיר משתמשים אחרים." too_many_mentions_newuser: + many: 'מצטערים, משתמשים חדשים יכולים להזכיר רק %{count} משתמשים אחרים בפוסט. ' one: מצטערים, משתמשים חדשים יכולים לאזכר רק משתמש אחד בפוסט. other: 'מצטערים, משתמשים חדשים יכולים להזכיר רק %{count} משתמשים אחרים בפוסט. ' two: 'מצטערים, משתמשים חדשים יכולים להזכיר רק %{count} משתמשים אחרים בפוסט. ' no_images_allowed: "מצטערים, משתמשים חדשים לא יכולים להוסיף תמונות לפוסטים." too_many_images: + many: מצטערים, משתמשים חדשים יכולים להוסיף רק %{count} תמונות לפוסט. one: מצטערים, משתמשים חדשים יכולים להוסיף רק תמונה אחת לפוסט. other: מצטערים, משתמשים חדשים יכולים להוסיף רק %{count} תמונות לפוסט. two: מצטערים, משתמשים חדשים יכולים להוסיף רק %{count} תמונות לפוסט. no_attachments_allowed: "מצטערים, משתמשים חדשים לא יכולים להוסיף קבצים לפוסטים." too_many_attachments: + many: מצטערים, משתמשים חדשים יכולים להוסיף רק %{count} צירופים לפוסט. one: מצטערים, משתמשים חדשים יכולים להוסיף רק צירוף אחד לפוסט. other: מצטערים, משתמשים חדשים יכולים להוסיף רק %{count} צירופים לפוסט. two: מצטערים, משתמשים חדשים יכולים להוסיף רק %{count} צירופים לפוסט. no_links_allowed: "מצטערים, משתמשים חדשים לא יכולים להוסיף קישורים לפוסטים." too_many_links: + many: מצטערים, משתמשים חדשים יכולים להוסיף רק %{count} קישורים בפוסט. one: מצטערים, משתמשים חדשים יכולים להוסיף רק קישור אחד בפוסט. other: מצטערים, משתמשים חדשים יכולים להוסיף רק %{count} קישורים בפוסט. two: מצטערים, משתמשים חדשים יכולים להוסיף רק %{count} קישורים בפוסט. @@ -253,6 +265,7 @@ he: title: "בקשת חברות עבור @%{group_name}" education: until_posts: + many: '%{count} פוסטים' one: פוסט אחד other: '%{count} פוסטים' two: '%{count} פוסטים' @@ -429,6 +442,7 @@ he: uncategorized: "לא ניתן למחוק תוכן ללא קטגוריה" has_subcategories: "לא ניתן למחוק קטגוריה זו משום שיש בה תת-קטגוריות." topic_exists: + many: לא ניתן למחוק את הקטגוריה הזו משום שיש בה %{count} נושאים. הנושא הותיק ביותר הוא %{topic_link}. one: לא ניתן למחוק את הקטגוריה הזו משום שיש בה נושא אחד. הנושא הותיק ביותר הוא %{topic_link}. other: לא ניתן למחוק את הקטגוריה הזו משום שיש בה %{count} נושאים. הנושא הותיק ביותר הוא %{topic_link}. two: לא ניתן למחוק את הקטגוריה הזו משום שיש בה %{count} נושאים. הנושא הותיק ביותר הוא %{topic_link}. @@ -451,14 +465,17 @@ he: broken: "תמונה זו שבורה" rate_limiter: hours: + many: '%{count} שעות' one: שעה אחת other: '%{count} שעות' two: '%{count} שעות' minutes: + many: '%{count} דקות' one: דקה אחת other: '%{count} דקות' two: '%{count} דקות' seconds: + many: '%{count} שניות' one: שניה אחת other: '%{count} שניות' two: '%{count} שניות' @@ -466,92 +483,114 @@ he: distance_in_words: half_a_minute: "פחות מדקה" less_than_x_seconds: + many: פחות מ-%{count} שניות one: פחות משנייה other: פחות מ-%{count} שניות two: פחות מ-%{count} שניות x_seconds: + many: '%{count} שניות' one: שנייה other: '%{count} שניות' two: '%{count} שניות' less_than_x_minutes: + many: פחות מ-%{count} דקות one: פחות מדקה other: פחות מ-%{count} דקות two: פחות מ-%{count} דקות x_minutes: + many: '%{count} דקות' one: דקה other: '%{count} דקות' two: '%{count} דקות' about_x_hours: + many: '%{count} שעות' one: שעה other: '%{count} שעות' two: '%{count} שעות' x_days: + many: '%{count} ימים' one: יום other: '%{count} ימים' two: '%{count} ימים' about_x_months: + many: '%{count} חודשים' one: חודש other: '%{count} חודשים' two: '%{count} חודשים' x_months: + many: '%{count} חודשים' one: חודש other: '%{count} חודשים' two: '%{count} חודשים' about_x_years: + many: '%{count} שנים' one: שנה other: '%{count} שנים' two: '%{count} שנים' over_x_years: + many: יותר מ-%{count} שנים one: יותר משנה other: יותר מ-%{count} שנים two: יותר מ-%{count} שנים almost_x_years: + many: '%{count} שנים' one: שנה other: '%{count} שנים' two: '%{count} שנים' distance_in_words_verbose: half_a_minute: "ממש עכשיו" less_than_x_seconds: + many: ממש עכשיו one: ממש עכשיו other: ממש עכשיו two: ממש עכשיו x_seconds: + many: לפני %{count} שניות one: לפני שנייה other: לפני %{count} שניות two: לפני %{count} שניות less_than_x_minutes: + many: לפני פחות מ-%{count} דקות one: לפני פחות מדקה other: לפני פחות מ-%{count} דקות two: לפני פחות מ-%{count} דקות x_minutes: + many: לפני %{count} דקות one: לפני דקה other: לפני %{count} דקות two: לפני %{count} דקות about_x_hours: + many: לפני %{count} שעות one: לפני שעה other: לפני %{count} שעות two: לפני %{count} שעות x_days: + many: לפני %{count} ימים one: אתמול other: לפני %{count} ימים two: לפני %{count} ימים about_x_months: + many: לפני בערך %{count} חודשים one: לפני בערך חודש other: לפני בערך %{count} חודשים two: לפני בערך %{count} חודשים x_months: + many: לפני %{count} חודשים one: לפני חודש other: לפני %{count} חודשים two: לפני %{count} חודשים about_x_years: + many: לפני בערך %{count} שנים one: לפני בערך שנה other: לפני בערך %{count} שנים two: לפני בערך %{count} שנים over_x_years: + many: לפני יותר מ %{count} שנים one: לפני יותר משנה other: לפני יותר מ %{count} שנים two: לפני יותר מ %{count} שנים almost_x_years: + many: לפני כמעט %{count} שנים one: לפני כמעט שנה other: לפני כמעט %{count} שנים two: לפני כמעט %{count} שנים @@ -705,9 +744,7 @@ he: xaxis: "יום" yaxis: "מספר ביקורים" signups: - title: "משתמשים חדשים" xaxis: "יום" - yaxis: "מספר משתמשים חדשים" profile_views: title: "צפיות בפרופילי משתמשים" xaxis: "יום" @@ -854,6 +891,7 @@ he: failing_emails_warning: 'יש %{num_failed_jobs} עבודות מייל שנכשלו. בידקו את app.yml שלכם כדי לוודא ששרת המייל מוגדר כיאות. ראו את העבודות שנכשלו ב Sidekiq.' subfolder_ends_in_slash: "הגדרות תיקיית המשנה שלכם לא נכונות, הנתיב DISCOURSE_RELATIVE_URL_ROOT צריך להסתיים בלוכסן." email_polling_errored_recently: + many: ניסיונות שליחת מיילים יצרו %{count} תקלות ב 24 השעות האחרונות. צפו ביומנים לפרטים נוספים. one: ניסיונות שליחת מיילים יצרו תקלה ב 24 השעות האחרונות. צפו ביומנים לפרטים נוספים. other: ניסיונות שליחת מיילים יצרו %{count} תקלות ב 24 השעות האחרונות. צפו ביומנים לפרטים נוספים. two: ניסיונות שליחת מיילים יצרו %{count} תקלות ב 24 השעות האחרונות. צפו ביומנים לפרטים נוספים. @@ -1358,6 +1396,7 @@ he: not_seen_in_a_month: "ברוך שובכם! לא ראינו אתכם כבר כמה זמן, אה? הנה כמה נושאים פופולאריים שהתווספו מאז שהייתם כאן." merge_posts: edit_reason: + many: '%{count} פוסטים מוזגו על ידי %{username}' one: פוסט מוזג על ידי %{username} other: '%{count} פוסטים מוזגו על ידי %{username}' two: '%{count} פוסטים מוזגו על ידי %{username}' @@ -1366,10 +1405,12 @@ he: different_users: "לא ניתן למזג פוסטים ששייכים למשתמשים שונים." move_posts: new_topic_moderator_post: + many: '%{count} תגובות פוצלו לנושא חדש: %{topic_link}' one: 'תגובה פוצלה לנושא חדש: %{topic_link}' other: '%{count} תגובות פוצלו לנושא חדש: %{topic_link}' two: '%{count} תגובות פוצלו לנושא חדש: %{topic_link}' existing_topic_moderator_post: + many: '%{count} תגובות אוחדו לנושא קיים: %{topic_link}' one: 'תגובה אוחדה לנושא קיים: %{topic_link}' other: '%{count} תגובות אוחדו לנושא קיים: %{topic_link}' two: '%{count} תגובות אוחדו לנושא קיים: %{topic_link}' @@ -1382,58 +1423,72 @@ he: closed_enabled: "הנושא הזה סגור. לא ניתן להגיב תגובות חדשות." closed_disabled: "הנושא הזה פתוח. ניתן להגיב תגובות חדשות." autoclosed_message_max_posts: + many: 'הודעה זו נסגרה אוטומטית אחרי שהגיעה למספר המקסימלי של תגובות: %{count} .' one: 'הודעה זו נסגרה אוטומטית אחרי שהגיעה למספר המקסימלי של תגובות: 1 .' other: 'הודעה זו נסגרה אוטומטית אחרי שהגיעה למספר המקסימלי של תגובות: %{count} .' two: 'הודעה זו נסגרה אוטומטית אחרי שהגיעה למספר המקסימלי של תגובות: %{count} .' autoclosed_topic_max_posts: + many: 'נושא זה נסגר אוטומטית אחרי שהגיע למספר המקסימלי של תגובות: %{count} .' one: 'נושא זה נסגר אוטומטית לאחר שהגיע למספר המקסימלי של תגובות: 1.' other: 'נושא זה נסגר אוטומטית אחרי שהגיע למספר המקסימלי של תגובות: %{count} .' two: 'נושא זה נסגר אוטומטית אחרי שהגיע למספר המקסימלי של תגובות: %{count} .' autoclosed_enabled_days: + many: נושא זה נסגר באופן אוטומטי לאחר %{count} ימים. לא ניתן להוסיף תגובות חדשות. one: הנושא הזה ננעל אוטומטית לאחר יום אחד. תגובות חדשות לא מתקבלות. other: נושא זה נסגר באופן אוטומטי לאחר %{count} ימים. לא ניתן להוסיף תגובות חדשות. two: נושא זה נסגר באופן אוטומטי לאחר %{count} ימים. לא ניתן להוסיף תגובות חדשות. autoclosed_enabled_hours: + many: נושא זה נסגר אוטומטית לאחר %{count} שעות. לא ניתן להוסיף תגובות חדשות. one: נושא זה ננעל לאחר שעה אחת. לא ניתן להוסיף תגובות חדשות. other: נושא זה נסגר אוטומטית לאחר %{count} שעות. לא ניתן להוסיף תגובות חדשות. two: נושא זה נסגר אוטומטית לאחר %{count} שעות. לא ניתן להוסיף תגובות חדשות. autoclosed_enabled_minutes: + many: הנושא הזה נסגר אוטומטית לאחר %{count} דקות. תגובות חדשות לא מתקבלות. one: הנושא הזה ננעל אוטומטית לאחר דקה. תגובות חדשות לא מתקבלות. other: הנושא הזה נסגר אוטומטית לאחר %{count} דקות. תגובות חדשות לא מתקבלות. two: הנושא הזה נסגר אוטומטית לאחר %{count} דקות. תגובות חדשות לא מתקבלות. autoclosed_enabled_lastpost_days: + many: נושא זה נסגר אוטומטית לאחר %{count} ימים מהתגובה האחרונה. תגובות חדשות לא מתקבלות. one: נושא זה ננעל אוטומטית לאחר יום אחד מהתגובה האחרונה. תגובות חדשות לא מתקבלות. other: נושא זה נסגר אוטומטית לאחר %{count} ימים מהתגובה האחרונה. תגובות חדשות לא מתקבלות. two: נושא זה נסגר אוטומטית לאחר %{count} ימים מהתגובה האחרונה. תגובות חדשות לא מתקבלות. autoclosed_enabled_lastpost_hours: + many: נושא זה נסגר אוטומטית %{count} שעות לאחר התגובה האחרונה. תגובות נוספות אינן מותרות יותר. one: נושא זה נסגר שעה לאחר התגובה האחרונה. תגובות נוספות אינן מותרות יותר. other: נושא זה נסגר אוטומטית %{count} שעות לאחר התגובה האחרונה. תגובות נוספות אינן מותרות יותר. two: נושא זה נסגר אוטומטית %{count} שעות לאחר התגובה האחרונה. תגובות נוספות אינן מותרות יותר. autoclosed_enabled_lastpost_minutes: + many: נושא זה נסגר אוטומטית לאחר %{count} דקות מהתגובה האחרונה. תגובות חדשות לא מתקבלות. one: נושא זה ננעל אוטומטית לאחר דקה מהתגובה האחרונה. תגובות חדשות לא מתקבלות. other: נושא זה נסגר אוטומטית לאחר %{count} דקות מהתגובה האחרונה. תגובות חדשות לא מתקבלות. two: נושא זה נסגר אוטומטית לאחר %{count} דקות מהתגובה האחרונה. תגובות חדשות לא מתקבלות. autoclosed_disabled_days: + many: נושא זה נפתח אוטומטית לאחר %{count} ימים. one: נושא זה נפתח אוטומטית לאחר יום 1. other: נושא זה נפתח אוטומטית לאחר %{count} ימים. two: נושא זה נפתח אוטומטית לאחר %{count} ימים. autoclosed_disabled_hours: + many: נושא זה נפתח אוטומטית לאחר %{count} שעות. one: נושא זה נפתח אוטומטית לאחר שעה 1. other: נושא זה נפתח אוטומטית לאחר %{count} שעות. two: נושא זה נפתח אוטומטית לאחר %{count} שעות. autoclosed_disabled_minutes: + many: נושא זה נפתוח אוטומטית לאחר %{count} דקות. one: נושא זה נפתח אוטומטית לאחר דקה 1. other: נושא זה נפתוח אוטומטית לאחר %{count} דקות. two: נושא זה נפתוח אוטומטית לאחר %{count} דקות. autoclosed_disabled_lastpost_days: + many: הנושא נפתח אוטומטית %{count} ימים אחרי התגובה האחרונה. one: הנושא נפתח אוטומטית יום 1 אחרי התגובה האחרונה. other: הנושא נפתח אוטומטית %{count} ימים אחרי התגובה האחרונה. two: הנושא נפתח אוטומטית %{count} ימים אחרי התגובה האחרונה. autoclosed_disabled_lastpost_hours: + many: נושא זה נפתח אוטומטית %{count} שעות אחרי התגובה האחרונה. one: נושא זה נפתח אוטומטית שעה 1 אחרי התגובה האחרונה. other: נושא זה נפתח אוטומטית %{count} שעות אחרי התגובה האחרונה. two: נושא זה נפתח אוטומטית %{count} שעות אחרי התגובה האחרונה. autoclosed_disabled_lastpost_minutes: + many: נושא זה נפתח אוטומטית %{count} דקות אחרי התגובה האחרונה. one: נושא זה נפתח אוטומטית דקה 1 אחרי התגובה האחרונה. other: נושא זה נפתח אוטומטית %{count} דקות אחרי התגובה האחרונה. two: נושא זה נפתח אוטומטית %{count} דקות אחרי התגובה האחרונה. @@ -1496,10 +1551,12 @@ he: domain_not_allowed: "אתר לא תקין. מתחמים מותרים: %{domains}" flags_reminder: flags_were_submitted: + many: דגלים נרשמו לפני יותר מ %{count} שעות. [אנא סיקרו אותם](/admin/flags). one: דגלים נרשמו לפני יותר משעה. [אנא סיקרו אותם](/admin/flags). other: דגלים נרשמו לפני יותר מ %{count} שעות. [אנא סיקרו אותם](/admin/flags). two: דגלים נרשמו לפני יותר מ %{count} שעות. [אנא סיקרו אותם](/admin/flags). subject_template: + many: '%{count} דגלים ממתינים לטיפול' one: דגל אחד ממתין לטיפול other: '%{count} דגלים ממתינים לטיפול' two: '%{count} דגלים ממתינים לטיפול' @@ -1571,6 +1628,7 @@ he: deferred: "תודה שעדכנתם אותנו. אנחנו בודקים את העניין." deferred_and_deleted: "תודה שעדכנתם אותנו. הסרנו את הפוסט." temporarily_closed_due_to_flags: + many: נושא זה סגור זמנית ל-%{count} שעות עקב מספר רב של דגלי קהילה. one: נושא זה סגור זמנית לשעה 1 עקב מספר רב של דגלי קהילה. other: נושא זה סגור זמנית ל-%{count} שעות עקב מספר רב של דגלי קהילה. two: נושא זה סגור זמנית ל-%{count} שעות עקב מספר רב של דגלי קהילה. @@ -1777,6 +1835,7 @@ he: pending_users_reminder: title: "תזכורת משתמשים ממתינים" subject_template: + many: '%{count} משתמשים ממתינים לאישורכם' one: משתמש 1 ממתין לאישורכם other: '%{count} משתמשים ממתינים לאישורכם' two: '%{count} משתמשים ממתינים לאישורכם' @@ -1813,6 +1872,7 @@ he: user_notifications: previous_discussion: "תגובות קודמות" reached_limit: + many: 'שימו לב: אנחנו שולחים לכל היותר %{count} מיילים יומיים. בידקו באתר כדי לראות את אלו שעלולים להשאר מאחור. נ.ב: תודה שאתם פופולאריים!' one: 'שימו לב: אנחנו שולחים לכל היותר מייל 1 יומי. בידקו באתר כדי לראות את אלו שעלולים להשאר מאחור.' other: 'שימו לב: אנחנו שולחים לכל היותר %{count} מיילים יומיים. בידקו באתר כדי לראות את אלו שעלולים להשאר מאחור. נ.ב: תודה שאתם פופולאריים!' two: 'שימו לב: אנחנו שולחים לכל היותר %{count} מיילים יומיים. בידקו באתר כדי לראות את אלו שעלולים להשאר מאחור. נ.ב: תודה שאתם פופולאריים!' diff --git a/config/locales/server.id.yml b/config/locales/server.id.yml index e938a17e86..72259317ab 100644 --- a/config/locales/server.id.yml +++ b/config/locales/server.id.yml @@ -310,9 +310,7 @@ id: xaxis: "Haru" yaxis: "Jumlah kunjungan" signups: - title: "Pengguna Baru" xaxis: "Hari" - yaxis: "Jumlah pengguna baru" profile_views: xaxis: "Hari" topics: diff --git a/config/locales/server.it.yml b/config/locales/server.it.yml index 2abea1653b..4836c61dad 100644 --- a/config/locales/server.it.yml +++ b/config/locales/server.it.yml @@ -678,9 +678,7 @@ it: xaxis: "Giorno" yaxis: "Numero visite" signups: - title: "Nuovi Utenti" xaxis: "Giorno" - yaxis: "Numero di nuovi utenti" profile_views: title: "Visite Profilo Utente" xaxis: "Giorno" diff --git a/config/locales/server.ja.yml b/config/locales/server.ja.yml index 6f602f90e8..e18b205fcd 100644 --- a/config/locales/server.ja.yml +++ b/config/locales/server.ja.yml @@ -402,9 +402,7 @@ ja: xaxis: "日" yaxis: "アクセス数" signups: - title: "新規ユーザー" xaxis: "日" - yaxis: "新規ユーザー数" profile_views: xaxis: "日" yaxis: "ユーザープロフィールの閲覧数" diff --git a/config/locales/server.ko.yml b/config/locales/server.ko.yml index 3da2962cf4..a0c99eb58e 100644 --- a/config/locales/server.ko.yml +++ b/config/locales/server.ko.yml @@ -608,9 +608,7 @@ ko: xaxis: "일" yaxis: "방문자 수" signups: - title: "새 사용자" xaxis: "일" - yaxis: "새로운 사용자 수" profile_views: title: "회원 프로필 조회수" xaxis: "일" diff --git a/config/locales/server.nb_NO.yml b/config/locales/server.nb_NO.yml index 7c53ed3dda..d574ab2160 100644 --- a/config/locales/server.nb_NO.yml +++ b/config/locales/server.nb_NO.yml @@ -29,16 +29,39 @@ nb_NO: loading: "Laster" powered_by_html: 'Drives av Discourse, og ser best ut med JavaScript aktivert' log_in: "Logg inn" + submit: "Send" 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" remove_posts_deleted_by_author: "Slettet av forfatter" + redirect_warning: "Vi kunne ikke verifisere at lenken du valgte faktisk var publisert på forumet. Hvis du likevel ønsker å fortsette, velg lenken under." themes: bad_color_scheme: "Kan ikke oppdatere drakt, ugyldig fargepalett" + other_error: "Noe gikk galt under oppdateringen av drakten" + error_importing: "En feil oppstod under kloning av git repository, tilgang ble nektet eller repository ikke funnet." + settings_errors: + invalid_yaml: "YAML koden er ikke gyldig." + data_type_not_a_number: "Innstilling `%{name}` typen er ikke støttet. Støttede typer er `integer`, `bool`, `list` og `enum`" + name_too_long: "En eller flere innstillinger har for langt navn. Maksimal lengde er 255 tegn" + default_value_missing: "Innstilling `%{name}` har ingen standardverdi" + default_not_match_type: "Innstilling `%{name}` har en type standardverdi som ikke stemmer med den definerte typen for innstillingen." + default_out_range: "Innstilling `%{name}` sin standardverdi er utenfor de tillatte grenseverdiene." + enum_value_not_valid: "Den valgte verdien er ikke en av de oppførte valgmulighetene." + number_value_not_valid: "Ny verdi er utenfor de tillatte grenseverdiene." + number_value_not_valid_min_max: "Den må være mellom %{min} og %{max}." + number_value_not_valid_min: "Den må være større enn eller lik %{min}." + number_value_not_valid_max: "Den må være mindre enn eller lik %{max}." + string_value_not_valid: "Lengden på ny verdi er ikke innenfor grensen." + string_value_not_valid_min_max: "Den må være mellom %{min} og %{max} tegn lang." + string_value_not_valid_min: "Den må være minst %{min} tegn lang." + string_value_not_valid_max: "Den må være maksimalt %{max} tegn lang." emails: incoming: default_subject: "Tråden trenger en tittel" show_trimmed_content: "Vis beskåret innhold" + maximum_staged_user_per_email_reached: "Grensen er nådd for antall arrangerte brukere per e-post." + no_subject: "(mangler emne)" + no_body: "(mangler tekst)" errors: empty_email_error: "Skjer når den rå e-posten vi mottok var blank." no_message_id_error: "Skjer når en e-post ikke har noen «Message-ID»-hode." @@ -46,15 +69,21 @@ nb_NO: no_body_detected_error: "Skjer når vi ikke kunne trekke ut meldingskroppen eller det ikke var noen vedlegg." no_sender_detected_error: "Skjer når vi ikke kunne finne en gyldig adresse i Fra-hodet." inactive_user_error: "Skjer når senderen ikke er aktiv." + silenced_user_error: "Skjer når senderen er dempet." bad_destination_address: "Skjer når ingen av adressene i To-, Cc- eller Bcc-feltene passer med en konfigurert innkommende e-postadresse." strangers_not_allowed_error: "Skjer når en bruker har forsøkt å opprette en ny tråd i en kategori som vedkommende ikke er medlem av." insufficient_trust_level_error: "Skjer når en bruker har forsøkt å opprette en ny tråd i en kategori som vedkommende ikke har påkrevet tillitsnivå for." reply_user_not_matching_error: "Skjer når et innkommende svar kommer fra en annen e-postadresse enn varselet var sendt til." topic_not_found_error: "Skjer når et svar blir mottatt, men den tilhørende tråden er slettet." topic_closed_error: "Skjer når et svar blir mottatt, men den tilhørende tråden er stengt." + bounced_email_error: "E-posten er en returnert e-postrapport." + screened_email_error: "Skjer når avsenderens e-postadresse allerede var filtrert." + unsubscribe_not_allowed: "Skjer når avmelding via e-post ikke er tillatt for denne brukeren." + email_not_allowed: "Skjer når e-postadressen ikke er på hvitlisten eller er svartelistet." unrecognized_error: "Ukjent feil" errors: &errors format: '%{attribute} %{message}' + format_with_full_message: '%{attribute}: %{message}' messages: too_long_validation: "er begrenset til %{max} tegn; du brukte %{length}." invalid_boolean: "Ugyldig boolsk verdi." @@ -80,6 +109,8 @@ nb_NO: not_an_integer: må være ett heltall odd: må være oddetall record_invalid: 'Validering feilet: %{errors}' + max_emojis: "kan ikke ha over %{max_emojis_count} emoji" + ip_address_already_screened: "er allerede inkludert i en eksisterende regel" restrict_dependent_destroy: one: "Kunne ikke slette oppføringen, oppføringen %{record} er avhengig av denne" many: "Kunne ikke slette oppføringen, oppføringen %{record} er avhengig av denne" @@ -101,24 +132,39 @@ nb_NO: embed: load_from_remote: "Det oppstod et problem med innlastingen av innlegget." site_settings: + invalid_choice: + one: Du spesifiserte det ugyldige valget %{name} + other: Du spesifiserte de ugyldige valgene %{name} min_username_length_exists: "Du kan ikke sette minimumslengden på brukernavn over det korteste brukernavnet." min_username_length_range: "Du kan ikke sette minimum høyere enn maksimum." max_username_length_exists: "Du kan ikke sette maksimallengden for brukernavn under det lengste brukernavnet." max_username_length_range: "Du kan ikke sette maksimum under minimum." default_categories_already_selected: "Du kan ikke velge en annen kategori brukt i en annen liste." + s3_upload_bucket_is_required: "Du kan ikke aktivere opplasting til S3 hvis ikke du har satt innstillingen 's3_upload_bucket'." + conflicting_google_user_id: 'Google Account ID for denne kontoen har endret seg; staben må manuelt godkjenne endringen av sikkerhetshensyn. Vennligst kontakt staben og pek dem til
    https://meta.discourse.org/t/76575' activemodel: errors: <<: *errors invite: not_found: "Ditt invitasjonssymbol er ugyldig. Kontakt sidens administrator." + not_found_template: | +

    Invitasjonen din til %{site_name} er allerede brukt.

    + +

    Hvis du husker passordet ditt kan du Logge Inn.

    + +

    Hvis ikke kan du Nullstille Passordet.

    + user_exists: "Det er ikke nødvendig å invitere %{email}, de har allerede en konto!" bulk_invite: file_should_be_csv: "Filen som lastes opp burde være i csv format." error: "Det skjedde en feil når filen ble lastet opp. Prøv igjen senere. " + topic_invite: + user_exists: "Beklager, den brukeren er allerede invitert. Du kan ikke invitere samme bruker til et emne flere ganger." backup: operation_already_running: "En prosess kjører allerede. Kan ikke starte en ny jobb akkurat nå." backup_file_should_be_tar_gz: "Backup-filen må være en .tar.gz -arkiveringsfil." not_enough_space_on_disk: "Det er ikke nok diskplass til å laste opp denne backupen." invalid_filename: "Det sikkerhetskopierte filnavnet inneholder ugyldige tegn. Gyldige tegn er a-z 0-9 . - _." + invalid_params: "Du brukte feil parametre i forespørselen: %{message}" not_logged_in: "Du må være innlogget for å gjøre det." not_found: "Den etterspurte URL eller ressurs ble ikke funnet" invalid_access: "Du har ingen tilgang til denne resurssen." @@ -152,6 +198,10 @@ nb_NO: one: 'Beklager, du kan bare nevne en bruker i et innlegg. ' other: 'Beklager, du kan bare nevne %{count} brukere i et innlegg. ' no_mentions_allowed_newuser: "Beklager, nye brukere kan ikke nevne andre brukere." + too_many_mentions_newuser: + 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. + no_images_allowed_trust: "Beklager, du kan ikke legge til bilder i et innlegg." no_images_allowed: "Beklager, nye brukere kan ikke legge til bilder i et innlegg." too_many_images: one: Beklager, nye brukere kan bare legge til ett bilde i et innlegg. @@ -161,11 +211,19 @@ nb_NO: one: Beklager, nye brukere kan bare laste opp ett vedlegg til et innlegg. other: Beklager, nye brukere kan bare laste opp %{count} vedlegg til et innlegg. no_links_allowed: "Beklager, nye brukere kan ikke publisere innlegg med lenker." + links_require_trust: "Beklager, du kan ikke legge til lenker i et innlegg." + too_many_links: + one: Beklager, nye brukere kan bare legge til én lenke i et innlegg. + other: Beklager, nye brukere kan bare legge til %{count} lenker i et innlegg. + contains_blocked_words: "Innlegget ditt inneholder et ord som ikke er tillatt: %{word}" spamming_host: "Beklager, du kan ikke lenke til det domenet." user_is_suspended: "Utestengte brukere kan ikke skrive innlegg." topic_not_found: "Noe gikk galt. Kanskje tråden ble lukket eller slettet mens du leste den?" + not_accepting_pms: "Beklager, %{username} ønsker ikke å motta personlige meldinger." + max_pm_recepients: "Beklager, du kan bare sende en melding til maksimalt %{recipients_limit} mottakere." just_posted_that: "er for likt det du nylig publiserte." invalid_characters: "inneholder ugyldige tegn" + is_invalid: "virker uklart, er det en komplett setning?" next_page: "neste side →" prev_page: "← forrige side" page_num: "Side %{num}" @@ -195,17 +253,29 @@ nb_NO: user_posts: "Siste innlegg av @%{username}" user_topics: "Siste tråder av @%{username}" tag: "Tråder med stikkord" + badge: "%{display_name} merke på %{site_title}" too_late_to_edit: "Det er for lenge siden det innlegget ble skrevet. Det kan ikke lenger redigeres eller slettes." + revert_version_same: "Den gjeldende versjonen er den samme som den du prøver å rulle tilbake til." excerpt_image: "bilde" queue: delete_reason: "Slettet via køen for innleggmoderering" + not_found: "Innlegget ble ikke funnet eller er allerede oppdatert." groups: + success: + bulk_add: + one: '%{count} bruker ble lagt til i gruppen.' + other: '%{count} brukere ble lagt til i gruppen.' errors: + grant_trust_level_not_valid: "'%{trust_level}' er ikke et gyldig tillitsnivå." can_not_modify_automatic: "Du kan ikke modifisere en automatisk gruppe" + member_already_exist: + one: '''%{username}'' er allerede medlem av denne gruppen.' + other: 'Følgende brukere er allerede medlemmer av denne gruppen: %{username}' invalid_domain: "'%{domain}' er ikke et gyldig domene." invalid_incoming_email: "'%{email}' er ikke en gyldig e-postadresse." email_already_used_in_group: "'%{email}' er allerede i bruk av gruppa '%{group_name}'." email_already_used_in_category: "'%{email}' er allerede i bruk av kategorien '%{category_name}'." + cant_allow_membership_requests: "Du kan ikke tillate forespørsler om medlemskap for en gruppe som ikke har noen eiere." default_names: everyone: "alle" admins: "administratorer" @@ -216,6 +286,8 @@ nb_NO: trust_level_2: "tillitsnivå_2" trust_level_3: "tillitsnivå_3" trust_level_4: "tillitsnivå_4" + request_membership_pm: + title: "Ønske om medlemskap i gruppen @%{group_name}" education: until_posts: one: 1 innlegg @@ -240,6 +312,48 @@ nb_NO: - Konstruktiv kritikk er velkommen, men husk å kritisere *idéer,* ikke mennesker. For mer informasjon [se retningslinjene våre](/guidelines). Dette panelet vil kun vises for ditt/dine første %{education_posts_text}. + avatar: | + ### Hva med et bilde på kontoen din? + + Du har skrevet et par emner og svar, men profilbildet ditt er ikke like unikt som du er - akkurat nå er det bare en bokstav. + + Har du vurdert å **[besøke brukerprofilen din](%{profile_path})** for å laste opp et bilde som kan representere deg? + + Det er lettere å følge diskusjoner og å finne interessante personer i en samtale om alle har et unikt profilbilde! + sequential_replies: | + ### Vurder å svare på flere innlegg samtidig + + I stedet for å legge inn flere svar på rad i et emne, anbefaler vi at du skriver et innlegg som kombinerer flere sitater fra tidligere innlegg eller @navn referanser. + + Du kan redigere det forrige svaret ditt om du ønsker å legge til et sitat ved å merke teksten som skal siteres og velge Sitat knappen som spretter opp. + + Det er lettere for alle å lese emner som har færre og mer dyptgående innlegg enn et stort antall små, individuelle svar. + dominating_topic: | + ### La andre delta i diskusjonen + + Dette emnet er helt klart viktig for deg – du har skrevet mer enn %{percent}% av svarene her. + + Er du sikker på at du gir andre folk nok tid til å dele sine synspunkter også? + get_a_room: | + ### Vurder å svare flere personer + + Du har allerede svart %{count}ganger til @%{reply_username} i dette ene emnet. + + Har du vurdert å skrive svar til *andre* folk i diskusjonen også? En bra diskusjon involverer mange stemmer og perspektiv. + + Hvis du vil fortsette en lang samtale med denne ene personen kan det være bedre å [sende dem en personlig melding](/u/%{reply_username}). + too_many_replies: | + ### Du har nådd grensen for svar i dette emnet + + Vi beklager, men nye brukere er midlertidig begrenset til å skrive %{newuser_max_replies_per_topic} svar per emne. + + I stedet for å legge til et nytt svar, vurder om du kan redigere et tidligere svar, eller besøk et annet emne i mellomtiden. + reviving_old_topic: | + ### Gjennopplive dette emnet? + + Det siste svaret i dette emnet ble skrevet **%{time_ago}**. Svaret ditt vil flytte emnet tilbake på toppen av listene og varsle alle tidligere deltagere av samtalen. + + Er du sikker på at du ønsker å fortsette denne gamle samtalen? activerecord: attributes: category: @@ -257,8 +371,12 @@ nb_NO: topic: attributes: base: + warning_requires_pm: "Du kan bare legge ved advarsel til personlige meldinger." too_many_users: "Du kan bare sende advarsel til en bruker om gangen." + cant_send_pm: "Beklager, du kan ikke sende en personlig melding til den brukeren." no_user_selected: "Du må velge en gyldig bruker. " + reply_by_email_disabled: "Svar via e-post er nå deaktivert." + target_user_not_found: "En av brukerne du prøver å sende denne meldingen til ble ikke funnet." featured_link: invalid: "er ugyldig. Nettadressen bør inneholde http:// eller https://" invalid_category: "kan ikke redigeres i denne kategorien." @@ -272,6 +390,10 @@ nb_NO: unique_characters: "har for mange gjentatte tegn. Benytt et sikrere passord." ip_address: signup_not_allowed: "Registrering er ikke tillatt fra denne kontoen." + user_email: + attributes: + user_id: + reassigning_primary_email: "Å flytte en primær e-postadresse over til en annen bruker er ikke tillatt." color_scheme_color: attributes: hex: @@ -291,7 +413,16 @@ nb_NO: attributes: execute_at: in_the_past: "må være i fremtiden." + translation_overrides: + attributes: + value: + invalid_interpolation_keys: 'De følgende interpolasjonsnøklene er ugyldige: "%{keys}"' + watched_word: + attributes: + word: + too_many: "For mange ord for den handlingen" user_profile: + no_info_me: "
    feltet \"Om Meg\" i profilen din er foreløpig blankt, ønsker du å fylle det ut?
    " no_info_other: "
    %{name} har ikke skrevet noe i Om meg-feltet i profilen sin ennå
    " vip_category_name: "Salong" vip_category_description: "En kategori tilgjengelig for brukere på tillitsnivå 3 og høyere." @@ -299,8 +430,24 @@ nb_NO: meta_category_description: "Diskusjon om dette nettstedet, hvordan det er organisert, hvordan det fungerer og hvordan vi kan forbedre det." staff_category_name: "Stab" staff_category_description: "Privat kategori for diskusjoner blant staben. Tråder er kun synlige for administratorer og moderatorer." + assets_topic_title: "Ressurser til nettstedets design" + assets_topic_body: "Dette emnet, kun synlig for staben, brukes for å lagre bilder og filer som benyttes av nettstedets design. Ikke slett emnet!\n\n\nHer er hvordan du bruker det:\n\n\n1. Svar på dette emnet.\n2. Last opp alle bilder du ønsker å bruke som logoer, ikoner og så videre her. (Bruk knappen merket \"last opp\" i redigeringsverktøyet eller trekk og slipp bilder.)\n3. Publiser svaret ditt.\n4. Høyreklikk på bildene for å kopiere stien til bildet, eller klikk på redigeringsknappen for å vise stien der. Kopier lenken til utklippstavlen.\n5. Lim lenkene til bildene inn der du ønsker å bruke dem i [grunnleggende oppsett](admin/site_settings/category/required).\n\n\nHvis du trenger å laste opp en annen type fil, kan du legge den til i listen `godkjente_filendelser` i instillingene for [Filer](/admin/site_settings/category/files)." discourse_welcome_topic: title: "Velkommen til Discourse" + body: |2 + + Det første avsnittet av dette festede emnet vil være synlig som en velkomstmelding til alle nye besøkende på hjemmesiden. Det er viktig! + + **Rediger dette** til en kort beskrivelse av samfunnet ditt: + + - Hvem er det ment for? + - Hva kan de finner her? + - Hvorfor skal de besøke stedet? + - Hvor kan de lese mer (lenker, ressurser, etc)? + + + + Vi anbefaler at du stenger dette emnet ved hjelp av Admin :wrench: knappen (oppe til høyre og i bunnen), slik at svar ikke hoper seg opp på en kunngjøring som denne. lounge_welcome: title: "Velkommen til salongen" body: |2 @@ -329,9 +476,14 @@ nb_NO: replace_paragraph: "(Erstatt dette første avsnittet med en kort beskrivelse av den nye kategorien din. Denne teksten vil vises i oversikten over kategorier, så prøv å holde lengden under 200 bokstaver. **Inntil du endrer denne beskrivelsen eller oppretter tråder, vil denne kategorien ikke vises på kategorier-siden.**)" post_template: "%{replace_paragraph}\n\nBruk de følgende avsnittene for en lengre beskrivelse, eller for å formulere retningslinjer eller regler for kategorien:\n\n- Hvorfor skal folk bruke denne kategorien? Hva er den ment for?\n\n- Hvordan skiller den seg fra de andre kategoriene vi allerede har?\n\n- Hva skal tråder i denne kategorien generelt sett inneholde?\n\n- Trenger vi denne kategorien? Kan vi slå den sammen med en annen kategori eller underkategori?\n" errors: + not_found: "Kategorien finnes ikke!" uncategorized_parent: "Ukategorisert kan ikke ha en foreldrekategori" self_parent: "En underkategori kan ikke være underlagt seg selv" depth: "En underkategori kan ikke underlegges en annen underkategori" + invalid_email_in: "'%{email}' er ikke en gyldig e-postadresse." + email_already_used_in_group: "'%{email}' er allerede i bruk av gruppen '%{group_name}'." + email_already_used_in_category: "'%{email}' er allerede i bruk av kategorien '%{category_name}'." + description_incomplete: "Innlegget som beskriver en kategori må ha minst ett avsnitt." cannot_delete: uncategorized: "Kan ikke slette Ukategorisert" has_subcategories: "Kan ikke slette denne kategorien fordi den har underkategorier." @@ -351,7 +503,28 @@ nb_NO: title: "aktivt medlem" leader: title: "leder" + change_failed_explanation: "Du forsøkte å nedgradere %{user_name} til '%{new_trust_level}'. Men tillitsnivået til brukeren er allerede '%{current_trust_level}'. %{user_name} vil bli værende ved '%{current_trust_level}' - hvis du ønsker å nedgradere brukeren må du låse fast tillitsnivået først" + post: + image_placeholder: + broken: "Dette bildet fungerer ikke" rate_limiter: + slow_down: "Du har utført denne handlingen for mange ganger, vennligst prøv igjen senere." + too_many_requests: "Du har utført denne handlingen for mange ganger. Vennligst vent %{time_left} før du prøver igjen." + by_type: + first_day_replies_per_day: "Du har nådd grensen for hvor mange innlegg en ny bruker kan skrive den første dagen. Vennligst vent %{time_left} før du prøver igjen." + first_day_topics_per_day: "Du har nådd grensen for hvor mange emner en ny bruker kan lage den første dagen. Vennligst vent %{time_left} før du prøver igjen." + create_topic: "Du lager emner i for høyt tempo! Vennligst vent %{time_left} før du prøver igjen." + create_post: "Du svarer for raskt. Vennligst vent %{time_left} før du prøver igjen." + delete_post: "Du sletter innlegg for fort. Vennligst vent %{time_left} før du prøver på nytt." + public_group_membership: "Du melder deg inn/ut av grupper for ofte. Vennligst vent %{time_left} før du prøver igjen." + topics_per_day: "Du har nådd grensen for publisering av nye emner. Vennligst vent %{time_left} før du prøver igjen." + pms_per_day: "Du har nådd grensen for antall meldinger. Vennligst vent %{time_left} før du prøver igjen." + create_like: "Du har nådd grensen for antall likte innlegg. Vennligst vent %{time_left} før du prøver igjen." + create_bookmark: "Du har nådd grensen for antall bokmerker. Vennligst vent %{time_left} før du prøver igjen." + edit_post: "Du har nådd grensen for antall redigeringer. Vennligst vent %{time_left} før du prøver igjen." + live_post_counts: "Du ber om oppdateringer av antall innlegg for ofte. Vennligst vent %{time_left} før du prøver igjen." + unsubscribe_via_email: "Du har nådd grensen for antall avmeldinger via e-post. Vennligst vent %{time_left} før du prøver igjen." + topic_invitations_per_day: "Du har nådd grensen for invitasjoner til emner. Vennligst vent %{time_left} før du prøver igjen." hours: one: 1 time other: '%{count} timer' @@ -441,10 +614,15 @@ nb_NO: title: 'Tilbakestill passord' success: "Du har endret passordet og er nå logget inn." success_unapproved: "Du har endret ditt passord." + email_login: + invalid_token: "Beklager, denne lenken for innlogging via e-post er for gammel. Bruk 'Logg Inn' knappen og deretter 'Jeg har glemt passordet' for å motta en oppdatert lenke." + title: "E-post innlogging" change_email: confirmed: "E-postaddressen din er blitt oppdatert." please_continue: "Fortsett til %{site_name}" error: "Det oppsto en feil ved endring av din e-postadresse. Kanskje addressen allerede er i bruk?" + error_staged: "En feil oppstod ved endring av e-postadressen din. Den nye adressen er allerede i bruk av en arrangert bruker." + already_done: "Beklager, denne godkjenningslenken er ikke lenger gyldig. Kanskje e-postadressen din allerede er byttet?" authorizing_old: title: "Takk for at du bekreftet din nåværende e-postadresse" description: "Vi sender deg en e-post til din nye adresse for bekreftelse." @@ -455,50 +633,74 @@ nb_NO: continue_button: "Fortsett til %{site_name}" welcome_to: "Velkommen til %{site_name}!" approval_required: "En moderator må manuelt godkjenne kontoen din før du får tilgang til forumet. Du vil motta en e-post når kontoen din er godkjent!" + missing_session: "Vi klarer ikke å se om kontoen din ble laget, vennligst sjekk om cookies/kapsler er aktivert i nettleseren." + activated: "Beklager, denne kontoen er allerede aktivert." admin_confirm: title: "Bekreft admin-konto" + description: "Er du sikker på at du ønsker at %{target_username} skal være en administrator?" grant: "Tildel admin-tilgang" + complete: "%{target_username} er nå en administrator." back_to: "Gå tilbake til %{title}" post_action_types: off_topic: title: 'Urelatert' description: 'Dette innlegget er ikke relevant for den aktuelle diskusjonen som fastsatt av tittelen og det første innlegget og burde sannsynligvis flyttes til et annet sted. ' + short_description: 'Ikke relevant til diskusjonen' long_form: 'markerte dette som urelevant' spam: title: 'Spam' + description: 'Dette innlegget er reklame, eller vandalisme. Det er ikke nyttig eller relevant for dette emnet.' + short_description: 'Dette er reklame eller vandalisme' long_form: 'markerte dette som spam' email_title: '"%{title}" ble rapportert som spam' email_body: "%{link}\n\n%{message}" inappropriate: title: 'Upassende' description: 'Dette innlegget har innhold som for en fornuftig person vil kunne være fornærmende, nedverdigende eller brudd på retningslinjene til denne gemenskapen.' + short_description: 'Et brudd på retningslinjene for samfunnet' long_form: 'markerte dette som upassende' notify_user: title: 'Send en melding til @{{username}}' + description: 'Jeg ønsker å snakke med denne personen direkte og personlig om innlegget.' + short_description: 'Jeg ønsker å snakke med denne personen direkte og personlig om innlegget.' 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 krever oppmerksomhet fra staben av en annen grunn enn listen over.' + short_description: 'Krever oppmerksomhet fra staben av en annen grunn' + long_form: 'flagget dette for oppfølging av staben' + email_title: 'Et innlegg i "%{title}" krever oppfølging av staben' email_body: "%{link}\n\n%{message}" bookmark: title: 'Bokmerke' description: 'Bokmerk dette innlegget' + short_description: 'Lag bokmerke for dette innlegget' long_form: 'bokmerket dette innlegget' like: title: 'Lik' description: 'Liker dette innlegget' + short_description: 'Lik dette innlegget' long_form: 'likte dette' vote: title: 'Stem' description: 'Stem på dette innlegget' + short_description: 'Stem på dette innlegget' long_form: 'stemte for dette innlegget' user_activity: + no_default: + self: "Du har ingen aktivitet enda." + others: "Ingen aktivitet." no_bookmarks: + self: "Du har ingen bokmerker, hvis du lager bokmerker for innlegg er det lettere å finne dem igjen senere." others: "Ingen bokmerker." no_likes_given: self: "Du har ikke likt noen innlegg." others: "Ingen likte innlegg. " + no_replies: + self: "Du har ikke svart på noen innlegg." + others: "Ingen svar." topic_flag_types: spam: title: 'Spam' @@ -510,10 +712,12 @@ nb_NO: long_form: 'markerte dette som upassende' notify_moderators: title: "Noe annet" + description: 'Emnet krever oppfølging av staben basert på retningslinjene, brukeravtale, eller en annen grunn ikke i listen over.' long_form: 'Markert for mederering' email_title: 'Tråden "%{title}" krever oppmerksomhet fra en moderator' email_body: "%{link}\n\n%{message}" flagging: + you_must_edit: '

    Innlegget ditt ble flagget av samfunnet. Vennligst sjekk meldingene dine.

    ' user_must_edit: '

    Dette innlegget ble rapportert av gemenskapen og er midlertidig skjult.

    ' archetypes: regular: @@ -523,6 +727,11 @@ nb_NO: message: make: "Denne tråden er nå et banner. Det vil vises øverst på hver side til brukeren lukker det." remove: "Denne tråden er ikke lenger et banner. Det vil ikke lenger vises øverst på hver side." + unsubscribed: + title: "Avmeldt!" + description: "%{email} er avmeldt. For å endre på oppsettet for e-post kan du besøke brukerinnstilingene." + topic_description: "For å melde deg på %{link} igjen, bruk varslingskontrollene til høyre for eller i bunnen av emnet." + private_topic_description: "For å melde deg på igjen, bruk varslingskontrollene til høyre for eller i bunnen av emnet." unsubscribe: title: "Avmeld" stop_watching_topic: "Slutt å følge denne tråden, %{link}" @@ -531,12 +740,22 @@ nb_NO: mailing_list_mode: "Slå av e-postlistemodus" disable_digest_emails: "Slutt å sende meg oppsummerings-eposter" all: "Ikke send meg noen e-poster fra %{sitename}" + different_user_description: "Du er allerede logget inn som en annen bruker enn den vi sendte e-posten til. Vennligst logg ut eller bytt til anonym modus før du prøver igjen." + not_found_description: "Beklager, vi klarte ikke finne denne avmeldingen. Det kan tenkes lenken i e-posten har gått ut på dato?" log_out: "Logg ut" user_api_key: + title: "Autoriser tilgang fra applikasjon" + authorize: "Autoriser" read: "les" read_write: "les/skriv" + description: "\"%{application_name}\" ber om følgende tilgang til kontoen din:" + no_trust_level: "Beklager, du har ikke det nødvendige tillitsnivået for tilgang til API for brukere" + generic_error: "Beklager, vi kan ikke utstede API nøkler for brukere, denne funksjonen kan være deaktivert av administratoren" scopes: message_bus: "Sanntidsoppdateringer" + notifications: "Les og rydd varsler" + push: "Push varslinger til eksterne tjenester " + session_info: "Les informasjon om brukersesjon" read: "Les alt" write: "Skriv alt" reports: @@ -545,9 +764,22 @@ nb_NO: xaxis: "Dag" yaxis: "Antall besøk" signups: - title: "nye brukere" xaxis: "Dag" - yaxis: "Antall nye brukere" + new_contributors: + title: "Nye Bidragsytere" + xaxis: "Dag" + yaxis: "Antall nye bidragsytere" + description: "Antall brukere som skrev sitt første innlegg i denne perioden" + dau_by_mau: + title: "DAB/MAB" + xaxis: "Dag" + yaxis: "DAB/MAB" + description: "Antall medlemmer som logget inn siste døgn delt på antall brukere som logget inn siste måned – returnerer en % som indikerer samfunnets evne til å engasjere brukere. Sikt mot >30%." + daily_engaged_users: + title: "Daglige Engasjerte Brukere" + xaxis: "Dag" + yaxis: "Engasjerte Brukere" + description: "Antall brukere som har likt eller skrevet innlegg siste døgn" profile_views: title: "Visninger av brukerprofil" xaxis: "Dag" @@ -556,10 +788,12 @@ nb_NO: title: "Tråder" xaxis: "Dag" yaxis: "Antall nye tråder" + description: "Nye emner opprettet i denne perioden" posts: title: "Innlegg" xaxis: "Dag" yaxis: "Antall nye innlegg" + description: "Nye innlegg opprettet i denne perioden" likes: title: "Likes" xaxis: "Dag" @@ -580,11 +814,31 @@ nb_NO: title: "Brukere per tillitsnivå" xaxis: "Tillitsnivå" yaxis: "Antall brukere" + users_by_type: + title: "Brukere per Type" + xaxis: "Type" + yaxis: "Antall Brukere" + xaxis_labels: + admin: Admin + moderator: Moderator + suspended: Utestengt + silenced: Dempet + trending_search: + title: Søketrender + labels: + term: Uttrykk + searches: Søk + click_through: Klikkrate emails: title: "Emailer sendt" xaxis: "Dag" yaxis: "Antall emailer" user_to_user_private_messages: + title: "Bruker-til-Bruker (ekskludert svar)" + xaxis: "Dag" + yaxis: "Antall meldinger" + user_to_user_private_messages_with_replies: + title: "Bruker-til-Bruker (med svar)" xaxis: "Dag" yaxis: "Antall meldinger" system_private_messages: @@ -629,7 +883,9 @@ nb_NO: page_view_crawler_reqs: title: "Web crawlere" xaxis: "Dag" + yaxis: "Sidevisninger fra Søkeroboter" page_view_total_reqs: + title: "Sidevisninger" xaxis: "Dag" yaxis: "Totalt antall sidevisninger" page_view_logged_in_mobile_reqs: @@ -637,7 +893,9 @@ nb_NO: xaxis: "Dag" yaxis: "Sidevisninger på mobil av innloggede" page_view_anon_mobile_reqs: + title: "Anonyme Sidevisninger" xaxis: "Dag" + yaxis: "Mobile Anonyme Sidevisninger" http_background_reqs: title: "Bakgrunn" xaxis: "Dag" @@ -674,39 +932,112 @@ nb_NO: title: "Brukerbesøk" xaxis: "Dag" yaxis: "Antall besøk" + web_crawlers: + title: "Forespørsler fra Søkeroboter" + xaxis: "Brukeragent" + yaxis: "Sidevisninger" dashboard: rails_env_warning: "Serveren din kjører i %{env] modus." host_names_warning: "Din config/database.yml-fil bruker forvalgt lokalvert-vertsnavn. Oppdater det til å bruke din sides vertsnavn." + gc_warning: 'Serveren din bruker standardinstillingene for garbage collection i Ruby, dette gir ikke den beste ytelsen. Les dette emnet om hvordan man optimaliserer ytelse: Tuning Ruby and Rails for Discourse.' + sidekiq_warning: 'Sidekiq kjører ikke. Mange oppgaver, som å sende e-post, kjøres i bakgrunnen av sidekiq. Vennligst verifiser at minst én sidekiq-prosess kjører. Lær mer om Sidekiq her.' + queue_size_warning: 'Antallet jobber som står i kø er %{queue_size}, som er høyt. Dette kan være en indikasjon på at Sidekiq-prosessen(e) har et problem, eller det kan tenkes du bare trenger flere samtidige Sidekiq-arbeidere.' memory_warning: 'Serveren din kjører med mindre enn 1 GB med minne. Minst 1 GB RAM er anbefalt.' + google_oauth2_config_warning: 'Denne serveren er konfigurert for å tillate innmelding og innlogging med Google OAuth2 (enable_google_oauth2_logins), men verdiene for klientid og klienthemmelighet er ikke satt. Gå til Instillingene for nettstedet og oppdater dem. Les denne guiden for å lære mer.' + facebook_config_warning: 'Denne serveren er konfigurert for å tillate innmelding og innlogging med Facebook (enable_facebook_logins), men verdiene for app-id og app-hemmelighet er ikke satt. Gå til Instillingene for nettstedet og oppdater dem. Les denne guiden for å lære mer.' + twitter_config_warning: 'Denne serveren er konfigurert for å tillate innmelding og innlogging med Twitter (enable_twitter_logins), men verdiene for nøkkel og hemmelighet er ikke satt. Gå til Instillingene for nettstedet og oppdater dem. Les denne guiden for å lære mer.' + github_config_warning: 'Denne serveren er konfigurert for å tillate innmelding og innlogging med GitHub (enable_github_logins), men verdiene for klientid og hemmelighet er ikke satt. Gå til Instillingene for nettstedet og oppdater dem. Les denne guiden for å lære mer.' + s3_config_warning: 'Denne serveren er konfigurert for å tillate opplasting av filer til s3, men minst en av de følgende verdiene er ikke satt: s3_access_key_id, s3_secret_access_key, s3_use_iam_profile, eller s3_upload_bucket. Gå til Instillingene for nettstedet og oppdater dem. Les "How to set up image uploads to S3?" for å lære mer.' + s3_backup_config_warning: 'Denne serveren er konfigurert for å sende backup til s3, men minst en av de følgende verdiene er ikke satt: s3_access_key_id, s3_secret_access_key, s3_use_iam_profile, eller s3_backup_bucket. Gå til Instillingene for nettstedet og oppdater dem. Les "How to set up image uploads to S3?" for å lære mer.' + image_magick_warning: 'Denne serveren er konfigurert for å lage miniatyrer for store bilder, men ImageMagick er ikke installert. Installer ImageMagick via operativsystemets pakkehåndtering eller last ned den siste versjonen.' + failing_emails_warning: 'Det er %{num_failed_jobs} e-postjobber som har feilet. Sjekk instillingene i app.yml og verifiser at serverinstillingene for e-post er riktige. Se de feilede jobbene i Sidekiq.' + subfolder_ends_in_slash: "Oppsettet av undermappe er feil; variablen DISCOURSE_RELATIVE_URL_ROOT slutter med en skråstrek." + email_polling_errored_recently: + one: Henting av e-post har generert en feil de siste 24 timene. Se i loggene for mer detaljer. + other: Henting av e-post har generert %{count} feil de siste 24 timene. Se i loggene for mer detaljer. + missing_mailgun_api_key: "Serveren er konfigurert til å sende e-post via Mailgun men du har ikke satt API-nøkkelen som brukes til å verifisere webhook meldinger." + bad_favicon_url: "Favicon filen blir ikke lastet inn. Sjekk instillingen for favicon_url i Instillingene for nettstedet." + poll_pop3_timeout: "Tilkoblingen til POP3 serveren får timeout. Vi får ikke hentet innkommende e-post. Vennligst sjekk instillingene for POP3 eller leverandøren av posttjenesten." + poll_pop3_auth_error: "Tilkoblingen til POP3 serveren feiler på grunn av problemer med autentisering. Vennligst sjekk POP3 instillingene. " + force_https_warning: "Nettstedet ditt bruker SSL. Men `force_https` er ikke aktivert enda i instillingene." site_settings: censored_words: "Ord som automatisk vil bli erstattet med ■■■■" delete_old_hidden_posts: "Slett automatisk skjulte innlegg som har vært skjult i mer enn 30 dager." + default_locale: "Standardspråket for denne instansen av Discourse" allow_user_locale: "Tillat brukere å velge eget språk" + set_locale_from_accept_language_header: "sett språket i grensesnittet for anonyme brukere basert på hva nettleseren deres rapporterer. (EKSPERIMENTELL, fungerer ikke med anonym cache) " + support_mixed_text_direction: "Tillat blanding av skriftspråk som bruker venstre-til-høyre og høyre-til-venstre." min_post_length: "Minimum tillatt lengde for innlegg i tegn" min_first_post_length: "Minimum tillatt lengde på for teksten i første innlegg" + min_personal_message_post_length: "Minste lengde i antall tegn for en melding" max_post_length: "Maksimum tillatt lengde for innlegg i tegn" + topic_featured_link_enabled: "Tillat publisering av lenker som emner." + show_topic_featured_link_in_digest: "Vis den fremhevede lenken fra et emne i e-postsammendrag." min_topic_title_length: "Minimum tillatt lengde for tittel i tegn" max_topic_title_length: "Maksimum tillatt lengde for innlegg i tegn" + min_personal_message_title_length: "Minste lengde i antall tegn for en meldingstittel" + max_emojis_in_title: "Maksimalt antall emojier i en emnetittel" min_search_term_length: "Minimum lengde på søkeord i tegn" + search_tokenize_chinese_japanese_korean: "Tving søk til å tokenisere Kinesisk/Japansk/Koreansk selv på nettsteder uten KJK" + search_prefer_recent_posts: "Hvis søking er tregt på et stort forum, vil dette valget forsøke å søke i en index av de nyeste innleggene først" + search_recent_posts_size: "Hvor mange innlegg som beholdes i indeksen" + log_search_queries: "Logg søkeord som benyttes av brukerne" + search_query_log_max_size: "Maksimalt antall søkeord som beholdes" + allow_uncategorized_topics: "Tillat opprettelse av ukategoriserte emner. ADVARSEL: Hvis det finnes ukategoriserte emner, må du sette en kategori på dem før du skrur denne instillingen av." allow_duplicate_topic_titles: "Tillat flere tråder med identisk tittel." unique_posts_mins: "Hvor mange minutter før en bruker kan lage et innlegg med det samme innholdet igjen" educate_until_posts: "Når brukeren begynner å skrive sine første (n) innlegg, vis pop-up med opplæringspanelet for nye brukere i redigeringspanelet." title: "Navnet på denne siden, slik du vil ha det i title-taggen." site_description: "Beskriv siden med en setning, vil brukes i beskrivelses-merkelappen." + contact_email: "E-postadresser for nøkkelpersonen ansvarlig for dette nettstedet. Brukes for kritiske varsler, i tillegg til på /about kontaktskjema for saker som haster." contact_url: "Kontakt-URL for siden. Brukes på /om siden." crawl_images: "Hent bilder fra ekstern URL for å sette inn korrekt høyde og bredde." 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)" + download_remote_images_max_days_old: "Ikke last ned eksterne bilder for innlegg som er eldre enn dette antall dager." disabled_image_download_domains: "Eksterne bilder vil aldri bli lastet ned fra disse domenene (pipe-separert liste)." editing_grace_period: "(n) sekunder etter publisering vil redigering ikke opprette en ny versjon i redigeringsloggen." + editing_grace_period_max_diff: "Maksimalt antall tegn for en endring utført i nådeperioden, hvis antallet overskrides lagres en ny revisjon av innlegget (tillitsnivå 0 og 1)" + editing_grace_period_max_diff_high_trust: "Maksimalt antall tegn for en endring utført i nådeperioden, hvis antallet overskrides lagres en ny revisjon av innlegget (tillitsnivå 2 og opp)" + staff_edit_locks_post: "Innlegg vil bli sperret for redigering av brukere hvis de har vært redigert av staben " post_edit_time_limit: "Forfatteren kan redigere eller slette innleggene sine (n) minutter etter opprettelse. Sett til 0 for uendelig." edit_history_visible_to_public: "La alle se tidligere versjoner av et redigert innlegg. Hvis det er slått av, kan kun staben 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." max_image_width: "Maksimal thumbnail bredde for bilder i et innlegg" max_image_height: "Maksimal thumbnail høyde for bilder i et innlegg" + fixed_category_positions: "Hvis denne er valgt kan du manuelt bestemme rekkefølgen i listen over kategorier. Ellers vil kategoriene sorteres automatisk basert på aktivitet." + fixed_category_positions_on_create: "Hvis denne er valgt vil den fastsatte rekkefølgen på kategorier også gjelde for dialogboksen når man lager nye emner (krever fixed_category_positions)." + add_rel_nofollow_to_user_content: "Legg til rel nofollow på alle lenker som publiseres av brukere, bortsett fra interne lenker (inkludert foreldredomener). Hvis du endrer denne, må du rebake alle innlegg med: \"rake posts:rebake\"" + exclude_rel_nofollow_domains: "En liste over domener hvor nofollow ikke skal legges til i lenker. example.com vil automatisk også tillate sub.example.com. Som et minimum bør du legge til dette nettstedets domene slik at søkeroboter klarer å finne alt innholdet. Hvis andre deler av nettstedet ditt ligger under forskjellige domener bør de også legges til." post_excerpt_maxlength: "Maksimal lengde på utdrag eller oppsummering av innlegg." + show_pinned_excerpt_mobile: "Vis utdrag fra festede emner i mobil visning." + show_pinned_excerpt_desktop: "Vis utdrag fra festede emner i desktop visning." + post_onebox_maxlength: "Maksimal lengde på et onebox Discourse innlegg i antall tegn." + onebox_domains_blacklist: "En liste over domener som aldri vil bli forsøkt oneboxet." + inline_onebox_domains_whitelist: "En liste over domener hvor onebox brukes i miniatyrstørrelse hvis lenken ikke har en tittel" + enable_inline_onebox_on_all_domains: "Ignorer inline_onebox_domain_whitelist innstillingen og tillat inline onebox på alle domener." + max_oneboxes_per_post: "Maksimalt antall oneboxer i hvert innlegg." + logo_url: "Bildet som skal brukes som logo øverst til venstre på nettstedet, må være en bred rektangel. Hvis instillingen er blank brukes kun tittelteksten." + digest_logo_url: "Alternativt bilde for logoen som brukes i toppen av nettstedets oppsummeringer på e-post. Må være et bredt rektangulært bilde. Bør ikke være i SVG format. Hvis instillingen er blank, brukes `logo_url` i stedet." + logo_small_url: "Den lille logoen øverst til venstre på nettstedet, bør være et kvadratisk bilde. Dette bildet brukes når man blar nedover på sidene. Hvis den er blank brukes et symbol for 'Hjem' i stedet." + favicon_url: "Bildet som skal være favicon for nettstedet, se http://en.wikipedia.org/wiki/Favicon, for å fungere via et CDN må filen være i png-format" + mobile_logo_url: "URL for tilpasset logo som skal brukes på den mobile versjonen av nettstedet. Hvis blank, brukes `logo_url` i stedet, for eksempel: http://example.com/uploads/default/logo.png " + large_icon_url: "Bildet som skal brukes som logo/splash på Android. Anbefalt størrelse er 512x512 piksler." apple_touch_icon_url: "Ikon brukt på Apple touch enheter. Anbefalt størrelse er 144px x 144px." + notification_email: "Adressen som skal brukes som avsender: på alle viktige system e-poster. Domenet som spesifiseres her må ha SPF, DKIM og reverse PTR record satt korrekt for at e-post skal nå frem." + email_custom_headers: "En liste over tilpassede e-posthoder med pipe-tegn mellom hvert element" + email_subject: "Tilpasset formatering av emnefeltet i standard e-poster. Se også https://meta.discourse.org/t/customize-subject-format-for-standard-emails/20801 " + force_https: "Tving dette nettstedet til å bare tillate HTTPS. ADVARSEL: Du må IKKE aktivere dette valget før du har verifisert at HTTPS er riktig satt opp og fungerer absolutt alle steder! Har du sjekket CDN, alle sosiale loginmetoder og eventuelle eksterne ressurser for å sikre at de også er kompatible med HTTPS?" + same_site_cookies: "Bruk Same-Site cookies/kapsler, de eliminerer alle former for Cross Site Request Forgery på nettlesere som støtter dem (Lax eller Strict). Avarsel: Strict vil kun fungere på nettsteder som tvinger innlogging og bruker SSO." + summary_score_threshold: "Minste score for at et innlegg skal inkluderes i 'Sammendrag for Emnet'" + summary_posts_required: "Minste antall innlegg før 'Sammendrag for Emnet' aktiveres" + summary_likes_required: "Minste antall 'likes' i et emne før 'Sammendrag for Emnet' aktiveres" summary_max_results: "Maksimalt antall innlegg som returneres av 'Oppsummer denne tråden'" + num_spam_flags_to_silence_new_user: "Hvis en ny brukers innlegg flagges som spam av minst num_users_to_silence_new_user forskjellige brukere, skjul den nye brukerens innlegg og stans fremtidige innlegg. 0 for å deaktivere." + num_users_to_silence_new_user: "Hvis en ny brukers innlegg flagges som spam num_spam_flags_to_silence_new_user ganger av dette antallet brukere, skjul den nye brukerens innlegg og stans fremtidige innlegg. 0 for å deaktivere." + num_tl3_flags_to_silence_new_user: "Hvis en ny brukers innlegg flagges av num_tl3_users_to_silence_new_user forskjellige brukere med tillitsnivå 3, skjul alle den nye brukerens innlegg og stans fremtidige innlegg. 0 for å deaktivere." + num_tl3_users_to_silence_new_user: "Hvis en ny brukers innlegg flagges num_tl3_flags_to_silence_new_user ganger fra dette antallet brukere med tillitsnivå 3, skjul alle den nye brukerens innlegg og stans fremtidige innlegg. 0 for å deaktivere." + notify_mods_when_user_silenced: "Hvis en bruker har blitt automatisk dempet, send en melding til alle moderatorene." allow_moderators_to_create_categories: "Tillat moderatorer å opprette nye kategorier" send_welcome_message: "Send alle nye brukere en velkomstmelding med en rask startveileder." topics_per_period_in_top_summary: "Antall tråder som vises i standard oppsummering av mest populære tråder." @@ -730,6 +1061,8 @@ nb_NO: faq_url: "Hvis du har O-S-S på et annet nettsted du gjerne vil bruke, skriv inn nettadressen her." tos_url: "Dersom du har et bruksvilkår-dokument et annet sted som du vil bruke, skriv inn den fullstendige URL-en her." privacy_policy_url: "Dersom du har en personvernerklæring et annet sted som du vil bruke, skriv inn den fullstendige URL-en her." + auto_silence_fast_typers_on_first_post: "Demp brukere automatisk hvis de skriver innlegg raskere enn min_first_post_typing_time" + auto_silence_fast_typers_max_trust_level: "Maksimalt tillitsnivå for automatisk demping av raske innlegg" delete_user_max_post_age: "Ikke tillatt å slette brukere hvor deres første innlegg er mer enn (x) dager gamle." email_editable: "Tillat brukere å endre e-postadressen sin etter registrering." digest_topics: "Maksimalt antall populære tråder som skal vises i oppsummerings-e-posten." diff --git a/config/locales/server.nl.yml b/config/locales/server.nl.yml index dcb64e44af..3f10fed8e2 100644 --- a/config/locales/server.nl.yml +++ b/config/locales/server.nl.yml @@ -660,9 +660,7 @@ nl: xaxis: "Dag" yaxis: "Aantal bezoeken" signups: - title: "Nieuwe gebruikers" xaxis: "Dag" - yaxis: "Aantal nieuwe gebruikers" profile_views: title: "Gebruikersprofielweergaven" xaxis: "Dag" diff --git a/config/locales/server.pl_PL.yml b/config/locales/server.pl_PL.yml index 0dc4535086..280b002edc 100644 --- a/config/locales/server.pl_PL.yml +++ b/config/locales/server.pl_PL.yml @@ -727,9 +727,7 @@ pl_PL: xaxis: "Dzień" yaxis: "Liczba wizyt" signups: - title: "Nowi Użytkownicy" xaxis: "Dzień" - yaxis: "Liczba nowych użytkowników" profile_views: title: "Wyświetlenia profilu użytkownika" xaxis: "Dzień" diff --git a/config/locales/server.pt.yml b/config/locales/server.pt.yml index ac24c95070..30a3b9f9c2 100644 --- a/config/locales/server.pt.yml +++ b/config/locales/server.pt.yml @@ -606,9 +606,7 @@ pt: xaxis: "Dia" yaxis: "Número de visitas" signups: - title: "Novos Utilizadores" xaxis: "Dia" - yaxis: "Número de novos utilizadores" profile_views: title: "Vistas do Perfil de Utilizador" xaxis: "Dia" diff --git a/config/locales/server.pt_BR.yml b/config/locales/server.pt_BR.yml index 4293cda920..b8b7b423a6 100644 --- a/config/locales/server.pt_BR.yml +++ b/config/locales/server.pt_BR.yml @@ -615,9 +615,7 @@ pt_BR: xaxis: "Dia" yaxis: "Número de visitas" signups: - 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" diff --git a/config/locales/server.ro.yml b/config/locales/server.ro.yml index e863cddca4..4470c411aa 100644 --- a/config/locales/server.ro.yml +++ b/config/locales/server.ro.yml @@ -610,9 +610,7 @@ ro: xaxis: "Zi" yaxis: "Număr de vizite" signups: - title: "Utilizatori noi" xaxis: "Zi" - yaxis: "Număr de noi utilizatori" profile_views: title: "Vizualizări profil utilizator" xaxis: "Zi" diff --git a/config/locales/server.ru.yml b/config/locales/server.ru.yml index cc5caa0345..c03072a3b2 100644 --- a/config/locales/server.ru.yml +++ b/config/locales/server.ru.yml @@ -654,9 +654,7 @@ ru: xaxis: "Дата" yaxis: "Количество визитов" signups: - title: "Регистрации" xaxis: "Дата" - yaxis: "Количество регистраций" profile_views: title: "Просмотры профилей" xaxis: "Дата" diff --git a/config/locales/server.sk.yml b/config/locales/server.sk.yml index 8581e71d63..8bfca02ab0 100644 --- a/config/locales/server.sk.yml +++ b/config/locales/server.sk.yml @@ -618,9 +618,7 @@ sk: 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ň" diff --git a/config/locales/server.sq.yml b/config/locales/server.sq.yml index 5dd0eadf35..71baba1a3d 100644 --- a/config/locales/server.sq.yml +++ b/config/locales/server.sq.yml @@ -399,9 +399,7 @@ sq: xaxis: "Ditë" yaxis: "Numri i vizitave" signups: - title: "Përdorues të rinj" xaxis: "Ditë" - yaxis: "Numri i përdoruesve të rinj" profile_views: xaxis: "Ditë" topics: diff --git a/config/locales/server.sv.yml b/config/locales/server.sv.yml index 3e40f05ef1..54ba030b12 100644 --- a/config/locales/server.sv.yml +++ b/config/locales/server.sv.yml @@ -561,9 +561,7 @@ sv: xaxis: "Dag" yaxis: "Antal besök" signups: - title: "Nya användare" xaxis: "Dag" - yaxis: "Antalet nya användare" profile_views: title: "Användarprofilvisningar" xaxis: "Dag" diff --git a/config/locales/server.te.yml b/config/locales/server.te.yml index 768b665ea1..4b8dde9331 100644 --- a/config/locales/server.te.yml +++ b/config/locales/server.te.yml @@ -347,9 +347,7 @@ te: xaxis: "రోజు" yaxis: "దర్శనాల సంఖ్య" signups: - title: "కొత్త వినియోగదారులు" xaxis: "రోజు" - yaxis: "కొత్త సభ్యుల సంఖ్య" topics: title: "విషయాలు" xaxis: "రోజు" diff --git a/config/locales/server.tr_TR.yml b/config/locales/server.tr_TR.yml index 40ae373422..5c970ce234 100644 --- a/config/locales/server.tr_TR.yml +++ b/config/locales/server.tr_TR.yml @@ -512,9 +512,7 @@ tr_TR: xaxis: "Gün" yaxis: "Ziyaret sayısı" signups: - 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" diff --git a/config/locales/server.uk.yml b/config/locales/server.uk.yml index 58e448dfa8..daacd8082f 100644 --- a/config/locales/server.uk.yml +++ b/config/locales/server.uk.yml @@ -239,7 +239,6 @@ uk: yaxis: "Кількість відвідин" signups: xaxis: "День" - yaxis: "Кількість нових користувачів" topics: title: "Теми" xaxis: "День" diff --git a/config/locales/server.ur.yml b/config/locales/server.ur.yml index a12687d07d..c68947603c 100644 --- a/config/locales/server.ur.yml +++ b/config/locales/server.ur.yml @@ -746,9 +746,7 @@ ur: xaxis: "دن" yaxis: "وِزِٹس کی تعداد" signups: - title: "نئے صارفین" xaxis: "دن" - yaxis: "نئے صارفین کی تعداد" profile_views: title: "صارف پروفائل وِیوز" xaxis: "دن" diff --git a/config/locales/server.vi.yml b/config/locales/server.vi.yml index feec5266ba..12bb1ad386 100644 --- a/config/locales/server.vi.yml +++ b/config/locales/server.vi.yml @@ -27,14 +27,14 @@ vi: posts: "bài viết" loading: "Đang tải" log_in: "Đăng nhập" - disable_remote_images_download_reason: "Không thể tải ảnh về máy chủ vì thiếu dung lượng." + disable_remote_images_download_reason: "Không thể tải ảnh về máy chủ vì không dung lượng lưu trữ." anonymous: "Ẩn danh" emails: incoming: - show_trimmed_content: "Hiện nội dung đã cắt" + show_trimmed_content: "Hiện nội dung đã ẩn" errors: - empty_email_error: "Xảy ra khi thư nguồn hệ thống nhận được trống." - no_message_id_error: "Xảy ra khi thư không có tiêu đề." + empty_email_error: "Xảy ra khi hệ thống nhận được một thư rỗng." + no_message_id_error: "Xảy ra khi thư không có phần 'Message-Id'." auto_generated_email_error: "Xảy ra khi tiêu đề 'ưu tiên' được đặt là: danh sách, rác, theo lô hoặc tự động trả lời, hoặc khi có tiêu đề khác bao gồm: tự động gửi, tự động trả lời hoặc tự động tạo." inactive_user_error: "Xảy ra khi người gửi không hoạt động." bad_destination_address: "Xảy ra khi không có địa chỉ email trong các trường Tới/Cc/Bcc khớp với địa chỉ email đến đã được cấu hình." @@ -449,9 +449,7 @@ vi: 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" diff --git a/config/locales/server.zh_CN.yml b/config/locales/server.zh_CN.yml index d40e15c65a..ddd63933e7 100644 --- a/config/locales/server.zh_CN.yml +++ b/config/locales/server.zh_CN.yml @@ -646,9 +646,7 @@ zh_CN: xaxis: "天" yaxis: "访问量" signups: - title: "新用户" xaxis: "天" - yaxis: "新用户数" profile_views: title: "查看用户资料" xaxis: "天" diff --git a/config/locales/server.zh_TW.yml b/config/locales/server.zh_TW.yml index 58a3a1e02f..f2ac0db693 100644 --- a/config/locales/server.zh_TW.yml +++ b/config/locales/server.zh_TW.yml @@ -584,9 +584,7 @@ zh_TW: xaxis: "天" yaxis: "瀏覽量" signups: - title: "新用戶" xaxis: "天" - yaxis: "新用戶數量" profile_views: title: "查看用戶資料" xaxis: "天" diff --git a/config/locales/transliterate.bg.yml b/config/locales/transliterate.bg.yml new file mode 100644 index 0000000000..4c8c61c289 --- /dev/null +++ b/config/locales/transliterate.bg.yml @@ -0,0 +1,71 @@ +# encoding: utf-8 +# This file contains content for the i18n transliteration map from +# Russian Cyrillic to ASCII (ISO-9:1995 / GOST 7.79-2000, table B) +# +# To validate this YAML file after you change it, please paste it into +# http://yamllint.com/ + +bg: + i18n: + transliterate: + rule: + А: A + а: a + Б: B + б: b + В: V + в: v + Г: G + г: g + Д: D + д: d + Е: E + е: e + Ж: Zh + ж: zh + З: Z + з: z + И: I + и: i + Й: J + й: j + К: K + к: k + Л: L + л: l + М: M + м: m + Н: N + н: n + О: O + о: o + П: P + п: p + Р: R + р: r + С: S + с: s + Т: T + т: t + У: U + у: u + Ф: F + ф: f + Х: H + х: h + Ц: C + ц: c + Ч: Ch + ч: ch + Ш: Sh + ш: sh + Щ: Sht + щ: sht + Ъ: y + ъ: y + Ь: y + ь: y + Ю: Yu + ю: yu + Я: Ya + я: ya diff --git a/config/routes.rb b/config/routes.rb index cebaf579dc..8765881d63 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -103,6 +103,7 @@ Discourse::Application.routes.draw do put "approve-bulk" => "users#approve_bulk" delete "reject-bulk" => "users#reject_bulk" end + delete "penalty_history", constraints: AdminConstraint.new put "suspend" put "delete_all_posts" put "unsuspend" @@ -213,9 +214,10 @@ Discourse::Application.routes.draw do # They have periods in their URLs often: get 'site_texts' => 'site_texts#index' - get 'site_texts/(:id)' => 'site_texts#show', constraints: { id: /[\w.\-\+]+/i } - put 'site_texts/(:id)' => 'site_texts#update', constraints: { id: /[\w.\-\+]+/i } - delete 'site_texts/(:id)' => 'site_texts#revert', constraints: { id: /[\w.\-\+]+/i } + get 'site_texts/:id' => 'site_texts#show', constraints: { id: /[\w.\-\+]+/i } + put 'site_texts/:id.json' => 'site_texts#update', constraints: { id: /[\w.\-\+]+/i } + put 'site_texts/:id' => 'site_texts#update', constraints: { id: /[\w.\-\+]+/i } + delete 'site_texts/:id' => 'site_texts#revert', constraints: { id: /[\w.\-\+]+/i } get 'email_templates' => 'email_templates#index' get 'email_templates/(:id)' => 'email_templates#show', constraints: { id: /[0-9a-z_.]+/ } diff --git a/config/site_settings.yml b/config/site_settings.yml index def3802eaf..6686036b76 100644 --- a/config/site_settings.yml +++ b/config/site_settings.yml @@ -717,8 +717,15 @@ email: digest_topics: default: 5 min: 1 - digest_posts: 3 - digest_other_topics: 5 + max: 20 + digest_posts: + default: 5 + min: 0 + max: 20 + digest_other_topics: + default: 5 + min: 0 + max: 20 suppress_digest_email_after_days: default: 365 digest_suppress_categories: @@ -1317,6 +1324,8 @@ search: locale_default: zh_CN: 2 zh_TW: 2 + ko: 2 + ja: 2 search_tokenize_chinese_japanese_korean: false search_prefer_recent_posts: false diff --git a/db/migrate/20180519053933_delete_confirm_old_email_template_overrides.rb b/db/migrate/20180519053933_delete_confirm_old_email_template_overrides.rb new file mode 100644 index 0000000000..f1383030db --- /dev/null +++ b/db/migrate/20180519053933_delete_confirm_old_email_template_overrides.rb @@ -0,0 +1,11 @@ +class DeleteConfirmOldEmailTemplateOverrides < ActiveRecord::Migration[5.1] + def up + execute "DELETE FROM translation_overrides WHERE translation_key = 'user_notifications.confirm_old_email.title'" + execute "DELETE FROM translation_overrides WHERE translation_key = 'user_notifications.confirm_old_email.subject_template'" + execute "DELETE FROM translation_overrides WHERE translation_key = 'user_notifications.confirm_old_email.text_body_template'" + end + + def down + raise ActiveRecord::IrreversibleMigration + end +end diff --git a/db/migrate/20180521190040_allow_null_ip_topic_link_click.rb b/db/migrate/20180521190040_allow_null_ip_topic_link_click.rb new file mode 100644 index 0000000000..b9f29e1aa8 --- /dev/null +++ b/db/migrate/20180521190040_allow_null_ip_topic_link_click.rb @@ -0,0 +1,10 @@ +class AllowNullIpTopicLinkClick < ActiveRecord::Migration[5.1] + def up + begin + Migration::SafeMigrate.disable! + change_column :topic_link_clicks, :ip_address, :inet, null: true + ensure + Migration::SafeMigrate.enable! + end + end +end diff --git a/db/migrate/20180521191418_allow_null_ip_user_profile_view.rb b/db/migrate/20180521191418_allow_null_ip_user_profile_view.rb new file mode 100644 index 0000000000..0f5b3795c1 --- /dev/null +++ b/db/migrate/20180521191418_allow_null_ip_user_profile_view.rb @@ -0,0 +1,25 @@ +class AllowNullIpUserProfileView < ActiveRecord::Migration[5.1] + def up + begin + Migration::SafeMigrate.disable! + change_column :user_profile_views, :ip_address, :inet, null: true + ensure + Migration::SafeMigrate.enable! + end + + remove_index :user_profile_views, + column: [:viewed_at, :ip_address, :user_profile_id], + name: :unique_profile_view_ip, + unique: true + remove_index :user_profile_views, + column: [:viewed_at, :user_id, :user_profile_id], + name: :unique_profile_view_user, + unique: true + add_index :user_profile_views, [:viewed_at, :user_id, :ip_address, :user_profile_id], + name: :unique_profile_view_user_or_ip, + unique: true + end + + def down + end +end diff --git a/lib/auth/github_authenticator.rb b/lib/auth/github_authenticator.rb index fa274b4e93..2d3f705cf3 100644 --- a/lib/auth/github_authenticator.rb +++ b/lib/auth/github_authenticator.rb @@ -41,7 +41,7 @@ class Auth::GithubAuthenticator < Auth::Authenticator # If there's existing user info with the given GitHub ID, that's all we # need to know. user = user_info.user - result.email = data[:email], + result.email = data[:email] result.email_valid = data[:email].present? else # Potentially use *any* of the emails from GitHub to find a match or diff --git a/lib/auth/google_oauth2_authenticator.rb b/lib/auth/google_oauth2_authenticator.rb index a280408193..e477c55edc 100644 --- a/lib/auth/google_oauth2_authenticator.rb +++ b/lib/auth/google_oauth2_authenticator.rb @@ -44,10 +44,6 @@ class Auth::GoogleOAuth2Authenticator < Auth::Authenticator def after_create_account(user, auth) data = auth[:extra_data] GoogleUserInfo.create({ user_id: user.id }.merge(data)) - if auth[:email_valid].to_s == 'true' && data[:email]&.downcase == user.email - EmailToken.confirm(user.email_tokens.first.token) - user.set_automatic_groups - end end def register_middleware(omniauth) diff --git a/lib/autospec/rspec_runner.rb b/lib/autospec/rspec_runner.rb index d09acd5450..34e4043df3 100644 --- a/lib/autospec/rspec_runner.rb +++ b/lib/autospec/rspec_runner.rb @@ -23,6 +23,7 @@ module Autospec watch(%r{^plugins/.*/discourse-markdown/.*\.js\.es6$}) { "spec/components/pretty_text_spec.rb" } watch(%r{^plugins/.*/spec/.*\.rb}) + watch(%r{^(plugins/.*/)plugin\.rb}) { |m| "#{m[1]}spec" } watch(%r{^(plugins/.*)/(lib|app)}) { |m| "#{m[1]}/spec/integration" } watch(%r{^(plugins/.*)/lib/(.*)\.rb}) { |m| "#{m[1]}/spec/lib/#{m[2]}_spec.rb" } diff --git a/lib/cooked_post_processor.rb b/lib/cooked_post_processor.rb index 4b8aa8c5f7..1dc0306dfb 100644 --- a/lib/cooked_post_processor.rb +++ b/lib/cooked_post_processor.rb @@ -257,7 +257,7 @@ class CookedPostProcessor return unless SiteSetting.crawl_images? || Discourse.store.has_been_uploaded?(url) @size_cache[url] = FastImage.size(absolute_url) - rescue Zlib::BufError, URI::InvalidURIError, URI::InvalidComponentError + rescue Zlib::BufError, URI::InvalidURIError, URI::InvalidComponentError, OpenSSL::SSL::SSLError # FastImage.size raises BufError for some gifs, leave it. end diff --git a/lib/email/processor.rb b/lib/email/processor.rb index b996dae629..6bac32fe3a 100644 --- a/lib/email/processor.rb +++ b/lib/email/processor.rb @@ -36,6 +36,7 @@ module Email def handle_failure(mail_string, e) message_template = case e when Email::Receiver::NoSenderDetectedError then return nil + when Email::Receiver::FromReplyByAddressError then return nil when Email::Receiver::EmptyEmailError then :email_reject_empty when Email::Receiver::NoBodyDetectedError then :email_reject_empty when Email::Receiver::UserNotFoundError then :email_reject_user_not_found diff --git a/lib/email/receiver.rb b/lib/email/receiver.rb index 06c9cb6761..09d6ca52fb 100644 --- a/lib/email/receiver.rb +++ b/lib/email/receiver.rb @@ -21,6 +21,7 @@ module Email class BouncedEmailError < ProcessingError; end class NoBodyDetectedError < ProcessingError; end class NoSenderDetectedError < ProcessingError; end + class FromReplyByAddressError < ProcessingError; end class InactiveUserError < ProcessingError; end class SilencedUserError < ProcessingError; end class BadDestinationAddress < ProcessingError; end @@ -107,6 +108,7 @@ module Email def process_internal raise BouncedEmailError if is_bounce? raise NoSenderDetectedError if @from_email.blank? + raise FromReplyByAddressError if is_from_reply_by_email_address? raise ScreenedEmailError if ScreenedEmail.should_block?(@from_email) user = find_user(@from_email) @@ -203,6 +205,10 @@ module Email true end + def is_from_reply_by_email_address? + Email::Receiver.reply_by_email_address_regex.match(@from_email) + end + def verp @verp ||= all_destinations.select { |to| to[/\+verp-\h{32}@/] }.first end @@ -723,9 +729,13 @@ module Email reply_addresses.flatten! reply_addresses.select!(&:present?) reply_addresses.map! { |a| Regexp.escape(a) } - reply_addresses.map! { |a| a.gsub(Regexp.escape("%{reply_key}"), "(\\h{32})") } - - /#{reply_addresses.join("|")}/ + reply_addresses.map! { |a| a.gsub("\+", "\+?") } + reply_addresses.map! { |a| a.gsub(Regexp.escape("%{reply_key}"), "(\\h{32})?") } + if reply_addresses.empty? + /$a/ # a regex that can never match + else + /#{reply_addresses.join("|")}/ + end end def group_incoming_emails_regex diff --git a/lib/file_store/s3_store.rb b/lib/file_store/s3_store.rb index 838e8ffbc6..483b41e02f 100644 --- a/lib/file_store/s3_store.rb +++ b/lib/file_store/s3_store.rb @@ -85,7 +85,8 @@ module FileStore def cdn_url(url) return url if SiteSetting.Upload.s3_cdn_url.blank? schema = url[/^(https?:)?\/\//, 1] - url.sub("#{schema}#{absolute_base_url}", SiteSetting.Upload.s3_cdn_url) + folder = @s3_helper.s3_bucket_folder_path.nil? ? "" : "#{@s3_helper.s3_bucket_folder_path}/" + url.sub("#{schema}#{absolute_base_url}/#{folder}", "#{SiteSetting.Upload.s3_cdn_url}/") end def cache_avatar(avatar, user_id) diff --git a/lib/final_destination.rb b/lib/final_destination.rb index f58b8a1888..c551715e6f 100644 --- a/lib/final_destination.rb +++ b/lib/final_destination.rb @@ -288,8 +288,7 @@ class FinalDestination end def log(log_level, message) - # blacklist 404 on gravatar.com - return if @status_code == 404 && @uri.hostname["gravatar.com"] + return if @status_code == 404 Rails.logger.public_send( log_level, diff --git a/lib/guardian/topic_guardian.rb b/lib/guardian/topic_guardian.rb index 0d75e290d8..d3b6052180 100644 --- a/lib/guardian/topic_guardian.rb +++ b/lib/guardian/topic_guardian.rb @@ -86,15 +86,15 @@ module TopicGuardian def can_delete_topic?(topic) !topic.trashed? && is_staff? && - !(Category.exists?(topic_id: topic.id)) && + !(topic.is_category_topic?) && !Discourse.static_doc_topic_ids.include?(topic.id) end def can_convert_topic?(topic) return false unless SiteSetting.enable_personal_messages? return false if topic.blank? - return false if topic && topic.trashed? - return false if Category.where("topic_id = ?", topic.id).exists? + return false if topic.trashed? + return false if topic.is_category_topic? return true if is_admin? is_moderator? && can_create_post?(topic) end diff --git a/lib/letter_avatar.rb b/lib/letter_avatar.rb index 93766c4b2d..cad64a83c5 100644 --- a/lib/letter_avatar.rb +++ b/lib/letter_avatar.rb @@ -105,12 +105,16 @@ class LetterAvatar end def cleanup_old - skip = File.basename(cache_path) - parent_path = File.dirname(cache_path) - Dir.entries(parent_path).each do |path| - unless ['.', '..'].include?(path) || path == skip - FileUtils.rm_rf(parent_path + "/" + path) + begin + skip = File.basename(cache_path) + parent_path = File.dirname(cache_path) + Dir.entries(parent_path).each do |path| + unless ['.', '..'].include?(path) || path == skip + FileUtils.rm_rf(parent_path + "/" + path) + end end + rescue Errno::ENOENT + # no worries, folder doesn't exists end end end diff --git a/lib/plugin/metadata.rb b/lib/plugin/metadata.rb index f9dfabc622..097845103d 100644 --- a/lib/plugin/metadata.rb +++ b/lib/plugin/metadata.rb @@ -50,6 +50,9 @@ class Plugin::Metadata "discourse-styleguide", "discourse-saved-searches", "discourse-user-card-badges", + "discourse-policy", + "discourse-github-linkback", + ]) FIELDS ||= [:name, :about, :version, :authors, :url, :required_version] diff --git a/lib/post_jobs_enqueuer.rb b/lib/post_jobs_enqueuer.rb index 898743e44a..4dde3b73af 100644 --- a/lib/post_jobs_enqueuer.rb +++ b/lib/post_jobs_enqueuer.rb @@ -26,7 +26,11 @@ class PostJobsEnqueuer private def enqueue_post_alerts - Jobs.enqueue(:post_alert, post_id: @post.id, options: @opts[:post_alert_options]) + Jobs.enqueue(:post_alert, + post_id: @post.id, + new_record: true, + options: @opts[:post_alert_options], + ) end def feature_topic_users @@ -41,10 +45,9 @@ class PostJobsEnqueuer TopicTrackingState.publish_unread(@post) if @post.post_number > 1 TopicTrackingState.publish_latest(@topic, @post.whisper?) - Jobs.enqueue_in( - SiteSetting.email_time_window_mins.minutes, - :notify_mailing_list_subscribers, - post_id: @post.id + Jobs.enqueue_in(SiteSetting.email_time_window_mins.minutes, + :notify_mailing_list_subscribers, + post_id: @post.id, ) end diff --git a/lib/post_revisor.rb b/lib/post_revisor.rb index efa718787d..d74e50dd95 100644 --- a/lib/post_revisor.rb +++ b/lib/post_revisor.rb @@ -190,6 +190,7 @@ class PostRevisor # WARNING: do not pull this into the transaction # it can fire events in sidekiq before the post is done saving # leading to corrupt state + QuotedPost.extract_from(@post) post_process_post update_topic_word_counts @@ -198,7 +199,6 @@ class PostRevisor grant_badge TopicLink.extract_from(@post) - QuotedPost.extract_from(@post) successfully_saved_post_and_topic end @@ -577,7 +577,7 @@ class PostRevisor def alert_users return if @editor.id == Discourse::SYSTEM_USER_ID - PostAlerter.new.after_save_post(@post) + Jobs.enqueue(:post_alert, post_id: @post.id) end def publish_changes diff --git a/lib/pretty_text.rb b/lib/pretty_text.rb index f157800e38..83001ce837 100644 --- a/lib/pretty_text.rb +++ b/lib/pretty_text.rb @@ -142,25 +142,13 @@ module PrettyText protect do context = v8 - paths = { - baseUri: Discourse::base_uri, - CDN: Rails.configuration.action_controller.asset_host, - } - - if SiteSetting.Upload.enable_s3_uploads - if SiteSetting.Upload.s3_cdn_url.present? - paths[:S3CDN] = SiteSetting.Upload.s3_cdn_url - end - paths[:S3BaseUrl] = Discourse.store.absolute_base_url - end - custom_emoji = {} Emoji.custom.map { |e| custom_emoji[e.name] = e.url } buffer = <<~JS __optInput = {}; __optInput.siteSettings = #{SiteSetting.client_settings_json}; - __paths = #{paths.to_json}; + __paths = #{paths_json}; __optInput.getURL = __getURL; __optInput.getCurrentUser = __getCurrentUser; __optInput.lookupAvatar = __lookupAvatar; @@ -215,10 +203,29 @@ module PrettyText baked end + def self.paths_json + paths = { + baseUri: Discourse::base_uri, + CDN: Rails.configuration.action_controller.asset_host, + } + + if SiteSetting.Upload.enable_s3_uploads + if SiteSetting.Upload.s3_cdn_url.present? + paths[:S3CDN] = SiteSetting.Upload.s3_cdn_url + end + paths[:S3BaseUrl] = Discourse.store.absolute_base_url + end + + paths.to_json + end + # leaving this here, cause it invokes v8, don't want to implement twice def self.avatar_img(avatar_template, size) protect do - v8.eval("__utils.avatarImg({size: #{size.inspect}, avatarTemplate: #{avatar_template.inspect}}, __getURL);") + v8.eval(<<~JS) + __paths = #{paths_json}; + __utils.avatarImg({size: #{size.inspect}, avatarTemplate: #{avatar_template.inspect}}, __getURL); + JS end end @@ -227,7 +234,10 @@ module PrettyText set = SiteSetting.emoji_set.inspect protect do - v8.eval("__performEmojiUnescape(#{title.inspect}, { getURL: __getURL, emojiSet: #{set} })") + v8.eval(<<~JS) + __paths = #{paths_json}; + __performEmojiUnescape(#{title.inspect}, { getURL: __getURL, emojiSet: #{set} }); + JS end end diff --git a/lib/s3_helper.rb b/lib/s3_helper.rb index 9dadd71de3..8ead961b20 100644 --- a/lib/s3_helper.rb +++ b/lib/s3_helper.rb @@ -4,7 +4,7 @@ class S3Helper class SettingMissing < StandardError; end - attr_reader :s3_bucket_name + attr_reader :s3_bucket_name, :s3_bucket_folder_path def initialize(s3_bucket_name, tombstone_prefix = '', options = {}) @s3_options = default_s3_options.merge(options) @@ -131,7 +131,7 @@ class S3Helper end def list(prefix = "") - s3_bucket.objects(prefix: @s3_bucket_folder_path.to_s + prefix) + s3_bucket.objects(prefix: "#{@s3_bucket_folder_path}/#{prefix}") end def tag_file(key, tags) diff --git a/lib/scheduler/defer.rb b/lib/scheduler/defer.rb index 37116f58ed..f8f37090bb 100644 --- a/lib/scheduler/defer.rb +++ b/lib/scheduler/defer.rb @@ -21,7 +21,7 @@ module Scheduler @paused = false end - # for test + # for test and sidekiq def async=(val) @async = val end diff --git a/lib/search.rb b/lib/search.rb index adab7e3a7e..40f80a245c 100644 --- a/lib/search.rb +++ b/lib/search.rb @@ -48,8 +48,10 @@ class Search def self.prepare_data(search_data, purpose = :query) data = search_data.squish - # TODO cppjieba_rb is designed for chinese, we need something else for Korean / Japanese - if ['zh_TW', 'zh_CN', 'ja', 'ko'].include?(SiteSetting.default_locale) || SiteSetting.search_tokenize_chinese_japanese_korean + # TODO cppjieba_rb is designed for chinese, we need something else for Japanese + # Korean appears to be safe cause words are already space seperated + # For Japanese we should investigate using kakasi + if ['zh_TW', 'zh_CN', 'ja'].include?(SiteSetting.default_locale) || SiteSetting.search_tokenize_chinese_japanese_korean require 'cppjieba_rb' unless defined? CppjiebaRb mode = (purpose == :query ? :query : :mix) data = CppjiebaRb.segment(search_data, mode: mode) @@ -372,6 +374,8 @@ class Search exact = true slug = match.to_s.split(":") + next if slug.empty? + if slug[1] # sub category parent_category_id = Category.where(slug: slug[0].downcase, parent_category_id: nil).pluck(:id).first diff --git a/lib/site_setting_extension.rb b/lib/site_setting_extension.rb index 8ea79430c9..412ded8bfd 100644 --- a/lib/site_setting_extension.rb +++ b/lib/site_setting_extension.rb @@ -12,7 +12,10 @@ module SiteSettingExtension def_delegator :defaults, :has_setting? def_delegators 'SiteSettings::TypeSupervisor', :types, :supported_types - # part 1 of refactor, centralizing the dependency here + def listen_for_changes=(val) + @listen_for_changes = val + end + def provider=(val) @provider = val refresh! @@ -190,6 +193,8 @@ module SiteSettingExtension end def ensure_listen_for_changes + return if @listen_for_changes == false + unless @subscribed MessageBus.subscribe("/site_settings") do |message| process_message(message) diff --git a/lib/stylesheet/manager.rb b/lib/stylesheet/manager.rb index ea7de4dbe0..2d5f3614d1 100644 --- a/lib/stylesheet/manager.rb +++ b/lib/stylesheet/manager.rb @@ -256,7 +256,18 @@ class Stylesheet::Manager raise "attempting to look up theme digest for invalid field" end - Digest::SHA1.hexdigest(scss.to_s + color_scheme_digest.to_s + settings_digest) + Digest::SHA1.hexdigest(scss.to_s + color_scheme_digest.to_s + settings_digest + plugins_digest) + end + + # this protects us from situations where new versions of a plugin removed a file + # old instances may still be serving CSS and not aware of the change + # so we could end up poisoning the cache with a bad file that can not be removed + def plugins_digest + assets = [] + assets += DiscoursePluginRegistry.stylesheets.to_a + assets += DiscoursePluginRegistry.mobile_stylesheets.to_a + assets += DiscoursePluginRegistry.desktop_stylesheets.to_a + Digest::SHA1.hexdigest(assets.sort.join) end def settings_digest diff --git a/lib/tasks/assets.rake b/lib/tasks/assets.rake index 75f7db109b..abb83aff2b 100644 --- a/lib/tasks/assets.rake +++ b/lib/tasks/assets.rake @@ -117,7 +117,7 @@ end if ENV['COMPRESS_BROTLI']&.to_i == 1 # different brotli versions use different parameters - ver_out, ver_err, ver_status = Open3.capture3('brotli --version') + ver_out, _ver_err, ver_status = Open3.capture3('brotli --version') if !ver_status.success? # old versions of brotli don't respond to --version def brotli_command(path) @@ -125,7 +125,7 @@ if ENV['COMPRESS_BROTLI']&.to_i == 1 end elsif ver_out >= "brotli 1.0.0" def brotli_command(path) - "brotli --quality=11 #{path} --output=#{path}.br" + "brotli -f --quality=11 #{path} --output=#{path}.br" end else # not sure what to do here, not expecting this diff --git a/lib/tasks/docker.rake b/lib/tasks/docker.rake index a0bfc0c0b7..f66450a050 100644 --- a/lib/tasks/docker.rake +++ b/lib/tasks/docker.rake @@ -74,6 +74,7 @@ task 'docker:test' do if ENV["INSTALL_OFFICIAL_PLUGINS"] @good &&= run_or_fail("bundle exec rake plugin:install_all_official") + @good &&= run_or_fail("bundle exec rails r 'puts \"installing all gems\"'") end unless ENV["JS_ONLY"] diff --git a/lib/tasks/export.rake b/lib/tasks/export.rake index d0b80c8819..121a864771 100644 --- a/lib/tasks/export.rake +++ b/lib/tasks/export.rake @@ -1,8 +1,9 @@ desc 'Export all the categories' task 'export:categories', [:category_ids] => [:environment] do |_, args| require "import_export/import_export" + ids = args[:category_ids].split(" ") - ImportExport.export_categories(args[:category_ids]) + ImportExport.export_categories(ids) puts "", "Done", "" end diff --git a/lib/tasks/smoke_test.rake b/lib/tasks/smoke_test.rake index 99f09a8462..87b526e7f6 100644 --- a/lib/tasks/smoke_test.rake +++ b/lib/tasks/smoke_test.rake @@ -26,6 +26,9 @@ task "smoke:test" do request.basic_auth(ENV['AUTH_USER'], ENV['AUTH_PASSWORD']) end + dir = ENV["SMOKE_TEST_SCREENSHOT_PATH"] || 'tmp/smoke-test-screenshots' + FileUtils.mkdir_p(dir) unless Dir.exists?(dir) + start = Time.now while true response = Net::HTTP.start(uri.hostname, uri.port, use_ssl: uri.scheme == 'https') do |http| diff --git a/lib/tasks/users.rake b/lib/tasks/users.rake index 40dce95817..877d270f68 100644 --- a/lib/tasks/users.rake +++ b/lib/tasks/users.rake @@ -6,7 +6,7 @@ task "users:change_post_ownership", [:old_username, :new_username, :archetype] = archetype = archetype.downcase if archetype if !old_username || !new_username - puts "ERROR: Expecting rake posts:change_post_ownership[old_username,new_username,archetype]" + puts "ERROR: Expecting rake users:change_post_ownership[old_username,new_username,archetype]" exit 1 end @@ -18,7 +18,7 @@ task "users:change_post_ownership", [:old_username, :new_username, :archetype] = elsif archetype == "public" || !archetype posts = Post.public_posts.where(user_id: old_user.id) else - puts "ERROR: Expecting rake posts:change_post_ownership[old_username,new_username,archetype] where archetype is public or private" + puts "ERROR: Expecting rake users:change_post_ownership[old_username,new_username,archetype] where archetype is public or private" exit 1 end @@ -37,7 +37,7 @@ task "users:merge", [:source_username, :target_username] => [:environment] do |_ target_username = args[:target_username] if !source_username || !target_username - puts "ERROR: Expecting rake posts:merge[source_username,target_username]" + puts "ERROR: Expecting rake users:merge[source_username,target_username]" exit 1 end @@ -53,7 +53,7 @@ task "users:rename", [:old_username, :new_username] => [:environment] do |_, arg new_username = args[:new_username] if !old_username || !new_username - puts "ERROR: Expecting rake posts:rename[old_username,new_username]" + puts "ERROR: Expecting rake users:rename[old_username,new_username]" exit 1 end @@ -62,6 +62,26 @@ task "users:rename", [:old_username, :new_username] => [:environment] do |_, arg puts "", "User renamed!", "" end +desc "Updates username in quotes and mentions. Use this if the user was renamed before proper renaming existed." +task "users:update_posts", [:old_username, :current_username] => [:environment] do |_, args| + old_username = args[:old_username] + current_username = args[:current_username] + + if !old_username || !current_username + puts "ERROR: Expecting rake users:update_posts[old_username,current_username]" + exit 1 + end + + user = find_user(current_username) + Jobs::UpdateUsername.new.execute( + user_id: user.id, + old_username: old_username, + new_username: user.username, + avatar_template: user.avatar_template) + + puts "", "Username updated!", "" +end + def find_user(username) user = User.find_by_username(username) diff --git a/lib/topic_view.rb b/lib/topic_view.rb index 3c3dbd4e84..d2bf87de10 100644 --- a/lib/topic_view.rb +++ b/lib/topic_view.rb @@ -37,15 +37,16 @@ class TopicView wpcf.flatten.uniq end - def initialize(topic_id, user = nil, options = {}) - @message_bus_last_id = MessageBus.last_id("/topic/#{topic_id}") + def initialize(topic_or_topic_id, user = nil, options = {}) + @topic = find_topic(topic_or_topic_id) @user = user @guardian = Guardian.new(@user) - @topic = find_topic(topic_id) - @print = options[:print].present? check_and_raise_exceptions + @message_bus_last_id = MessageBus.last_id("/topic/#{@topic.id}") + @print = options[:print].present? + options.each do |key, value| self.instance_variable_set("@#{key}".to_sym, value) end @@ -435,10 +436,14 @@ class TopicView @posts end - def find_topic(topic_id) - # with_deleted covered in #check_and_raise_exceptions - finder = Topic.with_deleted.where(id: topic_id).includes(:category) - finder.first + def find_topic(topic_or_topic_id) + if topic_or_topic_id.is_a?(Topic) + topic_or_topic_id + else + # with_deleted covered in #check_and_raise_exceptions + finder = Topic.with_deleted.where(id: topic_or_topic_id).includes(:category) + finder.first + end end def unfiltered_posts diff --git a/lib/version.rb b/lib/version.rb index aeed4d4aa9..187efbb7c9 100644 --- a/lib/version.rb +++ b/lib/version.rb @@ -3,9 +3,9 @@ module Discourse unless defined? ::Discourse::VERSION module VERSION #:nodoc: MAJOR = 2 - MINOR = 0 + MINOR = 1 TINY = 0 - PRE = 'beta10' + PRE = 'beta1' STRING = [MAJOR, MINOR, TINY, PRE].compact.join('.') end diff --git a/plugins/discourse-details/config/locales/client.bg.yml b/plugins/discourse-details/config/locales/client.bg.yml new file mode 100644 index 0000000000..8e225fa6bb --- /dev/null +++ b/plugins/discourse-details/config/locales/client.bg.yml @@ -0,0 +1,14 @@ +# 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/ + +bg: + js: + details: + title: Скрий детайлите + composer: + details_title: Сумарно + details_text: "Този текст ще бъде скрит." diff --git a/plugins/discourse-details/config/locales/client.nb_NO.yml b/plugins/discourse-details/config/locales/client.nb_NO.yml index 2231ad9749..3326b734c1 100644 --- a/plugins/discourse-details/config/locales/client.nb_NO.yml +++ b/plugins/discourse-details/config/locales/client.nb_NO.yml @@ -5,4 +5,10 @@ # To work with us on translations, join this project: # https://www.transifex.com/projects/p/discourse-org/ -nb_NO: {} +nb_NO: + js: + details: + title: Skjul Detaljer + composer: + details_title: Sammendrag + details_text: "Denne teksten vil skjules" diff --git a/plugins/discourse-details/config/locales/server.bg.yml b/plugins/discourse-details/config/locales/server.bg.yml new file mode 100644 index 0000000000..53ef6a6fa6 --- /dev/null +++ b/plugins/discourse-details/config/locales/server.bg.yml @@ -0,0 +1,8 @@ +# 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/ + +bg: {} diff --git a/plugins/discourse-details/config/locales/server.de.yml b/plugins/discourse-details/config/locales/server.de.yml index 9bbf19d9e8..ac14f8ca1a 100644 --- a/plugins/discourse-details/config/locales/server.de.yml +++ b/plugins/discourse-details/config/locales/server.de.yml @@ -5,4 +5,6 @@ # To work with us on translations, join this project: # https://www.transifex.com/projects/p/discourse-org/ -de: {} +de: + site_settings: + details_enabled: "Aktiviert die Details-Funktion. Wenn du dies änderst, musst du alle Beiträge neu „backen“ mit: \"rake posts:rebake\"." diff --git a/plugins/discourse-details/config/locales/server.es.yml b/plugins/discourse-details/config/locales/server.es.yml index ccb6e22af1..9fb2007d80 100644 --- a/plugins/discourse-details/config/locales/server.es.yml +++ b/plugins/discourse-details/config/locales/server.es.yml @@ -5,4 +5,6 @@ # To work with us on translations, join this project: # https://www.transifex.com/projects/p/discourse-org/ -es: {} +es: + site_settings: + details_enabled: "Habilitar el plugin details. Si cambias esto, debes hacer un rebake en todos los posts con: \"rake post:rebake\"." diff --git a/plugins/discourse-details/config/locales/server.nb_NO.yml b/plugins/discourse-details/config/locales/server.nb_NO.yml index 2231ad9749..2795879881 100644 --- a/plugins/discourse-details/config/locales/server.nb_NO.yml +++ b/plugins/discourse-details/config/locales/server.nb_NO.yml @@ -5,4 +5,6 @@ # To work with us on translations, join this project: # https://www.transifex.com/projects/p/discourse-org/ -nb_NO: {} +nb_NO: + site_settings: + details_enabled: "Aktiver funksjonen for detaljer. Hvis du endrer dette, må du rebake alle innlegg med: \"rake posts:rebake\"." diff --git a/plugins/discourse-local-dates/assets/javascripts/discourse-local-dates.js b/plugins/discourse-local-dates/assets/javascripts/discourse-local-dates.js index f64c694e01..c68c51a461 100644 --- a/plugins/discourse-local-dates/assets/javascripts/discourse-local-dates.js +++ b/plugins/discourse-local-dates/assets/javascripts/discourse-local-dates.js @@ -46,9 +46,12 @@ html += relativeTime.replace("TZ", _formatTimezone(moment.tz.guess()).join(": ")); html += ""; + var joinedPreviews = previews.join("\n"); + $element .html(html) - .attr("title", previews.join("\n")) + .attr("title", joinedPreviews) + .attr("data-tooltip", joinedPreviews) .addClass("cooked"); if (repeat) { diff --git a/plugins/discourse-local-dates/assets/javascripts/discourse/components/discourse-local-dates-create-form.js.es6 b/plugins/discourse-local-dates/assets/javascripts/discourse/components/discourse-local-dates-create-form.js.es6 index 9cb7bf5ac1..e3c1afefb5 100644 --- a/plugins/discourse-local-dates/assets/javascripts/discourse/components/discourse-local-dates-create-form.js.es6 +++ b/plugins/discourse-local-dates/assets/javascripts/discourse/components/discourse-local-dates-create-form.js.es6 @@ -34,6 +34,16 @@ export default Ember.Component.extend({ return moment.tz.guess(); }, + @computed("formats") + previewedFormats(formats) { + return formats.map(format => { + return { + format: format, + preview: moment().format(format) + }; + }); + }, + @computed recurringOptions() { return [ @@ -76,7 +86,7 @@ export default Ember.Component.extend({ let text = `[date=${config.date} `; if (config.recurring) text += `recurring=${config.recurring} `; text += `time=${config.time} `; - text += `format=${config.format} `; + text += `format="${config.format}" `; text += `timezones="${config.timezones.join("|")}"`; text += `]`; return text; @@ -88,6 +98,11 @@ export default Ember.Component.extend({ return dateTime.isValid(); }, + @computed("advancedMode") + toggleModeBtnLabel(advancedMode) { + return advancedMode ? "discourse_local_dates.create.form.simple_mode" : "discourse_local_dates.create.form.advanced_mode"; + }, + actions: { advancedMode() { this.toggleProperty("advancedMode"); diff --git a/plugins/discourse-local-dates/assets/javascripts/discourse/templates/components/discourse-local-dates-create-form.hbs b/plugins/discourse-local-dates/assets/javascripts/discourse/templates/components/discourse-local-dates-create-form.hbs index f9ffba54f2..5b7ae5fa84 100644 --- a/plugins/discourse-local-dates/assets/javascripts/discourse/templates/components/discourse-local-dates-create-form.hbs +++ b/plugins/discourse-local-dates/assets/javascripts/discourse/templates/components/discourse-local-dates-create-form.hbs @@ -1,59 +1,82 @@ {{#d-modal-body title="discourse_local_dates.create.modal_title" + subtitle="discourse_local_dates.create.modal_subtitle" class="discourse-local-dates-create-modal" style="overflow: auto"}}
    -
    -
    - {{date-picker-future class="date" value=date defaultDate="DD-MM-YYYY"}} - {{input type="time" value=time class="time"}} - {{currentUserTimezone}} +
    +
    + +
    + {{date-picker-future class="date-input" value=date defaultDate="DD-MM-YYYY"}} +
    + +
    + +
    + {{input type="time" value=time class="time-input"}} +
    +
    + + {{currentUserTimezone}}
    -

    {{i18n "discourse_local_dates.create.form.recurring_title"}}

    -
    + {{#unless validDate}} + {{i18n "discourse_local_dates.create.form.invalid_date"}} + {{/unless}} + +
    + {{#if advancedMode}} - +

    {{{i18n "discourse_local_dates.create.form.recurring_description"}}}

    {{/if}}
    - {{combo-box content=recurringOptions value=recurring none="discourse_local_dates.create.form.recurring_none"}} + {{combo-box content=recurringOptions class="recurrence-input" value=recurring none="discourse_local_dates.create.form.recurring_none"}}
    - {{d-button - class="advanced-mode-btn" - action=(action "advancedMode") - icon="cog" - label="discourse_local_dates.create.form.advanced_mode"}} - {{#if advancedMode}}
    -
    -