Merge branch 'main' into bark-prod
All checks were successful
continuous-integration/drone/push Build is passing

This commit is contained in:
Dalite 2023-12-19 13:39:59 +01:00
commit 130ae637e7
158 changed files with 6410 additions and 1783 deletions

View file

@ -99,6 +99,16 @@
matchUpdateTypes: ['patch', 'minor'],
groupName: 'eslint (non-major)',
},
{
// Group actions/*-artifact in the same PR
matchManagers: ['github-actions'],
matchPackageNames: [
'actions/download-artifact',
'actions/upload-artifact',
],
matchUpdateTypes: ['major'],
groupName: 'artifact actions (major)',
},
{
// Update @types/* packages every week, with one grouped PR
matchPackagePrefixes: '@types/',

View file

@ -1,33 +1,21 @@
# This configuration was generated by
# `haml-lint --auto-gen-config`
# on 2023-10-26 09:32:34 -0400 using Haml-Lint version 0.51.0.
# on 2023-12-15 11:02:19 -0500 using Haml-Lint version 0.52.0.
# The point is for the user to remove these configuration records
# one by one as the lints are removed from the code base.
# Note that changes in the inspected code, or installation of new
# versions of Haml-Lint, may require this file to be generated again.
linters:
# Offense count: 16
# Offense count: 11
LineLength:
exclude:
- 'app/views/admin/account_actions/new.html.haml'
- 'app/views/admin/accounts/index.html.haml'
- 'app/views/admin/ip_blocks/new.html.haml'
- 'app/views/admin/roles/_form.html.haml'
- 'app/views/admin/settings/discovery/show.html.haml'
- 'app/views/auth/registrations/edit.html.haml'
- 'app/views/auth/registrations/new.html.haml'
- 'app/views/filters/_filter_fields.html.haml'
- 'app/views/media/player.html.haml'
- 'app/views/settings/applications/_fields.html.haml'
- 'app/views/settings/imports/index.html.haml'
- 'app/views/settings/preferences/appearance/show.html.haml'
- 'app/views/settings/preferences/notifications/show.html.haml'
- 'app/views/settings/preferences/other/show.html.haml'
# Offense count: 9
RuboCop:
exclude:
- 'app/views/admin/accounts/_buttons.html.haml'
- 'app/views/admin/accounts/_local_account.html.haml'
- 'app/views/admin/roles/_form.html.haml'

View file

@ -105,6 +105,21 @@ Rails/Exit:
- 'config/boot.rb'
- 'lib/mastodon/cli/*.rb'
Rails/SkipsModelValidations:
Exclude:
- 'db/*migrate/**/*'
# Reason: We want to preserve the ability to migrate from arbitrary old versions,
# and cannot guarantee that every installation has run every migration as they upgrade.
# https://docs.rubocop.org/rubocop-rails/cops_rails.html#railsunusedignoredcolumns
Rails/UnusedIgnoredColumns:
Enabled: false
# Reason: Prevailing style choice
# https://docs.rubocop.org/rubocop-rails/cops_rails.html#railsnegateinclude
Rails/NegateInclude:
Enabled: false
# Reason: Some single letter camel case files shouldn't be split
# https://docs.rubocop.org/rubocop-rspec/cops_rspec.html#rspecfilepath
RSpec/FilePath:

View file

@ -26,7 +26,7 @@ Lint/NonLocalExitFromIterator:
# Configuration parameters: AllowedMethods, AllowedPatterns, CountRepeatedAttributes.
Metrics/AbcSize:
Max: 125
Max: 100
# Configuration parameters: CountBlocks, Max.
Metrics/BlockNesting:
@ -119,23 +119,6 @@ Rails/LexicallyScopedActionFilter:
- 'app/controllers/auth/passwords_controller.rb'
- 'app/controllers/auth/registrations_controller.rb'
# This cop supports unsafe autocorrection (--autocorrect-all).
Rails/NegateInclude:
Exclude:
- 'app/controllers/concerns/signature_verification.rb'
- 'app/helpers/jsonld_helper.rb'
- 'app/lib/activitypub/activity/create.rb'
- 'app/lib/activitypub/activity/move.rb'
- 'app/lib/feed_manager.rb'
- 'app/lib/link_details_extractor.rb'
- 'app/models/concerns/attachmentable.rb'
- 'app/models/concerns/remotable.rb'
- 'app/models/custom_filter.rb'
- 'app/services/activitypub/process_status_update_service.rb'
- 'app/services/fetch_link_card_service.rb'
- 'app/workers/web/push_notification_worker.rb'
- 'lib/paperclip/color_extractor.rb'
Rails/OutputSafety:
Exclude:
- 'config/initializers/simple_form.rb'
@ -181,22 +164,6 @@ Rails/SkipsModelValidations:
- 'app/workers/move_worker.rb'
- 'app/workers/scheduler/ip_cleanup_scheduler.rb'
- 'app/workers/scheduler/scheduled_statuses_scheduler.rb'
- 'db/migrate/20161203164520_add_from_account_id_to_notifications.rb'
- 'db/migrate/20170105224407_add_shortcode_to_media_attachments.rb'
- 'db/migrate/20170209184350_add_reply_to_statuses.rb'
- 'db/migrate/20170304202101_add_type_to_media_attachments.rb'
- 'db/migrate/20180528141303_fix_accounts_unique_index.rb'
- 'db/migrate/20180609104432_migrate_web_push_subscriptions2.rb'
- 'db/migrate/20181207011115_downcase_custom_emoji_domains.rb'
- 'db/migrate/20190511134027_add_silenced_at_suspended_at_to_accounts.rb'
- 'db/migrate/20191007013357_update_pt_locales.rb'
- 'db/migrate/20220316233212_update_kurdish_locales.rb'
- 'db/post_migrate/20190511152737_remove_suspended_silenced_account_fields.rb'
- 'db/post_migrate/20200917193528_migrate_notifications_type.rb'
- 'db/post_migrate/20201017234926_fill_account_suspension_origin.rb'
- 'db/post_migrate/20220617202502_migrate_roles.rb'
- 'db/post_migrate/20221101190723_backfill_admin_action_logs.rb'
- 'db/post_migrate/20221206114142_backfill_admin_action_logs_again.rb'
- 'lib/mastodon/cli/accounts.rb'
- 'lib/mastodon/cli/maintenance.rb'
- 'spec/lib/activitypub/activity/follow_spec.rb'
@ -212,19 +179,6 @@ Rails/UniqueValidationWithoutIndex:
- 'app/models/identity.rb'
- 'app/models/webauthn_credential.rb'
# Configuration parameters: Include.
# Include: app/models/**/*.rb
Rails/UnusedIgnoredColumns:
Exclude:
- 'app/models/account.rb'
- 'app/models/account_stat.rb'
- 'app/models/admin/action_log.rb'
- 'app/models/custom_filter.rb'
- 'app/models/email_domain_block.rb'
- 'app/models/report.rb'
- 'app/models/status_edit.rb'
- 'app/models/user.rb'
# This cop supports unsafe autocorrection (--autocorrect-all).
# Configuration parameters: EnforcedStyle.
# SupportedStyles: exists, where
@ -378,22 +332,6 @@ Style/IfUnlessModifier:
- 'config/initializers/devise.rb'
- 'config/initializers/ffmpeg.rb'
# This cop supports unsafe autocorrection (--autocorrect-all).
# Configuration parameters: InverseMethods, InverseBlocks.
Style/InverseMethods:
Exclude:
- 'app/models/custom_filter.rb'
- 'app/services/update_account_service.rb'
- 'spec/controllers/activitypub/replies_controller_spec.rb'
# This cop supports safe autocorrection (--autocorrect).
# Configuration parameters: EnforcedStyle.
# SupportedStyles: line_count_dependent, lambda, literal
Style/Lambda:
Exclude:
- 'config/initializers/simple_form.rb'
- 'config/routes.rb'
# This cop supports unsafe autocorrection (--autocorrect-all).
Style/MapToHash:
Exclude:
@ -458,15 +396,6 @@ Style/RedundantFetchBlock:
- 'config/initializers/paperclip.rb'
- 'config/puma.rb'
# This cop supports safe autocorrection (--autocorrect).
# Configuration parameters: AllowMultipleReturnValues.
Style/RedundantReturn:
Exclude:
- 'app/controllers/api/v1/directories_controller.rb'
- 'app/controllers/auth/confirmations_controller.rb'
- 'app/lib/ostatus/tag_manager.rb'
- 'app/models/form/import.rb'
# This cop supports unsafe autocorrection (--autocorrect-all).
# Configuration parameters: ConvertCodeThatCanStartToReturnNil, AllowedMethods, MaxChainLength.
# AllowedMethods: present?, blank?, presence, try, try!
@ -487,11 +416,6 @@ Style/SingleArgumentDig:
Exclude:
- 'lib/webpacker/manifest_extensions.rb'
# This cop supports safe autocorrection (--autocorrect).
Style/StderrPuts:
Exclude:
- 'config/boot.rb'
# This cop supports unsafe autocorrection (--autocorrect-all).
# Configuration parameters: Mode.
Style/StringConcatenation:
@ -510,13 +434,6 @@ Style/StringLiterals:
- 'config/initializers/webauthn.rb'
- 'config/routes.rb'
# This cop supports unsafe autocorrection (--autocorrect-all).
# Configuration parameters: AllowMethodsWithArguments, AllowedMethods, AllowedPatterns, AllowComments.
# AllowedMethods: define_method, mail, respond_to
Style/SymbolProc:
Exclude:
- 'config/initializers/3_omniauth.rb'
# This cop supports safe autocorrection (--autocorrect).
# Configuration parameters: EnforcedStyle, AllowSafeAssignment.
# SupportedStyles: require_parentheses, require_no_parentheses, require_parentheses_when_complex

View file

@ -168,7 +168,7 @@ GEM
erubi (~> 1.4)
parser (>= 2.4)
smart_properties
bigdecimal (3.1.4)
bigdecimal (3.1.5)
bindata (2.4.15)
binding_of_caller (1.0.0)
debug_inspector (>= 0.0.1)
@ -197,7 +197,7 @@ GEM
activesupport
cbor (0.5.9.6)
charlock_holmes (0.7.7)
chewy (7.3.5)
chewy (7.4.0)
activesupport (>= 5.2)
elasticsearch (>= 7.12.0, < 7.14.0)
elasticsearch-dsl
@ -326,7 +326,7 @@ GEM
ruby-progressbar (~> 1.4)
globalid (1.2.1)
activesupport (>= 6.1)
haml (6.2.0)
haml (6.3.0)
temple (>= 0.8.2)
thor
tilt
@ -335,7 +335,7 @@ GEM
activesupport (>= 5.1)
haml (>= 4.0.6)
railties (>= 5.1)
haml_lint (0.51.0)
haml_lint (0.52.0)
haml (>= 4.0)
parallel (~> 1.10)
rainbow
@ -381,7 +381,7 @@ GEM
rdoc
reline (>= 0.3.8)
jmespath (1.6.2)
json (2.7.0)
json (2.7.1)
json-canonicalization (1.0.0)
json-jwt (1.15.3)
activesupport (>= 4.2)
@ -484,8 +484,8 @@ GEM
nokogiri (1.15.5)
mini_portile2 (~> 2.8.2)
racc (~> 1.4)
oj (3.16.2)
bigdecimal (~> 3.1)
oj (3.16.3)
bigdecimal (>= 3.0)
omniauth (2.1.1)
hashie (>= 3.4.6)
rack (>= 2.2.3)
@ -515,7 +515,7 @@ GEM
openssl (> 2.0)
orm_adapter (0.5.0)
ox (2.14.17)
parallel (1.23.0)
parallel (1.24.0)
parser (3.2.2.4)
ast (~> 2.4.1)
racc
@ -622,7 +622,7 @@ GEM
redis (>= 4)
redlock (1.3.2)
redis (>= 3.0.0, < 6.0)
regexp_parser (2.8.2)
regexp_parser (2.8.3)
reline (0.4.1)
io-console (~> 0.5)
request_store (1.5.1)
@ -662,7 +662,7 @@ GEM
rspec-mocks (~> 3.0)
sidekiq (>= 5, < 8)
rspec-support (3.12.1)
rubocop (1.58.0)
rubocop (1.59.0)
json (~> 2.3)
language_server-protocol (>= 3.17.0)
parallel (~> 1.10)
@ -679,10 +679,10 @@ GEM
rubocop (~> 1.41)
rubocop-factory_bot (2.24.0)
rubocop (~> 1.33)
rubocop-performance (1.19.1)
rubocop (>= 1.7.0, < 2.0)
rubocop-ast (>= 0.4.0)
rubocop-rails (2.22.2)
rubocop-performance (1.20.0)
rubocop (>= 1.48.1, < 2.0)
rubocop-ast (>= 1.30.0, < 2.0)
rubocop-rails (2.23.0)
activesupport (>= 4.2.0)
rack (>= 1.1)
rubocop (>= 1.33.0, < 2.0)
@ -759,7 +759,7 @@ GEM
unicode-display_width (>= 1.1.1, < 3)
terrapin (0.6.0)
climate_control (>= 0.0.3, < 1.0)
test-prof (1.3.0)
test-prof (1.3.1)
thor (1.3.0)
tilt (2.3.0)
timeout (0.4.1)

View file

@ -8,7 +8,7 @@ module Admin
authorize :follow_recommendation, :show?
@form = Form::AccountBatch.new
@accounts = filtered_follow_recommendations
@accounts = filtered_follow_recommendations.page(params[:page])
end
def update

View file

@ -108,6 +108,10 @@ class Api::BaseController < ApplicationController
render json: { error: 'Your login is currently disabled' }, status: 403 if current_user&.account&.unavailable?
end
def require_valid_pagination_options!
render json: { error: 'Pagination values for `offset` and `limit` must be positive' }, status: 400 if pagination_options_invalid?
end
def require_user!
if !current_user
render json: { error: 'This method requires an authenticated user' }, status: 422
@ -136,6 +140,10 @@ class Api::BaseController < ApplicationController
private
def pagination_options_invalid?
params.slice(:limit, :offset).values.map(&:to_i).any?(&:negative?)
end
def respond_with_error(code)
render json: { error: Rack::Utils::HTTP_STATUS_CODES[code] }, status: code
end

View file

@ -25,6 +25,6 @@ class Api::V1::Accounts::NotesController < Api::BaseController
end
def relationships_presenter
AccountRelationshipsPresenter.new([@account.id], current_user.account_id)
AccountRelationshipsPresenter.new([@account], current_user.account_id)
end
end

View file

@ -25,6 +25,6 @@ class Api::V1::Accounts::PinsController < Api::BaseController
end
def relationships_presenter
AccountRelationshipsPresenter.new([@account.id], current_user.account_id)
AccountRelationshipsPresenter.new([@account], current_user.account_id)
end
end

View file

@ -5,7 +5,7 @@ class Api::V1::Accounts::RelationshipsController < Api::BaseController
before_action :require_user!
def index
@accounts = Account.where(id: account_ids).select('id')
@accounts = Account.where(id: account_ids).select(:id, :domain)
@accounts.merge!(Account.without_suspended) unless truthy_param?(:with_suspended)
render json: @accounts, each_serializer: REST::RelationshipSerializer, relationships: relationships
end

View file

@ -88,7 +88,7 @@ class Api::V1::AccountsController < Api::BaseController
end
def relationships(**options)
AccountRelationshipsPresenter.new([@account.id], current_user.account_id, **options)
AccountRelationshipsPresenter.new([@account], current_user.account_id, **options)
end
def account_params

View file

@ -12,7 +12,7 @@ class Api::V1::DirectoriesController < Api::BaseController
private
def require_enabled!
return not_found unless Setting.profile_directory
not_found unless Setting.profile_directory
end
def set_accounts

View file

@ -25,11 +25,11 @@ class Api::V1::FollowRequestsController < Api::BaseController
private
def account
Account.find(params[:id])
@account ||= Account.find(params[:id])
end
def relationships(**options)
AccountRelationshipsPresenter.new([params[:id]], current_user.account_id, **options)
AccountRelationshipsPresenter.new([account], current_user.account_id, **options)
end
def load_accounts

View file

@ -3,22 +3,23 @@
class Api::V1::SuggestionsController < Api::BaseController
include Authorization
before_action -> { doorkeeper_authorize! :read }
before_action -> { doorkeeper_authorize! :read, :'read:accounts' }, only: :index
before_action -> { doorkeeper_authorize! :write, :'write:accounts' }, except: :index
before_action :require_user!
before_action :set_suggestions
def index
suggestions = suggestions_source.get(current_account, limit: limit_param(DEFAULT_ACCOUNTS_LIMIT))
render json: suggestions.map(&:account), each_serializer: REST::AccountSerializer
render json: @suggestions.get(limit_param(DEFAULT_ACCOUNTS_LIMIT), params[:offset].to_i).map(&:account), each_serializer: REST::AccountSerializer
end
def destroy
suggestions_source.remove(current_account, params[:id])
@suggestions.remove(params[:id])
render_empty
end
private
def suggestions_source
AccountSuggestions::PastInteractionsSource.new
def set_suggestions
@suggestions = AccountSuggestions.new(current_account)
end
end

View file

@ -12,6 +12,7 @@ class Api::V2::SearchController < Api::BaseController
before_action :query_pagination_error, if: :pagination_requested?
before_action :remote_resolve_error, if: :remote_resolve_requested?
end
before_action :require_valid_pagination_options!
def index
@search = Search.new(search_results)

View file

@ -3,17 +3,23 @@
class Api::V2::SuggestionsController < Api::BaseController
include Authorization
before_action -> { doorkeeper_authorize! :read }
before_action -> { doorkeeper_authorize! :read, :'read:accounts' }, only: :index
before_action -> { doorkeeper_authorize! :write, :'write:accounts' }, except: :index
before_action :require_user!
before_action :set_suggestions
def index
render json: @suggestions, each_serializer: REST::SuggestionSerializer
render json: @suggestions.get(limit_param(DEFAULT_ACCOUNTS_LIMIT), params[:offset].to_i), each_serializer: REST::SuggestionSerializer
end
def destroy
@suggestions.remove(params[:id])
render_empty
end
private
def set_suggestions
@suggestions = AccountSuggestions.get(current_account, limit_param(DEFAULT_ACCOUNTS_LIMIT))
@suggestions = AccountSuggestions.new(current_account)
end
end

View file

@ -62,7 +62,7 @@ class Auth::ConfirmationsController < Devise::ConfirmationsController
end
def captcha_user_bypass?
return true if @confirmation_user.nil? || @confirmation_user.confirmed?
@confirmation_user.nil? || @confirmation_user.confirmed?
end
def require_unconfirmed!

View file

@ -33,7 +33,7 @@ class RelationshipsController < ApplicationController
end
def set_relationships
@relationships = AccountRelationshipsPresenter.new(@accounts.pluck(:id), current_user.account_id)
@relationships = AccountRelationshipsPresenter.new(@accounts, current_user.account_id)
end
def form_account_batch_params

View file

@ -110,11 +110,11 @@ module ApplicationHelper
def can?(action, record)
return false if record.nil?
policy(record).public_send("#{action}?")
policy(record).public_send(:"#{action}?")
end
def fa_icon(icon, attributes = {})
class_names = attributes[:class]&.split(' ') || []
class_names = attributes[:class]&.split || []
class_names << 'fa'
class_names += icon.split.map { |cl| "fa-#{cl}" }

View file

@ -21,7 +21,7 @@ function actionWithSkipLoadingTrue<Args extends object>(args: Args) {
}
export const followAccountSuccess = createAction(
'accounts/followAccountSuccess',
'accounts/followAccount/SUCCESS',
actionWithSkipLoadingTrue<{
relationship: ApiRelationshipJSON;
alreadyFollowing: boolean;
@ -29,7 +29,7 @@ export const followAccountSuccess = createAction(
);
export const unfollowAccountSuccess = createAction(
'accounts/unfollowAccountSuccess',
'accounts/unfollowAccount/SUCCESS',
actionWithSkipLoadingTrue<{
relationship: ApiRelationshipJSON;
statuses: unknown;
@ -38,60 +38,60 @@ export const unfollowAccountSuccess = createAction(
);
export const authorizeFollowRequestSuccess = createAction<{ id: string }>(
'accounts/followRequestAuthorizeSuccess',
'accounts/followRequestAuthorize/SUCCESS',
);
export const rejectFollowRequestSuccess = createAction<{ id: string }>(
'accounts/followRequestRejectSuccess',
'accounts/followRequestReject/SUCCESS',
);
export const followAccountRequest = createAction(
'accounts/followRequest',
'accounts/follow/REQUEST',
actionWithSkipLoadingTrue<{ id: string; locked: boolean }>,
);
export const followAccountFail = createAction(
'accounts/followFail',
'accounts/follow/FAIL',
actionWithSkipLoadingTrue<{ id: string; error: string; locked: boolean }>,
);
export const unfollowAccountRequest = createAction(
'accounts/unfollowRequest',
'accounts/unfollow/REQUEST',
actionWithSkipLoadingTrue<{ id: string }>,
);
export const unfollowAccountFail = createAction(
'accounts/unfollowFail',
'accounts/unfollow/FAIL',
actionWithSkipLoadingTrue<{ id: string; error: string }>,
);
export const blockAccountSuccess = createAction<{
relationship: ApiRelationshipJSON;
statuses: unknown;
}>('accounts/blockSuccess');
}>('accounts/block/SUCCESS');
export const unblockAccountSuccess = createAction<{
relationship: ApiRelationshipJSON;
}>('accounts/unblockSuccess');
}>('accounts/unblock/SUCCESS');
export const muteAccountSuccess = createAction<{
relationship: ApiRelationshipJSON;
statuses: unknown;
}>('accounts/muteSuccess');
}>('accounts/mute/SUCCESS');
export const unmuteAccountSuccess = createAction<{
relationship: ApiRelationshipJSON;
}>('accounts/unmuteSuccess');
}>('accounts/unmute/SUCCESS');
export const pinAccountSuccess = createAction<{
relationship: ApiRelationshipJSON;
}>('accounts/pinSuccess');
}>('accounts/pin/SUCCESS');
export const unpinAccountSuccess = createAction<{
relationship: ApiRelationshipJSON;
}>('accounts/unpinSuccess');
}>('accounts/unpin/SUCCESS');
export const fetchRelationshipsSuccess = createAction(
'relationships/fetchSuccess',
'relationships/fetch/SUCCESS',
actionWithSkipLoadingTrue<{ relationships: ApiRelationshipJSON[] }>,
);

View file

@ -5,9 +5,9 @@ import type { Account } from 'mastodon/models/account';
export const blockDomainSuccess = createAction<{
domain: string;
accounts: Account[];
}>('domain_blocks/blockSuccess');
}>('domain_blocks/block/SUCCESS');
export const unblockDomainSuccess = createAction<{
domain: string;
accounts: Account[];
}>('domain_blocks/unblockSuccess');
}>('domain_blocks/unblock/SUCCESS');

View file

@ -257,7 +257,7 @@ class Dropdown extends PureComponent {
};
findTarget = () => {
return this.target?.buttonRef?.current;
return this.target?.buttonRef?.current ?? this.target;
};
componentWillUnmount = () => {

View file

@ -1,80 +0,0 @@
import PropTypes from 'prop-types';
import React, { Component } from 'react';
import { render, fireEvent } from '@testing-library/react';
class Media extends Component {
constructor(props) {
super(props);
this.state = {
paused: props.paused || false,
};
}
handleMediaClick = () => {
const { onClick } = this.props;
this.setState(prevState => ({
paused: !prevState.paused,
}));
if (typeof onClick === 'function') {
onClick();
}
const { title } = this.props;
const mediaElements = document.querySelectorAll(`div[title="${title}"]`);
setTimeout(() => {
mediaElements.forEach(element => {
if (element !== this && !element.classList.contains('paused')) {
element.click();
}
});
}, 0);
};
render() {
const { title } = this.props;
const { paused } = this.state;
return (
<button title={title} onClick={this.handleMediaClick}>
Media Component - {paused ? 'Paused' : 'Playing'}
</button>
);
}
}
Media.propTypes = {
title: PropTypes.string.isRequired,
onClick: PropTypes.func,
paused: PropTypes.bool,
};
describe('Media attachments test', () => {
let currentMedia = null;
const togglePlayMock = jest.fn();
it('plays a new media file and pauses others that were playing', () => {
const container = render(
<div>
<Media title='firstMedia' paused onClick={togglePlayMock} />
<Media title='secondMedia' paused onClick={togglePlayMock} />
</div>,
);
fireEvent.click(container.getByTitle('firstMedia'));
expect(togglePlayMock).toHaveBeenCalledTimes(1);
currentMedia = container.getByTitle('firstMedia');
expect(currentMedia.textContent).toMatch(/Playing/);
fireEvent.click(container.getByTitle('secondMedia'));
expect(togglePlayMock).toHaveBeenCalledTimes(2);
currentMedia = container.getByTitle('secondMedia');
expect(currentMedia.textContent).toMatch(/Playing/);
});
});

View file

@ -20,7 +20,6 @@ import { formatTime, getPointerPosition, fileNameFromURL } from 'mastodon/featur
import { Blurhash } from '../../components/blurhash';
import { displayMedia, useBlurhash } from '../../initial_state';
import { currentMedia, setCurrentMedia } from '../../reducers/media_attachments';
import Visualizer from './visualizer';
@ -166,32 +165,15 @@ class Audio extends PureComponent {
}
togglePlay = () => {
const audios = document.querySelectorAll('audio');
audios.forEach((audio) => {
const button = audio.previousElementSibling;
button.addEventListener('click', () => {
if(audio.paused) {
audios.forEach((e) => {
if (e !== audio) {
e.pause();
}
});
audio.play();
this.setState({ paused: false });
} else {
audio.pause();
this.setState({ paused: true });
}
});
});
if (currentMedia !== null) {
currentMedia.pause();
if (!this.audioContext) {
this._initAudioContext();
}
this.audio.play();
setCurrentMedia(this.audio);
if (this.state.paused) {
this.setState({ paused: false }, () => this.audio.play());
} else {
this.setState({ paused: true }, () => this.audio.pause());
}
};
handleResize = debounce(() => {
@ -213,7 +195,6 @@ class Audio extends PureComponent {
};
handlePause = () => {
this.audio.pause();
this.setState({ paused: true });
if (this.audioContext) {

View file

@ -22,7 +22,6 @@ import { Icon } from 'mastodon/components/icon';
import { playerSettings } from 'mastodon/settings';
import { displayMedia, useBlurhash } from '../../initial_state';
import { currentMedia, setCurrentMedia } from '../../reducers/media_attachments';
import { isFullscreen, requestFullscreen, exitFullscreen } from '../ui/util/fullscreen';
const messages = defineMessages({
@ -182,7 +181,6 @@ class Video extends PureComponent {
};
handlePause = () => {
this.video.pause();
this.setState({ paused: true });
};
@ -346,32 +344,11 @@ class Video extends PureComponent {
};
togglePlay = () => {
const videos = document.querySelectorAll('video');
videos.forEach((video) => {
const button = video.nextElementSibling;
button.addEventListener('click', () => {
if (video.paused) {
videos.forEach((e) => {
if (e !== video) {
e.pause();
}
});
video.play();
this.setState({ paused: false });
} else {
video.pause();
this.setState({ paused: true });
}
});
});
if (currentMedia !== null) {
currentMedia.pause();
if (this.state.paused) {
this.setState({ paused: false }, () => this.video.play());
} else {
this.setState({ paused: true }, () => this.video.pause());
}
this.video.play();
setCurrentMedia(this.video);
};
toggleFullscreen = () => {

View file

@ -606,6 +606,7 @@
"search.quick_action.status_search": "Sobivad postitused {x}",
"search.search_or_paste": "Otsi või kleebi URL",
"search_popout.full_text_search_disabled_message": "Pole saadaval kohas {domain}.",
"search_popout.full_text_search_logged_out_message": "Saadaval vaid kui sisse logitud.",
"search_popout.language_code": "Keele ISO-kood",
"search_popout.options": "Otsimisvalikud",
"search_popout.quick_actions": "Kiirtegevused",

View file

@ -1 +1,145 @@
{}
{
"about.blocks": "Mga pinatimping server",
"about.contact": "Kontak:",
"about.disclaimer": "Ang Mastodon ay software na malaya at bukas-na-pinagmulan, at isang tatak-pangkalakal ng Mastodon gGmbH.",
"about.domain_blocks.no_reason_available": "Hindi makuha ang dahilan",
"about.domain_blocks.silenced.title": "Limitado",
"about.domain_blocks.suspended.title": "Suspendido",
"about.rules": "Mga alituntunin ng server",
"account.account_note_header": "Tala",
"account.add_or_remove_from_list": "I-dagdag o tanggalin mula sa mga listahan",
"account.badges.bot": "Pakusa",
"account.badges.group": "Pangkat",
"account.block": "Hadlangan si @{name}",
"account.block_domain": "Hadlangan ang domain na {domain}",
"account.block_short": "Hadlangan",
"account.blocked": "Hinadlangan",
"account.browse_more_on_origin_server": "Tingnan pa sa pangunahing profile",
"account.cancel_follow_request": "I-kansela ang pagsunod",
"account.copy": "I-sipi ang kawing sa profile",
"account.direct": "Palihim banggitin si @{name}",
"account.disable_notifications": "I-tigil ang pagpapaalam sa akin tuwing nagpopost si @{name}",
"account.domain_blocked": "Hinadlangan ang domain",
"account.edit_profile": "Baguhin ang profile",
"account.enable_notifications": "Ipaalam sa akin kapag nag-post si @{name}",
"account.endorse": "I-tampok sa profile",
"account.featured_tags.last_status_at": "Huling post noong {date}",
"account.featured_tags.last_status_never": "Walang mga post",
"account.featured_tags.title": "Nakatampok na hashtag ni {name}",
"account.follow": "Sundan",
"account.followers": "Mga tagasunod",
"account.followers.empty": "Wala pang sumusunod sa tagagamit na ito.",
"account.following": "Sinusundan",
"account.follows.empty": "Wala pang sinusundan ang tagagamit na ito.",
"account.follows_you": "Sinusunod ka",
"account.go_to_profile": "Pumunta sa profile",
"account.hide_reblogs": "Itago ang mga pagpapalakas mula sa {name}",
"account.in_memoriam": "Sa Alaala Ni.",
"account.joined_short": "Sumali",
"account.languages": "Palitan ang mga nakasumuscribing wika",
"account.link_verified_on": "Sinuri ang pagmamay-ari ng kawing ito sa {date}",
"account.locked_info": "Nakakandado ang pagsasariling kalagayan ng account na ito. Manomano sinusuri ng may-ari kung sino ang maaaring sumunod sa kanya.",
"account.media": "Medya",
"account.mention": "Banggitin si @{name}",
"account.moved_to": "Ipinahihiwatig ni {name} na ang kanilang bagong account ngayon ay:",
"bundle_column_error.error.title": "Naku!",
"bundle_column_error.network.body": "Nagkaroon ng kamalian habang sinusubukang i-karga ang pahinang ito. Maaaring dahil ito sa pansamantalang problema ng iyong koneksyon sa internet o ang server na ito.",
"bundle_column_error.network.title": "Kamaliang network",
"bundle_column_error.retry": "Subukang muli",
"bundle_column_error.return": "Bumalik sa tahanan",
"bundle_column_error.routing.body": "Hindi mahanap ang hiniling na pahina. Sigurado ka ba na ang URL sa address bar ay tama?",
"bundle_column_error.routing.title": "404",
"bundle_modal_error.close": "I-sara",
"bundle_modal_error.message": "May nangyaring mali habang kinakarga ang bahaging ito.",
"bundle_modal_error.retry": "Subukang muli",
"closed_registrations.other_server_instructions": "Dahil desentralisado ang Mastodon, pwede kang gumawa ng account sa iba pang server at makipag-ugnayan pa rin dito.",
"closed_registrations_modal.description": "Hindi pa pwedeng gumawa ng account sa {domain}, pero tandaan na hindi mo kailangan ng account partikular sa {domain} para gamitin ang Mastodon.",
"closed_registrations_modal.find_another_server": "Maghanap ng iba pang server",
"closed_registrations_modal.preamble": "Dahil desentralisado ang Mastodon, kahit saan ka pa gumawa ng account, maaari ka pa ring sumunod at makipag-ugnayan sa kahit-sino rito sa server na ito. Pwede mo pang i-host nang pasarili!",
"closed_registrations_modal.title": "Pagrerehistro sa Mastodon",
"column.about": "Tungkol dito",
"column.blocks": "Nakahadlang na mga tagagamit",
"column.bookmarks": "Mga bookmark",
"column.community": "Lokal na timeline",
"column.direct": "Mga palihim na banggit",
"column.directory": "Tingnan ang mga profile",
"column.domain_blocks": "Nakahadlang na mga domain",
"column.favourites": "Mga paborito",
"column.firehose": "Mga live feed",
"column.follow_requests": "Mga hiling para sundan",
"column.home": "Tahanan",
"column.lists": "Mga listahan",
"column.mutes": "Mga pinatahimik na tagagamit",
"column.notifications": "Mga abiso",
"column.pins": "Mga nakapaskil na post",
"column.public": "Pinagsamang timeline",
"column_back_button.label": "Bumalik",
"column_header.hide_settings": "I-tago ang mga setting",
"column_header.moveLeft_settings": "I-lipat ang hanay pakaliwa",
"column_header.moveRight_settings": "I-lipat ang hanay pakanan",
"column_header.pin": "I-paskil",
"column_header.show_settings": "Ipakita ang mga setting",
"column_header.unpin": "Tanggalin sa pagkapaskil",
"column_subheading.settings": "Mga setting",
"community.column_settings.local_only": "Lokal lamang",
"community.column_settings.media_only": "Medya Lamang",
"community.column_settings.remote_only": "Liblib lamang",
"compose.language.change": "Magpalit ng wika",
"compose.language.search": "Maghanap ng mga wika...",
"compose.published.body": "Nailathala ang post.",
"compose.published.open": "Buksan",
"compose.saved.body": "Nai-save ang post.",
"compose_form.direct_message_warning_learn_more": "Matuto pa",
"compose_form.encryption_warning": "Ang mga post sa Mastodon ay hindi naka-encrypt nang dulo-dulo. Huwag magbahagi ng anumang sensitibong impormasyon sa Mastodon.",
"compose_form.hashtag_warning": "Hindi maililista ang post na ito sa anumang hashtag dahil hindi ito nakapubliko. Mga nakapublikong post lamang ang mahahanap ayon sa hashtag.",
"copy_icon_button.copied": "Sinipi sa clipboard",
"copypaste.copied": "Sinipi",
"copypaste.copy_to_clipboard": "I-sipi sa clipboard",
"directory.federated": "Mula sa kilalang fediverse",
"directory.local": "Mula sa {domain} lamang",
"directory.new_arrivals": "Mga bagong dating",
"directory.recently_active": "Kamakailang aktibo",
"disabled_account_banner.account_settings": "Mga setting ng account",
"disabled_account_banner.text": "Ang iyong account na {disabledAccount} ay hindi pinapagana ngayon.",
"dismissable_banner.community_timeline": "Ito ang mga pinakamakailang nakapublikong post mula sa mga taong ang mga account hinohost ng {domain}.",
"dismissable_banner.dismiss": "Alisin",
"dismissable_banner.explore_links": "Ito ang mga balitang kwento na pinaka-binabahagi sa social web ngayon. Ang mga mas bagong balitang kwento na pinost ng mas marami pang mga iba't ibang tao ay tinataasan ng antas.",
"dismissable_banner.explore_statuses": "Ito ang mga sumisikat na mga post sa iba't ibang bahagi ng social web ngayon. Ang mga mas bagong post na mas marami ang mga pagpapalakas at paborito ay tinataasan ng antas.",
"dismissable_banner.explore_tags": "Ito ang mga sumisikat na mga hashtag sa iba't ibang bahagi ng social web ngayon. Ang mga hashtag ginagamit ng mas maraming mga iba't ibang tao ay tinataasan ng antas.",
"dismissable_banner.public_timeline": "Ito ang mga pinakamakailang nakapublikong post mula sa mga taong nasa social web na sinusundan ng mga tao sa {domain}.",
"embed.instructions": "I-embed ang post na ito sa iyong pook-sapot sa pamamagitan ng pagsipi ng kodigo sa ilalim.",
"embed.preview": "Ito ang magiging itsura:",
"emoji_button.activity": "Aktibidad",
"emoji_button.clear": "Linisin",
"emoji_button.custom": "Pasadya",
"emoji_button.flags": "Mga watawat",
"emoji_button.food": "Pagkain at Inumin",
"emoji_button.label": "Maglagay ng emoji",
"emoji_button.nature": "Kalikasan",
"emoji_button.not_found": "Walang mahanap na mga tugmang emoji",
"emoji_button.objects": "Mga bagay",
"emoji_button.people": "Mga tao",
"emoji_button.recent": "Madalas na ginagamit",
"emoji_button.search": "Maghanap...",
"emoji_button.search_results": "Resulta ng paghahanap",
"emoji_button.symbols": "Mga tanda",
"emoji_button.travel": "Paglakbay at Mga Lugar",
"empty_column.account_hides_collections": "Pinili ng tagagamit na ito na hindi makuha ang impormasyong ito",
"empty_column.account_suspended": "Sinuspinde ang account",
"empty_column.account_timeline": "Walang mga post dito!",
"empty_column.account_unavailable": "Hindi makuha ang profile",
"empty_column.blocks": "Hindi ka pa naghahadlang ng sinumang tagagamit.",
"empty_column.bookmarked_statuses": "Wala ka pang naka-bookmark na post. Kapag nag-bookmark ka ng isa, makikita yun dito.",
"empty_column.community": "Walang laman ang lokal na timeline. Magsulat ng anuman papubliko para makaandar tayo!",
"empty_column.direct": "Wala ka pang mga palihim na banggit. Kapag nagpadala o tumanggap ka ng isa, makikita yun dito.",
"empty_column.domain_blocks": "Wala pang nakahadlang na domain.",
"empty_column.explore_statuses": "Wala pang sumisikat sa ngayon. Balik na lang sa muli!",
"empty_column.favourited_statuses": "Wala ka pang mga paboritong post. Kapag nag-paborito ka ng isa, makikita yun dito.",
"empty_column.favourites": "Wala pang may paborito ng post na ito. Kung may sinumang nagpaborito, makikita sila rito.",
"empty_column.follow_requests": "Wala ka pang mga hiling para sundan ka. Kapag nakatanggap ka ng isa, makikita yun dito.",
"empty_column.followed_tags": "Wala ka pang sinusunod na hashtag. Kapag may sinundan ka na, makikita sila rito.",
"empty_column.hashtag": "Wala pang laman ang hashtag na ito.",
"empty_column.home": "Walang laman ang timeline ng tahanan mo! Sumunod sa marami pang tao para mapunan ito.",
"empty_column.list": "Wala pang laman ang listahang ito. Kapag naglathala ng mga bagong post ang mga miyembro ng listahang ito, makikita iyon dito.",
"empty_column.lists": "Wala ka pang mga listahan. Kapag gumawa ka ng isa, makikita yun dito."
}

View file

@ -0,0 +1,23 @@
{
"account.add_or_remove_from_list": "Adder o remover ab listas",
"account.copy": "Copiar ligamine a profilo",
"bundle_column_error.network.title": "Error de rete",
"bundle_modal_error.close": "Clauder",
"column.home": "Initio",
"column_subheading.settings": "Parametros",
"compose.language.search": "Cercar linguas...",
"compose.published.open": "Aperir",
"confirmation_modal.cancel": "Cancellar",
"confirmations.logout.confirm": "Clauder le session",
"copypaste.copy_to_clipboard": "Copiar al area de transferentia",
"dismissable_banner.dismiss": "Dimitter",
"firehose.local": "Iste servitor",
"footer.about": "A proposito de",
"home.pending_critical_update.link": "Vider actualisationes",
"keyboard_shortcuts.my_profile": "Aperir tu profilo",
"lightbox.close": "Clauder",
"lightbox.next": "Sequente",
"link_preview.author": "Per {name}",
"lists.account.add": "Adder al lista",
"navigation_bar.about": "A proposito de"
}

View file

@ -0,0 +1,700 @@
{
"about.blocks": "Moderat servitores",
"about.contact": "Contacter:",
"about.disclaimer": "Mastodon es programmatura líber e con fonte apert, e un marca de fabrica de Mastodon dGmbH.",
"about.domain_blocks.no_reason_available": "Rason ne disponibil",
"about.domain_blocks.preamble": "Mastodon generalmen possibilisa regardar li contenete de, e li interaction con usatores de quelcunc altri servitor in li fediverse. Ci trova se li exceptiones fat de ti-ci particulari servitor.",
"about.domain_blocks.silenced.explanation": "Generalmen, li profiles e contenete de ti-ci servitor ne va aparir, except si on sercha les explicitmen o optionalisa it per sequer.",
"about.domain_blocks.silenced.title": "Limitat",
"about.domain_blocks.suspended.explanation": "Necun data de ti-ci servitor va esser tractat, inmagasinat o exchangeat, quel inpossibilisa li interaction o comunication de usatores de ti-ci servitor.",
"about.domain_blocks.suspended.title": "Suspendet",
"about.not_available": "On ne ha disponibilisat ti-ci information sur ti-ci servitor.",
"about.powered_by": "Decentralisat social medie disponibilisat de {mastodon}",
"about.rules": "Regules del servitor",
"account.account_note_header": "Nota",
"account.add_or_remove_from_list": "Adjunter o remover de listes",
"account.badges.bot": "Automatisat",
"account.badges.group": "Gruppe",
"account.block": "Bloccar @{name}",
"account.block_domain": "Bloccar dominia {domain}",
"account.block_short": "Bloccar",
"account.blocked": "Bloccat",
"account.browse_more_on_origin_server": "Navigar plu sur li profil original",
"account.cancel_follow_request": "Anullar sequer",
"account.copy": "Copiar ligament al profil",
"account.direct": "Privatmen mentionar @{name}",
"account.disable_notifications": "Cessa notificar me quande @{name} posta",
"account.domain_blocked": "Dominia bloccat",
"account.edit_profile": "Redacter profil",
"account.enable_notifications": "Notificar me quande @{name} posta",
"account.endorse": "Recomandar sur profil",
"account.featured_tags.last_status_at": "Ultim posta ye {date}",
"account.featured_tags.last_status_never": "Null postas",
"account.featured_tags.title": "Recomandat hashtags de {name}",
"account.follow": "Sequer",
"account.followers": "Sequitores",
"account.followers.empty": "Ancor nequi seque ti-ci usator.",
"account.followers_counter": "{count, plural, one {{counter} Sequitor} other {{counter} Sequitor}}",
"account.following": "Sequent",
"account.following_counter": "{count, plural, one {{counter} Sequent} other {{counter} Sequent}}",
"account.follows.empty": "Ti-ci usator ancor ne seque quemcunc.",
"account.follows_you": "Seque te",
"account.go_to_profile": "Ear a profil",
"account.hide_reblogs": "Celar boosts de @{name}",
"account.in_memoriam": "In Memoriam.",
"account.joined_short": "Adheret",
"account.languages": "Changear lingues de subscrition",
"account.link_verified_on": "Proprietá de ti-ci ligament esset verificat ye {date}",
"account.locked_info": "Li statu de confidentialitá de ti-ci conto es configurat quam cludet. Li proprietario decide manualmen qui posse sequer.",
"account.media": "Medie",
"account.mention": "Mentionar @{name}",
"account.moved_to": "{name} ha indicat que su nov conto es ja:",
"account.mute": "Silentiar @{name}",
"account.mute_notifications_short": "Silentiar notificationes",
"account.mute_short": "Silentiar",
"account.muted": "Silentiat",
"account.no_bio": "Null descrition providet.",
"account.open_original_page": "Aperter li págine original",
"account.posts": "Postas",
"account.posts_with_replies": "Postas e replicas",
"account.report": "Raportar @{name}",
"account.requested": "Atendent aprobation. Cliccar por anullar li petition de sequer",
"account.requested_follow": "{name} ha petit sequer te",
"account.share": "Distribuer li profil de @{name}",
"account.show_reblogs": "Monstrar boosts de @{name}",
"account.statuses_counter": "{count, plural, one {{counter} Posta} other {{counter} Postas}}",
"account.unblock": "Desbloccar @{name}",
"account.unblock_domain": "Desbloccar dominia {domain}",
"account.unblock_short": "Desbloccar",
"account.unendorse": "Ne recomandar sur profil",
"account.unfollow": "Dessequer",
"account.unmute": "Dessilentiar @{name}",
"account.unmute_notifications_short": "Dessilentiar notificationes",
"account.unmute_short": "Dessilentiar",
"account_note.placeholder": "Clicca por adjunter un nota",
"admin.dashboard.daily_retention": "Usator-retention per die pos registration",
"admin.dashboard.monthly_retention": "Usator-retention per mensu pos registration",
"admin.dashboard.retention.average": "Medial",
"admin.dashboard.retention.cohort": "Mensu de registration",
"admin.dashboard.retention.cohort_size": "Nov usatores",
"admin.impact_report.instance_accounts": "Conto-profiles to-ci vell deleter",
"admin.impact_report.instance_followers": "Sequitores queles nor usatores vell perdir",
"admin.impact_report.instance_follows": "Sequitores queles lor usatores vell perdir",
"admin.impact_report.title": "Resumate de impact",
"alert.rate_limited.message": "Ples reprovar pos {retry_time, time, medium}.",
"alert.rate_limited.title": "Frequentie limitat",
"alert.unexpected.message": "Un ínexpectat erra ha evenit.",
"alert.unexpected.title": "Ups!",
"announcement.announcement": "Proclamation",
"attachments_list.unprocessed": "(íntractat)",
"audio.hide": "Celar audio",
"autosuggest_hashtag.per_week": "{count} per semane",
"boost_modal.combo": "Li proxim vez tu posse pressar {combo} por passar to-ci",
"bundle_column_error.copy_stacktrace": "Copiar erra-raporte",
"bundle_column_error.error.body": "Li demandat págine ne posset esser rendit. Fórsan it es un problema in nor code, o un problema de compatibilitá con li navigator.",
"bundle_column_error.error.title": "O ve!",
"bundle_column_error.network.body": "Un erra evenit durant li cargation de ti-ci págine, possibilmen pro un temporari problema de tui conexion del internet o de ti-ci servitor.",
"bundle_column_error.network.title": "Erra de retage",
"bundle_column_error.retry": "Provar denov",
"bundle_column_error.return": "Retornar al comense",
"bundle_column_error.routing.body": "Li demandat págine ne trovat se. Esque tu es cert que li URL in li adresse-barre es corect?",
"bundle_column_error.routing.title": "404",
"bundle_modal_error.close": "Cluder",
"bundle_modal_error.message": "Alquo errat durant li cargation de ti-ci componente.",
"bundle_modal_error.retry": "Provar denov",
"closed_registrations.other_server_instructions": "Pro que Mastodon es decentralisat, on posse crear un conto che un altri servitor e ancor interacter con ti-ci.",
"closed_registrations_modal.description": "Crear un conto che {domain} ne es possibil actualmen, ma ples memorar que on ne besona un conto specificmen che {domain} por usar Mastodon.",
"closed_registrations_modal.find_another_server": "Serchar altri servitor",
"closed_registrations_modal.preamble": "Mastodon es descentralisat, do on posse ser e interacter con quicunc che ti-ci servitor, sin egarda de u on crea su conto. On mem posse self-albergar it!",
"closed_registrations_modal.title": "Registrar sur Mastodon",
"column.about": "Information",
"column.blocks": "Bloccat usatores",
"column.bookmarks": "Marcatores",
"column.community": "Local témpor-linea",
"column.direct": "Privat mentiones",
"column.directory": "Navigar profiles",
"column.domain_blocks": "Bloccat dominia",
"column.favourites": "Favorites",
"column.firehose": "Témpor-lineas",
"column.follow_requests": "Petitiones de sequer",
"column.home": "Comense",
"column.lists": "Listes",
"column.mutes": "Silentiat usatores",
"column.notifications": "Notificationes",
"column.pins": "Pinglat postas",
"column.public": "Federat témpor-linea",
"column_back_button.label": "Retornar",
"column_header.hide_settings": "Celar parametres",
"column_header.moveLeft_settings": "Mover columne al levul",
"column_header.moveRight_settings": "Mover columne al dextri",
"column_header.pin": "Pinglar",
"column_header.show_settings": "Monstrar parametres",
"column_header.unpin": "Despinglar",
"column_subheading.settings": "Parametres",
"community.column_settings.local_only": "Solmen local",
"community.column_settings.media_only": "Solmen medie",
"community.column_settings.remote_only": "Solmen external",
"compose.language.change": "Changear lingue",
"compose.language.search": "Serchar lingues...",
"compose.published.body": "Posta publicat.",
"compose.published.open": "Aperter",
"compose.saved.body": "Posta conservat.",
"compose_form.direct_message_warning_learn_more": "Aprender plu",
"compose_form.hashtag_warning": "Ti-ci posta ne va esser listat sur quelcunc hashtag pro que it ne es public. Solmen public postas posse esser serchat per hashtag.",
"compose_form.lock_disclaimer": "Tui conto ne es {locked}. Quicunc posse sequer te por vider tui postas solmen por sequitores.",
"compose_form.lock_disclaimer.lock": "cludet",
"compose_form.placeholder": "Quo es in tui spiritu?",
"compose_form.poll.add_option": "Adjunter un option",
"compose_form.poll.duration": "Duration del balotation",
"compose_form.poll.option_placeholder": "Option {number}",
"compose_form.poll.remove_option": "Remover ti-ci option",
"compose_form.poll.switch_to_multiple": "Changea li balotation por permisser multiplic selectiones",
"compose_form.poll.switch_to_single": "Changea li balotation por permisser un singul selection",
"compose_form.publish": "Publicar",
"compose_form.publish_form": "Nov posta",
"compose_form.publish_loud": "{publish}!",
"compose_form.save_changes": "Conservar changes",
"compose_form.sensitive.hide": "{count, plural, one {Marcar medie quam sensitiv} other {Marcar medie quam sensitiv}}",
"compose_form.sensitive.marked": "{count, plural, one {Medie es marcat quam sensitiv} other {Medie es marcat quam sensitiv}}",
"compose_form.sensitive.unmarked": "{count, plural, one {Medie ne es marcat quam sensitiv} other {Medie ne es marcat quam sensitiv}}",
"compose_form.spoiler.marked": "Remover avise pri li contenete",
"compose_form.spoiler.unmarked": "Adjunter avise pri li contenete",
"compose_form.spoiler_placeholder": "Scri tui avise ci",
"confirmation_modal.cancel": "Anullar",
"confirmations.block.block_and_report": "Bloccar & Raportar",
"confirmations.block.confirm": "Bloccar",
"confirmations.block.message": "Esque tu vermen vole bloccar {name}?",
"confirmations.cancel_follow_request.confirm": "Retraer petition",
"confirmations.cancel_follow_request.message": "Esque tu vermen vole retraer tui petition sequer {name}?",
"confirmations.delete.confirm": "Deleter",
"confirmations.delete.message": "Esque tu vermen vole deleter ti-ci posta?",
"confirmations.delete_list.confirm": "Deleter",
"confirmations.delete_list.message": "Esque tu vermen vole permanentmen deleter ti-ci liste?",
"confirmations.discard_edit_media.confirm": "Forjettar",
"confirmations.discard_edit_media.message": "Tu have ínconservat changes al descrition de medie o al previse, forjettar les sin egarda?",
"confirmations.domain_block.confirm": "Bloccar li tot dominia",
"confirmations.domain_block.message": "Esque tu es certissim que tu vole bloccar li tot {domain}? In mult casus, bloccar o silentiar quelc specific contos es suficent e preferibil. Tu ne va vider contenete de ti dominia in quelcunc public témpor-linea o in tui notificationes. Tui sequitores de ti dominia va esser removet.",
"confirmations.edit.confirm": "Redacter",
"confirmations.edit.message": "Redacter nu va remplazzar li missage quel tu actualmen composi. Esque tu vermen vole proceder?",
"confirmations.logout.confirm": "Exear",
"confirmations.logout.message": "Esque tu vermen vole exear?",
"confirmations.mute.confirm": "Silentiar",
"confirmations.mute.explanation": "To-ci va celar postas de ilu e postas mentionant ilu, ma it ancor va permisser ilu vider tui postas e sequer te.",
"confirmations.mute.message": "Esque tu vermen vole silentiar {name}?",
"confirmations.redraft.confirm": "Deleter & redacter",
"confirmations.redraft.message": "Esque tu vermen vole deleter ti-ci posta e redacter it? Favorites e boosts va esser perdit, e responses al posta original va esser orfanat.",
"confirmations.reply.confirm": "Responder",
"confirmations.reply.message": "Responder nu va remplazzar li missage quel tu actualmen composi. Esque tu vermen vole proceder?",
"confirmations.unfollow.confirm": "Dessequer",
"confirmations.unfollow.message": "Esque tu vermen vole dessequer {name}?",
"conversation.delete": "Deleter conversation",
"conversation.mark_as_read": "Marcar quam leet",
"conversation.open": "Vider conversation",
"conversation.with": "Con {names}",
"copypaste.copied": "Copiat",
"directory.federated": "Del conosset fediverse",
"directory.local": "De solmen {domain}",
"directory.new_arrivals": "Nov arivantes",
"directory.recently_active": "Recentmen activ",
"disabled_account_banner.account_settings": "Parametres del conto",
"dismissable_banner.community_timeline": "Tis-ci es li postas max recent de gente con contos che {domain}.",
"dismissable_banner.dismiss": "Demisser",
"dismissable_banner.explore_links": "Tis-ci es li novas max distribuet che li social retage hodie. Novas plu nov, postat de plu diferent persones, es monstrat plu alt.",
"dismissable_banner.explore_statuses": "Tis-ci es postas del social retage queles es popular hodie. Nov postas con plu mult boosts e favorites es monstrat plu alt.",
"dismissable_banner.explore_tags": "Tis-ci es hashtags queles es popular che li social retage hodie. Hashtags usat de plu mult persones diferent es monstrat plu alt.",
"dismissable_banner.public_timeline": "Tis-ci es li max recent public postas de persones che li social retage quem gente che {domain} seque.",
"embed.instructions": "Inbedar ti-ci posta per copiar li code in infra.",
"embed.preview": "Vi qualmen it va aspecter:",
"emoji_button.activity": "Activitá",
"emoji_button.clear": "Efaciar",
"emoji_button.custom": "Custom",
"emoji_button.flags": "Flaggas",
"emoji_button.food": "Manjage & Trincage",
"emoji_button.label": "Inserter emoji",
"emoji_button.nature": "Natura",
"emoji_button.not_found": "Null acordant emoji trovat",
"emoji_button.objects": "Objectes",
"emoji_button.people": "Gente",
"emoji_button.recent": "Frequentmen usat",
"emoji_button.search": "Sercha...",
"emoji_button.search_results": "Resultates de sercha",
"emoji_button.symbols": "Simboles",
"emoji_button.travel": "Viageation & Locos",
"empty_column.account_hides_collections": "Ti-ci usator ha selectet ne publicar ti-ci information",
"empty_column.account_suspended": "Conto suspendet",
"empty_column.account_timeline": "Null postas ci!",
"empty_column.account_unavailable": "Profil índisponibil",
"empty_column.blocks": "Tu ancor ha bloccat null usatores.",
"empty_column.bookmarked_statuses": "Tu ancor have null marcat postas. Quande tu marca un, it va aparir ci.",
"empty_column.community": "Li local témpor-linea es vacui. Scri alquo publicmen por initiar la festa!",
"empty_column.direct": "Tu ancor have null privat mentiones. Quande tu misse o recive un, it va aparir ci.",
"empty_column.domain_blocks": "Ancor hay null bloccat dominias.",
"empty_column.explore_statuses": "Nequo es popular actualmen. Retorna plu tarde!",
"empty_column.favourited_statuses": "Tu ancor have null favorit postas. Quande tu favoritisa un, it va aparir ci.",
"empty_column.favourites": "Ancor nequi ha favoritisat ti-ci posta. Quande alqui fa it, ilu va aparir ci.",
"empty_column.follow_requests": "Tu ancor have null petitiones de sequer. Quande tu recive un, it va aparir ci.",
"empty_column.followed_tags": "Tu ancor ha sequet null hashtags. Quande tu seque un, it va aparir ci.",
"empty_column.hashtag": "Hay nullcos en ti-ci hashtag ancor.",
"empty_column.home": "Tui hemal témpor-linea es vacui! Sequer plu gente por plenar it.",
"empty_column.list": "Ancor ne hay quocunc in ti-ci liste. Quande membres de ti-ci liste publica nov postas, ili va aparir ci.",
"empty_column.lists": "Tu ancor have null listes. Quande tu crea un, it va aparir ci.",
"empty_column.mutes": "Tu ancor ha silentiat null usatores.",
"empty_column.notifications": "Tu have null notificationes. Quande altri persones interacte con te, tu va vider it ci.",
"empty_column.public": "Hay nullcos ci! Scri alquo publicmen, o manualmen seque usatores de altri servitores por plenar to-ci",
"error.unexpected_crash.explanation": "Pro un error in nor code o un problema de compatibilitá in li navigator, ti-ci págine ne posset esser monstrat correctmen.",
"error.unexpected_crash.explanation_addons": "Ti-ci págine ne posset esser monstrat correctmen. Li error es probabilmen causat de un extension al navigator o instrumentes por automatic traduction.",
"error.unexpected_crash.next_steps": "Prova recargar li págine. Si to ne auxilia, tu fórsan posse usar Mastodon per un diferent navigator o aplication.",
"error.unexpected_crash.next_steps_addons": "Prova desactivisar les e recargar li págine. Si to ne auxilia, tu fórsan posse usar Mastodon per un diferent navigator o aplication.",
"errors.unexpected_crash.report_issue": "Raportar un problema",
"explore.search_results": "Resultates de sercha",
"explore.suggested_follows": "Gente",
"explore.title": "Explorar",
"explore.trending_links": "Novas",
"explore.trending_statuses": "Postas",
"explore.trending_tags": "Hashtags",
"filter_modal.added.context_mismatch_explanation": "Ti-ci filtre-categorie ne aplica al contextu in quel tu ha accessat ti-ci posta. Si tu vole que li posta es filtrat anc in ti-ci contextu, tu deve redacter li filtre.",
"filter_modal.added.context_mismatch_title": "Contextu íncompatibil!",
"filter_modal.added.expired_explanation": "Ti-ci filtre-categorie ha expirat, tu deve changear li date de expiration por far it aplicar.",
"filter_modal.added.expired_title": "Expirat filtre!",
"filter_modal.added.review_and_configure": "Por reviser e configurar ti-ci filtre-categorie, ea a {settings_link}.",
"filter_modal.added.review_and_configure_title": "Parametres pri filtres",
"filter_modal.added.settings_link": "págine por parametres",
"filter_modal.added.short_explanation": "Ti-ci post ha esset adjuntet al sequente filtre-categorie: {title}.",
"filter_modal.added.title": "Filtre adjuntet!",
"filter_modal.select_filter.context_mismatch": "ne aplica a ti-ci contextu",
"filter_modal.select_filter.expired": "expirat",
"filter_modal.select_filter.prompt_new": "Nov categorie: {name}",
"filter_modal.select_filter.search": "Serchar o crear",
"filter_modal.select_filter.subtitle": "Usar un existent categorie o crear nov",
"filter_modal.select_filter.title": "Filtrar ti-ci posta",
"filter_modal.title.status": "Filtrar un posta",
"firehose.all": "Omno",
"firehose.local": "Ti-ci servitor",
"firehose.remote": "Altri servitores",
"follow_request.authorize": "Autorisar",
"follow_request.reject": "Rejecter",
"follow_requests.unlocked_explanation": "Benque tu conto ne es cludet, li administratores de {domain} pensat que tu fórsan vell voler tractar seque-petitiones de tis-ci contos manualmen.",
"followed_tags": "Sequet hashtags",
"footer.about": "Information",
"footer.directory": "Profilarium",
"footer.get_app": "Obtener li aplication",
"footer.invite": "Invitar gente",
"footer.privacy_policy": "Politica pri privatie",
"footer.source_code": "Vider li fonte-code",
"footer.status": "Statu",
"generic.saved": "Conservat",
"getting_started.heading": "Qualmen comensar",
"hashtag.column_header.tag_mode.all": "e {additional}",
"hashtag.column_header.tag_mode.any": "o {additional}",
"hashtag.column_header.tag_mode.none": "sin {additional}",
"hashtag.column_settings.select.no_options_message": "Null suggestiones trovat",
"hashtag.column_settings.select.placeholder": "Inscrir hashtags…",
"hashtag.column_settings.tag_mode.all": "Omni tis",
"hashtag.column_settings.tag_mode.any": "Quelcunc de tis",
"hashtag.column_settings.tag_mode.none": "Necun de tis",
"hashtag.column_settings.tag_toggle": "Include additional hashtags in ti-ci columne",
"hashtag.counter_by_accounts": "{count, plural, one {{counter} participante} other {{counter} participantes}}",
"hashtag.counter_by_uses": "{count, plural, one {{counter} posta} other {{counter} postas}}",
"hashtag.counter_by_uses_today": "{count, plural, one {{counter} posta} other {{counter} postas}} hodie",
"hashtag.follow": "Sequer hashtag",
"hashtag.unfollow": "Dessequer hashtag",
"hashtags.and_other": "…e {count, plural, other {# in plu}}",
"home.actions.go_to_explore": "Vider lu populari",
"home.actions.go_to_suggestions": "Trovar gente por sequer",
"home.column_settings.basic": "Basic",
"home.column_settings.show_reblogs": "Monstrar boosts",
"home.column_settings.show_replies": "Monstrar responses",
"home.explore_prompt.body": "Tui hemal témpor-linea have un mixtura del hashtags queles tu selectet sequer, li gente quem tu selectet sequer, e li postas queles ili boosta. Si to sembla tro quiet, tu fórsan vole:",
"home.explore_prompt.title": "To-ci es tui hemal págine in Mastodon.",
"home.hide_announcements": "Celar proclamationes",
"home.pending_critical_update.body": "Ples actualisar tui Mastodon-servitor tam rapid quam es possibil!",
"home.pending_critical_update.link": "Vider actualisationes",
"home.pending_critical_update.title": "Urgent actualisation de securitá disponibil!",
"home.show_announcements": "Monstrar proclamationes",
"interaction_modal.description.favourite": "Con un conto de Mastodon, tu posse favoritisar ti-ci posta por informar li autor pri quant mult tu aprecia it e conservar it por plu tard.",
"interaction_modal.description.follow": "Con un conto de Mastodon, tu posse sequer {name} por reciver su postas in tui hemal témpor-linea.",
"interaction_modal.description.reblog": "Con un conto de Mastodon, tu posse boostar ti-ci posta por distribuer it a tui propri sequitores.",
"interaction_modal.description.reply": "Con un conto de Mastodon, tu posse responder a ti-ci posta.",
"interaction_modal.login.action": "Retorna a hem",
"interaction_modal.login.prompt": "Dominia de tui hemal servitor, p.ex. mastodon.social",
"interaction_modal.no_account_yet": "Ne sur Mastodon?",
"interaction_modal.on_another_server": "Sur un servitor diferent",
"interaction_modal.on_this_server": "Sur ti-ci servitor",
"interaction_modal.sign_in": "Tu ne ha initiat session che ti-ci servitor. U logia tui conto?",
"interaction_modal.title.favourite": "Favoritisar li posta de {name}",
"interaction_modal.title.follow": "Sequer {name}",
"interaction_modal.title.reblog": "Boostar li posta de {name}",
"interaction_modal.title.reply": "Responder al posta de {name}",
"intervals.full.days": "{number, plural, one {# die} other {# dies}}",
"intervals.full.hours": "{number, plural, one {# hor} other {# hores}}",
"intervals.full.minutes": "{number, plural, one {# minute} other {# minutes}}",
"keyboard_shortcuts.back": "Retroear",
"keyboard_shortcuts.blocked": "Aperter li lista de bloccat usatores",
"keyboard_shortcuts.boost": "Boostar posta",
"keyboard_shortcuts.column": "Infocar columne",
"keyboard_shortcuts.compose": "Infocar li text-area de composition",
"keyboard_shortcuts.description": "Descrition",
"keyboard_shortcuts.direct": "por aperter li columne de privat mentiones",
"keyboard_shortcuts.down": "Mover ad-infra in li liste",
"keyboard_shortcuts.enter": "Aperter posta",
"keyboard_shortcuts.favourite": "Favoritisar posta",
"keyboard_shortcuts.favourites": "Aperter li liste de favorites",
"keyboard_shortcuts.federated": "Aperter li federat témpor-linea",
"keyboard_shortcuts.home": "Aperter li hemal témpor-linea",
"keyboard_shortcuts.local": "Aperter li local témpor-linea",
"keyboard_shortcuts.mention": "Mentionar li autor",
"keyboard_shortcuts.muted": "Aperter li lista de silentiat usatores",
"keyboard_shortcuts.my_profile": "Aperter tui profil",
"keyboard_shortcuts.notifications": "Aperter li columne de notificationes",
"keyboard_shortcuts.open_media": "Aperter medie",
"keyboard_shortcuts.pinned": "Aperter li liste de pinglat postas",
"keyboard_shortcuts.profile": "Aperter profil del autor",
"keyboard_shortcuts.reply": "Responder al posta",
"keyboard_shortcuts.requests": "Aperter liste de seque-petitiones",
"keyboard_shortcuts.toggle_sensitivity": "Monstrar/celar medie",
"keyboard_shortcuts.toot": "Crear un nov posta",
"keyboard_shortcuts.up": "Mover ad-supra in li liste",
"lightbox.close": "Cluder",
"lightbox.next": "Sequent",
"lightbox.previous": "Precedent",
"limited_account_hint.action": "Monstrar profil totvez",
"limited_account_hint.title": "Ti-ci profil ha esset celat del moderatores de {domain}.",
"link_preview.author": "De {name}",
"lists.account.add": "Adjunter a liste",
"lists.account.remove": "Remover de liste",
"lists.delete": "Deleter liste",
"lists.edit": "Redacter liste",
"lists.edit.submit": "Changear titul",
"lists.exclusive": "Celar ti-ci postas del hemal témpor-linea",
"lists.new.create": "Adjunter liste",
"lists.new.title_placeholder": "Titul del nov liste",
"lists.replies_policy.followed": "Quelcunc sequet usator",
"lists.replies_policy.list": "Membres del liste",
"lists.replies_policy.none": "Nequi",
"lists.replies_policy.title": "Monstrar responses a:",
"lists.search": "Serchar inter li persones quem tu seque",
"lists.subheading": "Tui listes",
"load_pending": "{count, plural, one {# nov element} other {# nov elementes}}",
"loading_indicator.label": "Cargant…",
"media_gallery.toggle_visible": "{number, plural, one {Celar image} other {Celar images}}",
"moved_to_account_banner.text": "Tui conto {disabledAccount} es actualmen desactivisat pro que tu movet te a {movedToAccount}.",
"mute_modal.duration": "Duration",
"mute_modal.hide_notifications": "Celar notificationes de ti-ci usator?",
"mute_modal.indefinite": "Índefinit",
"navigation_bar.about": "Information",
"navigation_bar.blocks": "Bloccat usatores",
"navigation_bar.bookmarks": "Marcatores",
"navigation_bar.community_timeline": "Local témpor-linea",
"navigation_bar.compose": "Composir un nov posta",
"navigation_bar.direct": "Privat mentiones",
"navigation_bar.discover": "Decovrir",
"navigation_bar.domain_blocks": "Bloccat dominias",
"navigation_bar.edit_profile": "Redacter profil",
"navigation_bar.explore": "Explorar",
"navigation_bar.favourites": "Favorites",
"navigation_bar.filters": "Silentiat paroles",
"navigation_bar.follow_requests": "Petitiones de sequer",
"navigation_bar.followed_tags": "Sequet hashtags",
"navigation_bar.follows_and_followers": "Sequetes e sequitores",
"navigation_bar.lists": "Listes",
"navigation_bar.logout": "Exear",
"navigation_bar.mutes": "Silentiat usatores",
"navigation_bar.personal": "Personal",
"navigation_bar.pins": "Pinglat postas",
"navigation_bar.preferences": "Preferenties",
"navigation_bar.public_timeline": "Federat témpor-linea",
"navigation_bar.search": "Sercha",
"navigation_bar.security": "Securitá",
"not_signed_in_indicator.not_signed_in": "On deve aperter session por accesser ti-ci ressurse.",
"notification.admin.report": "{name} raportat {target}",
"notification.admin.sign_up": "{name} adheret",
"notification.favourite": "{name} favoritisat tui posta",
"notification.follow": "{name} sequet te",
"notification.follow_request": "{name} ha petit sequer te",
"notification.mention": "{name} mentionat te",
"notification.own_poll": "Tui balotation ha finit",
"notification.poll": "Un balotation in quel tu votat ha finit",
"notification.reblog": "{name} boostat tui posta",
"notification.status": "{name} just postat",
"notification.update": "{name} modificat un posta",
"notifications.clear": "Aclarar notificationes",
"notifications.clear_confirmation": "Vole tu vermen permanentmen aclarar omni tui notificationes?",
"notifications.column_settings.admin.report": "Nov raportas:",
"notifications.column_settings.admin.sign_up": "Nov registrationes:",
"notifications.column_settings.favourite": "Favorites:",
"notifications.column_settings.filter_bar.advanced": "Monstrar omni categories",
"notifications.column_settings.follow": "Nov sequitores:",
"notifications.column_settings.follow_request": "Nov petitiones de sequer:",
"notifications.column_settings.mention": "Mentiones:",
"notifications.column_settings.poll": "Resultates del balotation:",
"notifications.column_settings.reblog": "Boosts:",
"notifications.column_settings.show": "Monstrar in columne",
"notifications.column_settings.sound": "Far son",
"notifications.column_settings.status": "Nov postas:",
"notifications.column_settings.unread_notifications.category": "Ínleet notificationes",
"notifications.column_settings.unread_notifications.highlight": "Marcar ínleet notificationes",
"notifications.column_settings.update": "Redactiones:",
"notifications.filter.all": "Omni",
"notifications.filter.boosts": "Boosts",
"notifications.filter.favourites": "Favorites",
"notifications.filter.follows": "Seques",
"notifications.filter.mentions": "Mentiones",
"notifications.filter.polls": "Resultates del balotation",
"notifications.filter.statuses": "Actualisationes de gente quem tu seque",
"notifications.grant_permission": "Dar permission.",
"notifications.group": "{count} notificationes",
"notifications.mark_as_read": "Marcar omni notificationes quam leet",
"onboarding.action.back": "Retroear",
"onboarding.actions.back": "Retroear",
"onboarding.actions.go_to_explore": "Ear a vider lu populari",
"onboarding.actions.go_to_home": "Ear al hemal témpor-linea",
"onboarding.compose.template": "Salute #Mastodon!",
"onboarding.follows.empty": "Ínfortunatmen, null resultates posse esser monstrat actualmen. Tu posse provar serchar o usar li \"Explorar\" págine por trovar gente por sequer, o prova denov plu tard.",
"onboarding.follows.lead": "Tui hemal témpor-linea es li primari maniere de experir Mastodon. Plu persones quem tu seque, plu activ e interessant it va esser. Por auxiliar te comensar, vi quelc suggestiones:",
"onboarding.follows.title": "Personalisar tui hemal témpor-linea",
"onboarding.profile.discoverable": "Fa mi profil decovribil",
"onboarding.profile.discoverable_hint": "Quande tu opta esser decovribil in Mastodon, tui postas posse aparir in resultates de sercha e tendenties, e tui profil posse esser suggestet a persones con interesses simil a tui.",
"onboarding.profile.display_name": "Nómine a monstrar",
"onboarding.profile.display_name_hint": "Tui complet nómine o tui amusant nómine…",
"onboarding.profile.lead": "Tu sempre posse completar ti-ci plu tard in li parametres, u mem plu optiones de customisation es disponibil.",
"onboarding.profile.note": "Biografie",
"onboarding.profile.note_hint": "Tu posse @mentionar altri persones o #hashtags…",
"onboarding.profile.save_and_continue": "Conservar e avansar",
"onboarding.profile.title": "Popular tu profil",
"onboarding.profile.upload_avatar": "Cargar profil-portrete",
"onboarding.profile.upload_header": "Cargar cap-image",
"onboarding.share.lead": "Di gente qualmen ili posse trovar te che Mastodon!",
"onboarding.share.message": "Yo es {username} che #Mastodon! Veni e seque me a {url}",
"onboarding.share.next_steps": "Possibil sequent passus:",
"onboarding.share.title": "Partir tui profil",
"onboarding.start.lead": "Tu es ja un parte de Mastodon, un unic, decentralisat platform de medie social in quel tu—ne un algoritme—selectiona tui propri experientie. Lass nos departer sur un nov frontiera social:",
"onboarding.start.skip": "Auxilie por comensar ne besonat?",
"onboarding.start.title": "Tu ha successat!",
"onboarding.steps.follow_people.body": "Sequer interessant gente es to quo importa in Mastodon.",
"onboarding.steps.follow_people.title": "Personalisar tui hemal témpor-linea",
"onboarding.steps.publish_status.body": "Saluta li munde con text, images, videos o balotationes {emoji}",
"onboarding.steps.publish_status.title": "Crear tui unesim posta",
"onboarding.steps.setup_profile.title": "Personalisar tui profil",
"onboarding.steps.share_profile.body": "Di tui amics qualmen trovar te che Mastodon",
"onboarding.steps.share_profile.title": "Partir tui profil Mastodon",
"password_confirmation.exceeds_maxlength": "Confirmation de passa-parol transpassa li maxim longore de passa-paroles",
"password_confirmation.mismatching": "Confirmation de passa-parol ne egala",
"picture_in_picture.restore": "Restaurar",
"poll.closed": "Finit",
"poll.refresh": "Recargar",
"poll.reveal": "Vider resultates",
"poll.total_people": "{count, plural, one {# person} other {# persones}}",
"poll.total_votes": "{count, plural, one {# vote} other {# votes}}",
"poll.vote": "Votar",
"poll.voted": "Tu votat por ti-ci option",
"poll.votes": "{votes, plural, one {# vote} other {# votes}}",
"poll_button.add_poll": "Adjunter un balotation",
"poll_button.remove_poll": "Remover balotation",
"privacy.change": "Changear li privatie del posta",
"privacy.direct.long": "Visibil solmen a mentionat usatores",
"privacy.direct.short": "Solmen persones mentionat",
"privacy.private.long": "Visibil solmen por sequitores",
"privacy.private.short": "Solmen sequitores",
"privacy.public.long": "Visibil a omnes",
"privacy.public.short": "Public",
"privacy.unlisted.long": "Visibil por omnes, ma excludet de functiones de decovrition",
"privacy.unlisted.short": "Delistat",
"privacy_policy.last_updated": "Ultimmen actualisat ye {date}",
"privacy_policy.title": "Politica pri Privatie",
"recommended": "Recomandat",
"refresh": "Recargar",
"regeneration_indicator.label": "Cargant…",
"regeneration_indicator.sublabel": "On es preparant tui hemal témpor-linea!",
"relative_time.days": "{number}d",
"relative_time.full.days": "Ante {number, plural, one {# die} other {# dies}}",
"relative_time.full.hours": "Ante {number, plural, one {# hor} other {# hores}}",
"relative_time.full.just_now": "just nu",
"relative_time.full.minutes": "Ante {number, plural, one {# minute} other {# minutes}}",
"relative_time.full.seconds": "Ante {number, plural, one {# second} other {# secondes}}",
"relative_time.hours": "{number}h",
"relative_time.just_now": "nu",
"relative_time.minutes": "{number}m",
"relative_time.seconds": "{number}s",
"relative_time.today": "hodie",
"reply_indicator.cancel": "Anullar",
"report.block": "Bloccar",
"report.block_explanation": "Tu ne va vider su postas. Li usator ni va posser vider tui postas, ni sequer te, ni va posser saver pri li statu de esser bloccat.",
"report.categories.legal": "Legal",
"report.categories.other": "Altricos",
"report.categories.spam": "Spam",
"report.categories.violation": "Contenete violant un o pluri regules del servitor",
"report.category.subtitle": "Selecte li max bon option",
"report.category.title": "Di nos quo passa con ti-ci {type}",
"report.category.title_account": "profil",
"report.category.title_status": "posta",
"report.close": "Finit",
"report.comment.title": "Hay alquo plu quel tu pensa que noi deve saver?",
"report.forward": "Misser anc a {target}",
"report.forward_hint": "Ti-ci conto es de un altri servitor. Misser un anonimisat copie del raporte anc a ta?",
"report.mute": "Silentiar",
"report.mute_explanation": "Tu ne va vider su postas. Ilu ancor posse sequer te e vider tui postas e ne va saver que ilu es silentiat.",
"report.next": "Sequent",
"report.placeholder": "Additional comentas",
"report.reasons.dislike": "It ne plese me",
"report.reasons.dislike_description": "It es alquo quel displese te",
"report.reasons.legal": "It es ínlegal",
"report.reasons.legal_description": "Tu crede que it viola un lege del land de te o de tui servitor",
"report.reasons.other": "It es altricos",
"report.reasons.other_description": "Li problema ne apartene in li altri categories",
"report.reasons.spam": "It es spam",
"report.reasons.spam_description": "Maliciosi ligamentes, fals activitá, o repetitiv responses",
"report.reasons.violation": "It viola li regules del servitor",
"report.reasons.violation_description": "Tu save que it viola specific regules",
"report.rules.subtitle": "Selecte omnes queles aplica",
"report.rules.title": "Quel regules es violat?",
"report.statuses.subtitle": "Selecte omnes queles aplica",
"report.statuses.title": "Hay postas queles posse subtener ti-ci raporte?",
"report.submit": "Misser",
"report.target": "Raportant {target}",
"report.thanks.take_action": "Tis-ci es tui optiones por controlar ti quel tu vide che Mastodon:",
"report.thanks.take_action_actionable": "Durante que noi tracta ti-ci, tu posse far lu sequent contra @{name}:",
"report.thanks.title": "Vole tu ne vider to?",
"report.thanks.title_actionable": "Mersí pro raportar, noi va investigar to.",
"report.unfollow": "Dessequer @{name}",
"report.unfollow_explanation": "Tu seque ti-ci conto. Por ne vider su postas en tui hemal témpor-linea, dessequer it.",
"report_notification.attached_statuses": "{count, plural, one {{count} posta} other {{count} postas}} atachat",
"report_notification.categories.legal": "Legal",
"report_notification.categories.other": "Altricos",
"report_notification.categories.spam": "Spam",
"report_notification.categories.violation": "Violation de regul",
"report_notification.open": "Aperter raporta",
"search.no_recent_searches": "Null recent serchas",
"search.placeholder": "Serchar",
"search.quick_action.account_search": "Profiles acordant con {x}",
"search.quick_action.go_to_account": "Ear al profil {x}",
"search.quick_action.go_to_hashtag": "Ear al hashtag {x}",
"search.quick_action.open_url": "Aperter URL in Mastodon",
"search.quick_action.status_search": "Postas acordant con {x}",
"search.search_or_paste": "Serchar o glutinar URL",
"search_popout.full_text_search_disabled_message": "Ne disponibil che {domain}.",
"search_popout.full_text_search_logged_out_message": "Solmen disponibil con session initiat.",
"search_popout.options": "Sercha-parametres",
"search_popout.quick_actions": "Rapid actiones",
"search_popout.recent": "Recent serchas",
"search_popout.specific_date": "specific date",
"search_popout.user": "usator",
"search_results.accounts": "Profiles",
"search_results.all": "Omni",
"search_results.hashtags": "Hashtags",
"search_results.nothing_found": "Trovat se nullcos por ti término de sercha",
"search_results.see_all": "Vider omni",
"search_results.statuses": "Postas",
"search_results.title": "Sercha por {q}",
"server_banner.about_active_users": "Gente usant ti-ci servitor durant li ultim 30 dies (Mensual Activ Usatores)",
"server_banner.active_users": "activ usatores",
"server_banner.administered_by": "Administrat de:",
"server_banner.introduction": "{domain} es un part del decentralisat social retage constructet sur {mastodon}.",
"server_banner.learn_more": "Aprender plu",
"server_banner.server_stats": "Statisticas pri li servitor:",
"sign_in_banner.create_account": "Crear un conto",
"sign_in_banner.sign_in": "Intrar",
"sign_in_banner.sso_redirect": "Intrar o registrar se",
"sign_in_banner.text": "Intrar por sequer profiles o hashtags, favoritisar, partir e responder a postas. Tu posse anc interacter per tui conto che un diferent servitor.",
"status.admin_account": "Aperter interfacie de moderation por @{name}",
"status.admin_domain": "Aperter interfacie de moderation por {domain}",
"status.admin_status": "Aperter ti-ci posta in li interfacie de moderation",
"status.block": "Bloccar @{name}",
"status.bookmark": "Marcar",
"status.copy": "Copiar ligament al posta",
"status.delete": "Deleter",
"status.detailed_status": "Detalliat vise de conversation",
"status.direct": "Privatmen mentionar @{name}",
"status.direct_indicator": "Privat mention",
"status.edit": "Modificar",
"status.edited": "Modificat ye {date}",
"status.edited_x_times": "Modificat {count, plural, one {{count} vez} other {{count} vezes}}",
"status.embed": "Inbedar",
"status.favourite": "Favoritisar",
"status.filter": "Filtrar ti-ci posta",
"status.filtered": "Filtrat",
"status.hide": "Celar posta",
"status.history.created": "creat de {name} ye {date}",
"status.history.edited": "modificat de {name} ye {date}",
"status.load_more": "Cargar plu",
"status.media.open": "Cliccar por aperter",
"status.media.show": "Cliccar por monstrar",
"status.media_hidden": "Medie celat",
"status.mention": "Mentionar @{name}",
"status.more": "Plu",
"status.mute": "Silentiar @{name}",
"status.mute_conversation": "Silentiar conversation",
"status.open": "Expander ti-ci posta",
"status.pin": "Pinglar sur profil",
"status.pinned": "Pinglat posta",
"status.read_more": "Leer plu",
"status.redraft": "Deleter & redacter",
"status.remove_bookmark": "Remover marcator",
"status.replied_to": "Respondet a {name}",
"status.reply": "Responder",
"status.replyAll": "Responder al fil",
"status.report": "Raportar @{name}",
"status.sensitive_warning": "Sensitiv contenete",
"status.share": "Partir",
"status.show_filter_reason": "Monstrar totvez",
"status.show_less": "Monstrar minu",
"status.show_less_all": "Monstrar minu por omno",
"status.show_more": "Monstrar plu",
"status.show_more_all": "Monstrar plu por omno",
"status.show_original": "Monstrar li original",
"status.title.with_attachments": "{user} postat {attachmentCount, plural, one {un atachament} other {{attachmentCount} atachamentes}}",
"status.translate": "Traducter",
"status.translated_from_with": "Traductet de {lang} per {provider}",
"status.uncached_media_warning": "Previse ne disponibil",
"status.unmute_conversation": "Dessilentiar conversation",
"status.unpin": "Despinglar de profil",
"subscribed_languages.lead": "Solmen postas in selectet lingues va aparir in tui hemal e listal témpor-lineas pos li change. Selecte null por reciver postas in omni lingues.",
"subscribed_languages.save": "Conservar changes",
"subscribed_languages.target": "Changear abonnat lingues por {target}",
"tabs_bar.home": "Hem",
"tabs_bar.notifications": "Notificationes",
"time_remaining.days": "{number, plural, one {# die} other {# dies}} resta",
"time_remaining.hours": "{number, plural, one {# hor} other {# hores}} resta",
"time_remaining.minutes": "{number, plural, one {# minute} other {# minutes}} resta",
"time_remaining.moments": "Momentes resta",
"time_remaining.seconds": "{number, plural, one {# second} other {# secondes}} resta",
"timeline_hint.remote_resource_not_displayed": "{resource} de altri servitores ne es monstrat.",
"timeline_hint.resources.followers": "Sequitores",
"timeline_hint.resources.follows": "Sequetes",
"timeline_hint.resources.statuses": "Plu old postas",
"trends.counter_by_accounts": "{count, plural, one {{counter} person} other {{counter} persones}} durant li ultim {days, plural, one {die} other {{days} dies}}",
"trends.trending_now": "Actualmen populari",
"ui.beforeunload": "Tui íncomplet posta va esser perdit si tu lassa Mastodon.",
"upload_area.title": "Trenar & lassar cader por cargar",
"upload_button.label": "Adjunter images, un video o un audio-file",
"upload_error.limit": "Límite de medie-cargationes transpassat.",
"upload_error.poll": "On ne es permisset cargar medie con balotationes.",
"upload_form.audio_description": "Descrir por persones qui es surd o ne audi bon",
"upload_form.description": "Descrir por persones qui es ciec o have mal vision",
"upload_form.description_missing": "Null descrition adjuntet",
"upload_form.edit": "Redacter",
"upload_form.thumbnail": "Changear previsual image",
"upload_form.undo": "Deleter",
"upload_form.video_description": "Descrir por persones qui es surd, ciec, ne audi bon, o have mal vision",
"upload_modal.analyzing_picture": "Analisant image…",
"upload_modal.apply": "Aplicar",
"upload_modal.applying": "Aplicant…",
"upload_modal.choose_image": "Selecter image",
"upload_modal.detect_text": "Detecter text del image",
"upload_modal.edit_media": "Redacter medie",
"upload_modal.hint": "Clicca o trena li circul por selecter li focal punctu quel va esser sempre visibil in omni previse-images.",
"upload_modal.preparing_ocr": "Preparant OCR…",
"upload_modal.preview_label": "Previse ({ratio})",
"upload_progress.label": "Cargant...",
"upload_progress.processing": "Tractant…",
"username.taken": "Ti usator-nómine es ja prendet. Trova altri",
"video.close": "Cluder video",
"video.download": "Descargar file",
"video.exit_fullscreen": "Exear plen-ecran",
"video.expand": "Expander video",
"video.fullscreen": "Plen-ecran",
"video.hide": "Celar video",
"video.mute": "Silentiar li son",
"video.pause": "Pausar",
"video.play": "Reproducter",
"video.unmute": "Dessilentiar li son"
}

View file

@ -20,6 +20,7 @@
"account.blocked": "Blokusita",
"account.browse_more_on_origin_server": "Videz pluse che la originala profilo",
"account.cancel_follow_request": "Desendez sequodemando",
"account.copy": "Kopiez ligilo al profilo",
"account.direct": "Private mencionez @{name}",
"account.disable_notifications": "Cesez avizar me kande @{name} postas",
"account.domain_blocked": "Domain hidden",
@ -38,7 +39,8 @@
"account.follows.empty": "Ca uzanto ne sequa irgu til nun.",
"account.follows_you": "Sequas tu",
"account.go_to_profile": "Irez al profilo",
"account.hide_reblogs": "Celez busti de @{name}",
"account.hide_reblogs": "Celez repeti de @{name}",
"account.in_memoriam": "Memorige.",
"account.joined_short": "Juntita",
"account.languages": "Chanjez abonita lingui",
"account.link_verified_on": "Proprieteso di ca ligilo kontrolesis ye {date}",
@ -58,7 +60,7 @@
"account.requested": "Vartante aprobo",
"account.requested_follow": "{name} demandis sequar tu",
"account.share": "Partigez profilo di @{name}",
"account.show_reblogs": "Montrez busti de @{name}",
"account.show_reblogs": "Montrez repeti de @{name}",
"account.statuses_counter": "{count, plural, one {{counter} Posto} other {{counter} Posti}}",
"account.unblock": "Desblokusar @{name}",
"account.unblock_domain": "Desblokusar {domain}",
@ -86,7 +88,7 @@
"attachments_list.unprocessed": "(neprocedita)",
"audio.hide": "Celez audio",
"autosuggest_hashtag.per_week": "{count} dum singla semano",
"boost_modal.combo": "Tu povas presar sur {combo} por omisar co en la venonta foyo",
"boost_modal.combo": "Vu povas pulsar {combo} por omisar co venontafoye",
"bundle_column_error.copy_stacktrace": "Kopierorraporto",
"bundle_column_error.error.body": "La demandita pagino ne povas strukturigesar. Forsan ol esas eroro en kodexo hike o vidilkoncilieblesproblemo.",
"bundle_column_error.error.title": "Ach!",
@ -180,7 +182,7 @@
"confirmations.mute.explanation": "Co celigos posti de oli e posti quo mencionas oli, ma ol ankore permisas oli vidar vua posti e sequar vu.",
"confirmations.mute.message": "Ka vu certe volas silencigar {name}?",
"confirmations.redraft.confirm": "Efacez e riskisez",
"confirmations.redraft.message": "Ka vu certe volas efacar ca posto e riskisigar ol? Favoriziti e busti esos perdita, e respondi al posto originala esos orfanigita.",
"confirmations.redraft.message": "Ka vu certe volas efacar ca posto e riskisigar ol? Favoriziti e repeti esos perdita, e respondi al posto originala esos orfanigita.",
"confirmations.reply.confirm": "Respondez",
"confirmations.reply.message": "Respondar nun remplos mesajo quon vu nun igas. Ka vu certe volas durar?",
"confirmations.unfollow.confirm": "Desequez",
@ -189,6 +191,7 @@
"conversation.mark_as_read": "Markizez quale lektita",
"conversation.open": "Videz konverso",
"conversation.with": "Kun {names}",
"copy_icon_button.copied": "Kopiita",
"copypaste.copied": "Kopiesis",
"copypaste.copy_to_clipboard": "Kopiez",
"directory.federated": "De savita fediverso",
@ -200,7 +203,7 @@
"dismissable_banner.community_timeline": "Co esas maxim recenta publika posti de personi quo havas konto quo hostigesas da {domain}.",
"dismissable_banner.dismiss": "Ignorez",
"dismissable_banner.explore_links": "Ca nova rakonti parolesas da personi che ca e altra servili di necentraligita situo nun.",
"dismissable_banner.explore_statuses": "Yen posti del tota reto sociala qui esas populara hodie. Posti plu nova kun plu busti e favoriziti esas rangizita plu alte.",
"dismissable_banner.explore_statuses": "Yen posti del tota reto sociala qui esas populara hodie. Posti plu nova kun plu repeti e favoriziti esas rangizita plu alte.",
"dismissable_banner.explore_tags": "Ca hashtagi bezonas plu famoza inter personi che ca e altra servili di la necentraligita situo nun.",
"dismissable_banner.public_timeline": "Yen la posti maxim recenta da personi che la reto sociala quin personi che {domain} sequas.",
"embed.instructions": "Embed this status on your website by copying the code below.",
@ -220,6 +223,7 @@
"emoji_button.search_results": "Trovuri",
"emoji_button.symbols": "Simboli",
"emoji_button.travel": "Vizito & Plasi",
"empty_column.account_hides_collections": "Ca uzanto selektis ne publikigar ca informo",
"empty_column.account_suspended": "Konto restriktesis",
"empty_column.account_timeline": "No toots here!",
"empty_column.account_unavailable": "Profilo esas nedisponebla",
@ -294,14 +298,18 @@
"hashtag.column_settings.tag_mode.any": "Irga co",
"hashtag.column_settings.tag_mode.none": "Nula co",
"hashtag.column_settings.tag_toggle": "Include additional tags in this column",
"hashtag.counter_by_accounts": "{count, plural, one {{counter} partoprenanto} other {{counter} partoprenanti}}",
"hashtag.counter_by_uses": "{count, plural, one {{counter} posto} other {{counter} posti}}",
"hashtag.counter_by_uses_today": "{count, plural, one {{counter} posto} other {{counter} posti}} hodie",
"hashtag.follow": "Sequez hashtago",
"hashtag.unfollow": "Desequez hashtago",
"hashtags.and_other": "…e {count, plural, one {# plusa}other {# plusa}}",
"home.actions.go_to_explore": "Videz quo es populara nun",
"home.actions.go_to_suggestions": "Trovez personi por sequar",
"home.column_settings.basic": "Simpla",
"home.column_settings.show_reblogs": "Montrar repeti",
"home.column_settings.show_replies": "Montrar respondi",
"home.explore_prompt.body": "Vua hemala fluo havos mixuro de la hashtagi quin vu selektis sequar, la personi quin vu selektis sequar, e la posti quin ili bustis. Se to semblas tro tacanta, vu darfas volar:",
"home.explore_prompt.body": "Vua hemala fluo havos mixuro de la hashtagi quin vu selektis sequar, la personi quin vu selektis sequar, e la posti quin ili repetis. Se to semblas tro tacanta, vu darfas volar:",
"home.explore_prompt.title": "Co es vua hemo en Mastodon.",
"home.hide_announcements": "Celez anunci",
"home.pending_critical_update.body": "Voluntez aktualigar vua Mastodon-servilo tam balde kam es posibla!",
@ -310,7 +318,7 @@
"home.show_announcements": "Montrez anunci",
"interaction_modal.description.favourite": "Kun konto che Mastodon, vu povas favorizar ca posto por savigar la autoro ke vu prizas ol e sparar ol por pose.",
"interaction_modal.description.follow": "Per konto che Mastodon, vu povas sequar {name} por ganar ola posti en vua hemniuzeto.",
"interaction_modal.description.reblog": "Per konto che Mastodon, vu povas bustizar ca posti por partigar kun sua sequanti.",
"interaction_modal.description.reblog": "Per konto che Mastodon, vu povas repetar ca posti por dissemar lo a vua propra sequati.",
"interaction_modal.description.reply": "Per konto che Mastodon, vu povas respondar ca posto.",
"interaction_modal.login.action": "Irar a hemo",
"interaction_modal.login.prompt": "Domeno di vua hemala servilo, ex. mastodon.social",
@ -321,14 +329,14 @@
"interaction_modal.sign_in_hint": "Averto: To es la retsituo ube vu kreis konto. Se vu ne rimemoras, serchez vua bonvenanta e-posto. Vu anke povas enpozar vua kompleta uzantnomo! (ex. @Mastodon@mastodon.social)",
"interaction_modal.title.favourite": "Favorizez ca posto da {name}",
"interaction_modal.title.follow": "Sequez {name}",
"interaction_modal.title.reblog": "Bustizez posto di {name}",
"interaction_modal.title.reblog": "Repetez posto di {name}",
"interaction_modal.title.reply": "Respondez posto di {name}",
"intervals.full.days": "{number, plural, one {# dio} other {# dii}}",
"intervals.full.hours": "{number, plural, one {# horo} other {# hori}}",
"intervals.full.minutes": "{number, plural, one {# minuto} other {# minuti}}",
"keyboard_shortcuts.back": "to navigate back",
"keyboard_shortcuts.blocked": "to open blocked users list",
"keyboard_shortcuts.boost": "to boost",
"keyboard_shortcuts.boost": "Repetez posto",
"keyboard_shortcuts.column": "to focus a status in one of the columns",
"keyboard_shortcuts.compose": "to focus the compose textarea",
"keyboard_shortcuts.description": "Deskripto",
@ -383,6 +391,7 @@
"lists.search": "Trovez inter personi quon vu sequas",
"lists.subheading": "Vua listi",
"load_pending": "{count, plural, one {# nova kozo} other {# nova kozi}}",
"loading_indicator.label": "Kargante…",
"media_gallery.toggle_visible": "Chanjar videbleso",
"moved_to_account_banner.text": "Vua konto {disabledAccount} es nune desaktiva pro ke vu movis a {movedToAccount}.",
"mute_modal.duration": "Durado",
@ -448,7 +457,7 @@
"notifications.column_settings.unread_notifications.highlight": "Briligez nelektita avizi",
"notifications.column_settings.update": "Modifikati:",
"notifications.filter.all": "Omna",
"notifications.filter.boosts": "Busti",
"notifications.filter.boosts": "Repeti",
"notifications.filter.favourites": "Favoriziti",
"notifications.filter.follows": "Sequati",
"notifications.filter.mentions": "Mencioni",
@ -471,6 +480,17 @@
"onboarding.follows.empty": "Regretinde, nula rezultajo povas montresar nune. Vu povas esforcar serchar, o irar al explorala pagino por trovar personi sequinda, o esforcar itere pose.",
"onboarding.follows.lead": "You curate your own home feed. The more people you follow, the more active and interesting it will be. These profiles may be a good starting point—you can always unfollow them later!",
"onboarding.follows.title": "Popular on Mastodon",
"onboarding.profile.discoverable": "Trovebligez mea profilo",
"onboarding.profile.discoverable_hint": "Se vu selektas deskovrebleso che Mastodon, vua posti povas aparar en sercho-rezultaji e populari, e vua profilo forsan sugestesos a personi kun interesi simila a vua.",
"onboarding.profile.display_name": "Publika nomo",
"onboarding.profile.display_name_hint": "Vua tota nomo o vua gaya nomo…",
"onboarding.profile.lead": "Vu sempre povas kompletigar co plu tarde en la opcioni, ube mem plua personalizanta opcioni es disponebla.",
"onboarding.profile.note": "Biografio",
"onboarding.profile.note_hint": "Vu povas @mencionar altra personi o #hashtagi…",
"onboarding.profile.save_and_continue": "Preservez e avancez",
"onboarding.profile.title": "Kompletigez la profilo",
"onboarding.profile.upload_avatar": "Kargez profiloportreto",
"onboarding.profile.upload_header": "Kargez profilokapimajo",
"onboarding.share.lead": "Savigez personi quale ili povas trovar vu che Mastodon!",
"onboarding.share.message": "Me esas {username} che #Mastodon! Venez e sequez me ye {url}",
"onboarding.share.next_steps": "Kozi quin vu darfas volar facar sequante:",
@ -482,7 +502,7 @@
"onboarding.steps.follow_people.title": "Follow {count, plural, one {one person} other {# people}}",
"onboarding.steps.publish_status.body": "Say hello to the world.",
"onboarding.steps.publish_status.title": "Facar vua unesma posto",
"onboarding.steps.setup_profile.body": "Others are more likely to interact with you with a filled out profile.",
"onboarding.steps.setup_profile.body": "Vu interagos plue kun profilo detalizita.",
"onboarding.steps.setup_profile.title": "Customize your profile",
"onboarding.steps.share_profile.body": "Let your friends know how to find you on Mastodon!",
"onboarding.steps.share_profile.title": "Share your profile",
@ -510,6 +530,7 @@
"privacy.unlisted.short": "Ne enlistigota",
"privacy_policy.last_updated": "Antea novajo ye {date}",
"privacy_policy.title": "Privatesguidilo",
"recommended": "Rekomendata",
"refresh": "Rifreshez",
"regeneration_indicator.label": "Chargas…",
"regeneration_indicator.sublabel": "Vua hemniuzeto preparesas!",
@ -580,6 +601,8 @@
"search.quick_action.status_search": "Posti qui asortas {x}",
"search.search_or_paste": "Serchar o pozar URL",
"search_popout.full_text_search_disabled_message": "Nedisponebla che {domain}.",
"search_popout.full_text_search_logged_out_message": "Nur disponebla enirite.",
"search_popout.language_code": "ISO linguokodexo",
"search_popout.options": "Opcioni serchala",
"search_popout.quick_actions": "Agi rapida",
"search_popout.recent": "Lasta serchi",
@ -607,8 +630,8 @@
"status.admin_status": "Open this status in the moderation interface",
"status.block": "Restriktez @{name}",
"status.bookmark": "Libromarko",
"status.cancel_reblog_private": "Debustez",
"status.cannot_reblog": "Ca posto ne povas bustesas",
"status.cancel_reblog_private": "Desrepetez",
"status.cannot_reblog": "Ca posto ne povas repetesar",
"status.copy": "Copy link to status",
"status.delete": "Efacar",
"status.detailed_status": "Detala konversvido",
@ -636,10 +659,10 @@
"status.pin": "Pinglagez che profilo",
"status.pinned": "Pinned toot",
"status.read_more": "Lektez pluse",
"status.reblog": "Repetar",
"status.reblog_private": "Bustez kun originala videbleso",
"status.reblogged_by": "{name} repetita",
"status.reblogs.empty": "No one has boosted this toot yet. When someone does, they will show up here.",
"status.reblog": "Repetez",
"status.reblog_private": "Repetez kun originala videbleso",
"status.reblogged_by": "{name} repetis",
"status.reblogs.empty": "Nulu ja repetis ca posto. Kande ulu facas lo, lu montresos hike.",
"status.redraft": "Efacez e riskisigez",
"status.remove_bookmark": "Efacez libromarko",
"status.replied_to": "Respondis a {name}",

View file

@ -21,7 +21,7 @@
"account.blocked": "ブロック済み",
"account.browse_more_on_origin_server": "リモートで表示",
"account.cancel_follow_request": "フォローリクエストの取り消し",
"account.copy": "プロフィールのリンクをコピーして下さい",
"account.copy": "プロフィールのリンクをコピー",
"account.direct": "@{name}さんに非公開でメンション",
"account.disable_notifications": "@{name}さんの投稿時の通知を停止",
"account.domain_blocked": "ドメインブロック中",
@ -192,7 +192,7 @@
"conversation.mark_as_read": "既読にする",
"conversation.open": "会話を表示",
"conversation.with": "{names}",
"copy_icon_button.copied": "クリップボードにコピーされた",
"copy_icon_button.copied": "コピーしました",
"copypaste.copied": "コピーしました",
"copypaste.copy_to_clipboard": "クリップボードにコピー",
"directory.federated": "既知の連合より",
@ -392,7 +392,7 @@
"lists.search": "フォローしている人の中から検索",
"lists.subheading": "あなたのリスト",
"load_pending": "{count}件の新着",
"loading_indicator.label": "",
"loading_indicator.label": "読み込み中…",
"media_gallery.toggle_visible": "{number, plural, one {画像を閉じる} other {画像を閉じる}}",
"moved_to_account_banner.text": "あなたのアカウント『{disabledAccount}』は『{movedToAccount}』に移動したため現在無効になっています。",
"mute_modal.duration": "ミュートする期間",
@ -481,17 +481,17 @@
"onboarding.follows.empty": "表示できる結果はありません。検索やエクスプローラーを使ったり、ほかのアカウントをフォローしたり、後でもう一度試しください。",
"onboarding.follows.lead": "ホームタイムラインはMastodonの軸足となる場所です。たくさんのユーザーをフォローすることで、ホームタイムラインはよりにぎやかでおもしろいものになります。手はじめに、おすすめのアカウントから何人かフォローしてみましょう:",
"onboarding.follows.title": "ホームタイムラインを埋める",
"onboarding.profile.discoverable": "自分のプロフィールが発見できないようにする",
"onboarding.profile.discoverable_hint": "マストドンの見つけやすくする機能が個人情報を利用することに承諾すると、あなたの投稿が検索結果やトレンドに表示されることがあります。また、あなたのプロフィールがあなたと似た興味関心を持つ人に提案されることがあります。",
"onboarding.profile.discoverable": "自分のプロフィールが見つけられるようにする",
"onboarding.profile.discoverable_hint": "Mastodonの「見つける」機能にオプトインすると、あなたの投稿が検索結果やトレンドに表示されることがあります。また、あなたに似た関心を持つ人にプロフィールがおすすめされることがあります。",
"onboarding.profile.display_name": "表示名",
"onboarding.profile.display_name_hint": "あなたのフルネーム、または楽しい名前…",
"onboarding.profile.lead": "このことは後でいつでも設定から完了させることが出来ますし、設定では更に多くのカスタマイズが利用可能になっています。",
"onboarding.profile.display_name_hint": "フルネーム、あるいは面白い名前など",
"onboarding.profile.lead": "あとでいつでも修正できますし、設定画面にはこれ以外のカスタマイズ項目もあります。",
"onboarding.profile.note": "自己紹介",
"onboarding.profile.note_hint": "@を使用して他の人々にメンションをすることができます。また#でハッシュタグが使用できます",
"onboarding.profile.save_and_continue": "保存してから続行して下さい",
"onboarding.profile.note_hint": "ほかの人に @言及 したり、#ハッシュタグ を付けたりできます",
"onboarding.profile.save_and_continue": "保存して続ける",
"onboarding.profile.title": "プロフィールの設定",
"onboarding.profile.upload_avatar": "プロフィール画像をアップロードしてください",
"onboarding.profile.upload_header": "プロフィールのヘッダー画像をアップロードして下さい",
"onboarding.profile.upload_avatar": "プロフィール画像をアップロード",
"onboarding.profile.upload_header": "プロフィールのヘッダー画像をアップロード",
"onboarding.share.lead": "新しいMastodonのアカウントをみんなに紹介しましょう。",
"onboarding.share.message": "「{username}」で #Mastodon はじめました! {url}",
"onboarding.share.next_steps": "次のステップに進む:",
@ -606,6 +606,7 @@
"search.quick_action.status_search": "{x}に該当する投稿",
"search.search_or_paste": "検索またはURLを入力",
"search_popout.full_text_search_disabled_message": "{domain}では利用できません。",
"search_popout.full_text_search_logged_out_message": "ログイン時のみ利用できます。",
"search_popout.language_code": "ISO言語コード",
"search_popout.options": "検索オプション",
"search_popout.quick_actions": "クイック操作",

View file

@ -0,0 +1,649 @@
{
"about.blocks": "Sirvidores moderados",
"about.contact": "Kontakto:",
"about.disclaimer": "Mastodon es un programario libero, kon kodiche avierto i una marka komersiala de Mastodon gGmbH.",
"about.domain_blocks.no_reason_available": "Razon no desponivle",
"about.domain_blocks.preamble": "Mastodon djeneralmente te permete ver kontenido de i enteraktuar kon utilizadores de kualseker otro sirvidor en el fediverso. Estas son las eksepsiones en este sirvidor en partikolar.",
"about.domain_blocks.silenced.explanation": "\"Djeneralmente no veras profiles i kontenido de este sirvidor, salvo ke eksplisitamente lo bushkes o sigas algun kuento de el.",
"about.domain_blocks.silenced.title": "Limitado",
"about.domain_blocks.suspended.explanation": "Dingunos datos de este sirvidor sera prosesado, magazinado o enterkambiado kon este sirvidor. Enteraksyon o komunikasyon kon sus utilizadores sera imposivle.",
"about.domain_blocks.suspended.title": "Suspendido",
"about.not_available": "Esta enformasyon no esta desponivle en este sirvidor.",
"about.powered_by": "Redes sosyalas desentralizadas kon uzo de {mastodon}",
"about.rules": "Reglas del sirvidor",
"account.account_note_header": "Nota",
"account.add_or_remove_from_list": "Adjusta a o kita de listas",
"account.badges.bot": "Bot",
"account.badges.group": "Grupo",
"account.block": "Bloka @{name}",
"account.block_domain": "Bloka el domeno {domain}",
"account.block_short": "Bloka",
"account.blocked": "Blokado",
"account.browse_more_on_origin_server": "Ve mas en el profil orijinal",
"account.cancel_follow_request": "Anula solisitud de segir",
"account.copy": "Kopia atadijo de profil",
"account.direct": "Enmenta a @{name} en privado",
"account.disable_notifications": "No me avizes mas sovre publikasyones de @{name}",
"account.domain_blocked": "Domeno blokado",
"account.edit_profile": "Edita profil",
"account.enable_notifications": "Avizame kuando @{name} publike",
"account.endorse": "Avalia en profil",
"account.featured_tags.last_status_at": "Ultima publikasyon de {date}",
"account.featured_tags.last_status_never": "\"No ay publikasyones",
"account.featured_tags.title": "Etiketas avaliadas de {name}",
"account.follow": "Sige",
"account.followers": "Suivantes",
"account.followers.empty": "Por agora dingun no sige a este utilizador.",
"account.followers_counter": "{count, plural, one {{counter} suivante} other {{counter} suivantes}}",
"account.following": "Sigiendo",
"account.following_counter": "{count, plural, other {Sigiendo a {counter}}}",
"account.follows.empty": "Este utilizador ainda no sige a ningun.",
"account.follows_you": "Te sige",
"account.go_to_profile": "Va al profil",
"account.hide_reblogs": "Eskonde repartajasyones de @{name}",
"account.in_memoriam": "De bendicha memoria.",
"account.joined_short": "Adjunto",
"account.languages": "Troka linguas suskrividas",
"account.link_verified_on": "La propriedad de este atadijo fue verifikada el {date}",
"account.locked_info": "El estado de privasita de este konto esta konfigurado komo serado. El proprietario reviza manualmente kien le puede segir.",
"account.media": "Multimedia",
"account.mention": "Enmenta a @{name}",
"account.moved_to": "{name} tiene endikado ke su muevo kuento agora es:",
"account.mute": "Silensia a @{name}",
"account.mute_notifications_short": "Silensia avizos de @{name}",
"account.mute_short": "Silensia",
"account.muted": "Silensiado",
"account.no_bio": "No ay deskripsion.",
"account.open_original_page": "Avre pajina orijnala",
"account.posts": "Publikasyones",
"account.posts_with_replies": "Kon repuestas",
"account.report": "Raporta @{name}",
"account.requested": "Asperando achetasion. Klika para anular la solisitud de segimiento",
"account.requested_follow": "{name} tiene solisitado segirte",
"account.share": "Partaja el profil de @{name}",
"account.show_reblogs": "Amostra repartajasyones de @{name}",
"account.statuses_counter": "{count, plural, one {{counter} publikasyon} other {{counter} publikasyones}}",
"account.unblock": "Dezbloka @{name}",
"account.unblock_domain": "Dezbloka domeno {domain}",
"account.unblock_short": "Dezbloka",
"account.unendorse": "No avalia en profil",
"account.unfollow": "Desige",
"account.unmute": "Desilensia a @{name}",
"account.unmute_notifications_short": "Desilensia avizos",
"account.unmute_short": "Desilensia",
"account_note.placeholder": "Klika para adjustar nota",
"admin.dashboard.daily_retention": "Proporsyon de retensyon de utilizadores por diya dempues de enrejistrasyon",
"admin.dashboard.monthly_retention": "Proporsyon de retensyon de utilizadores por mez dempues de enrejistrasyon",
"admin.dashboard.retention.average": "Media",
"admin.dashboard.retention.cohort": "Mez de enrejistrasyon",
"admin.dashboard.retention.cohort_size": "Muevos utilizadores",
"alert.rate_limited.message": "Por favor aprova dempues de {retry_time, time, medium}.",
"alert.rate_limited.title": "Trafiko limitado",
"alert.unexpected.message": "Afito un yerro no asperado.",
"alert.unexpected.title": "Atyo!",
"announcement.announcement": "Pregon",
"attachments_list.unprocessed": "(no prosesado)",
"audio.hide": "Eskonder audio",
"autosuggest_hashtag.per_week": "{count} por semana",
"boost_modal.combo": "Puedes klikar {combo} para ometer esto la proksima vez",
"bundle_column_error.copy_stacktrace": "Kopia el raporto de yerro",
"bundle_column_error.error.body": "La pajina solisitada no pudo ser renderada. Podria ser por un yerro en muestro kodiche o un problem de kompatibilita kon el navigador.",
"bundle_column_error.error.title": "Atyo, no!",
"bundle_column_error.network.body": "Uvo un yerro kon la prova de eskargar esta pajina. Esto puede ser por un problem temporal kon tu koneksyon a la internet o a este sirvidor.",
"bundle_column_error.network.title": "Yerro de red",
"bundle_column_error.retry": "Aprova de muevo",
"bundle_column_error.return": "Volta a la linya prinsipala",
"bundle_column_error.routing.body": "No se pudo trokar la pajina solisitada. Estas siguro ke el adreso URL en la vara de adreso es djusto?",
"bundle_column_error.routing.title": "404",
"bundle_modal_error.close": "Serra",
"bundle_modal_error.message": "Algo negro afito al eskargar este komponente.",
"bundle_modal_error.retry": "Aprova de muevo",
"closed_registrations.other_server_instructions": "Deke Mastodon es desentralizado, puedes kriyar un kuento en otro sirvidor i ainda enteraktuar kon este.",
"closed_registrations_modal.description": "Aktualmente no es posivle kriyar un kuento en {domain}, ama por favor akodrate de ke no ay menester de tener un kuento espesifikamente en {domain} para kulanear Mastodon.",
"closed_registrations_modal.find_another_server": "Bushka otro sirvidor",
"closed_registrations_modal.preamble": "Mastodon es desentralizado, estonses sin emportansya ande kriyas tu kuento, podras segir i enteraktuar kon kualseker persona en este sirvidor. Tamyen puedes balabayarlo tu mezmo!",
"closed_registrations_modal.title": "Enrerjistrate en Mastodon",
"column.about": "Sovre mozotros",
"column.blocks": "Utilizadores blokados",
"column.bookmarks": "Markadores",
"column.community": "Linya de tiempo lokala",
"column.direct": "Enmentaduras privadas",
"column.directory": "Eksplora profiles",
"column.domain_blocks": "Domenos blokados",
"column.favourites": "Te plazen",
"column.firehose": "Linyas en bivo",
"column.follow_requests": "Solisitudes de segimiento",
"column.home": "Linya prinsipala",
"column.lists": "Listas",
"column.mutes": "Utilizadores silensiados",
"column.notifications": "Avizos",
"column.pins": "Publikasyones fiksadas",
"column.public": "Linya de tiempo federada",
"column_back_button.label": "Atras",
"column_header.hide_settings": "Eskonde opsyones",
"column_header.moveLeft_settings": "Move kolumna a la siedra",
"column_header.moveRight_settings": "Move kolumna a la derecha",
"column_header.pin": "Fiksa",
"column_header.show_settings": "Amostra opsyones",
"column_header.unpin": "Defiksar",
"column_subheading.settings": "Opsyones",
"community.column_settings.local_only": "Solo lokalas",
"community.column_settings.media_only": "Solo multimedia",
"community.column_settings.remote_only": "Solo remotas",
"compose.language.change": "Troka lingua",
"compose.language.search": "Bushka linguas...",
"compose.published.body": "Publikasyon publikada.",
"compose.published.open": "Avre",
"compose.saved.body": "Publikasyon guadrada.",
"compose_form.direct_message_warning_learn_more": "Ambezate mas",
"compose_form.encryption_warning": "Publikasyones en Mastodon no son shifradas de lado a lado. No partajes dinguna enformasyon sensivle por Mastodon.",
"compose_form.hashtag_warning": "Esta publikasyon no sera amostrada debasho de dinguna etiketa si no es publika. Solo publikasyones publikas se pueden bushkar por la etiketa.",
"compose_form.lock_disclaimer": "Tu kuento no esta {locked}. Todos pueden segirte para ver tus publikasyones solo para suivantes.",
"compose_form.lock_disclaimer.lock": "serrado",
"compose_form.placeholder": "Ke haber?",
"compose_form.poll.add_option": "Adjusta opsyon",
"compose_form.poll.duration": "Durasion de anketa",
"compose_form.poll.option_placeholder": "Opsyon {number}",
"compose_form.poll.remove_option": "Kita esta opsyon",
"compose_form.poll.switch_to_multiple": "Trokar anketa para permeter a eskojer mas ke una opsyon",
"compose_form.poll.switch_to_single": "Trokar anketa para permeter a eskojer solo una opsyon",
"compose_form.publish": "Publika",
"compose_form.publish_form": "Mueva publikasyon",
"compose_form.publish_loud": "{publish}!",
"compose_form.save_changes": "Guadra trokamientos",
"compose_form.sensitive.hide": "{count, plural, one {Marka material komo sensivle} other {Marka material komo sensivle}}",
"compose_form.sensitive.marked": "{count, plural, one {Material markado komo sensivle} other {Material markado komo sensivle}}",
"compose_form.sensitive.unmarked": "{count, plural, one {Material no markado komo sensivle} other {Material no markado komo sensivle}}",
"compose_form.spoiler.marked": "Kita avertensya de kontenido",
"compose_form.spoiler.unmarked": "Adjusta avertensya de kontenido",
"compose_form.spoiler_placeholder": "Eskrive tu avertensya aki",
"confirmation_modal.cancel": "Anula",
"confirmations.block.block_and_report": "Bloka i raporta",
"confirmations.block.confirm": "Bloka",
"confirmations.block.message": "Estas siguro ke keres blokar a {name}?",
"confirmations.cancel_follow_request.confirm": "Anula solisitud",
"confirmations.cancel_follow_request.message": "Estas siguro ke keres anular tu solisitud de segir a {name}?",
"confirmations.delete.confirm": "Efasa",
"confirmations.delete.message": "Estas siguro ke keres efasar esta publikasyon?",
"confirmations.delete_list.confirm": "Efasa",
"confirmations.delete_list.message": "Estas siguro ke keres permanentemente efasar esta lista?",
"confirmations.discard_edit_media.confirm": "Anula",
"confirmations.discard_edit_media.message": "Tienes trokamientos no guadrados en la deskripsion o vista previa. Keres efasarlos entanto?",
"confirmations.domain_block.confirm": "Bloka domeno entero",
"confirmations.domain_block.message": "Estas totalmente siguro ke keres blokar todo el domeno {domain}? En djeneral unos kuantos blokos o silensiamientos son sufisientes i preferavles. No veras kontenido de akel domeno en dinguna linya de tiempo publika ni ent tus avizos. Tus suivantes de akel domeno seran kitados.",
"confirmations.edit.confirm": "Edita",
"confirmations.edit.message": "Editar agora kitara el mesaj kualo estas eskriviendo aktualmente. Estas siguro ke keres fazerlo?",
"confirmations.logout.confirm": "Sal",
"confirmations.logout.message": "Estas siguro ke keres salir de tu kuento?",
"confirmations.mute.confirm": "Silensia",
"confirmations.mute.explanation": "Esto eskondera las publikasyones de este kuento i publikasyones ke lo enmentan, pero ainda les permetera segirte.",
"confirmations.mute.message": "Estas siguro ke keres silensiar a {name}?",
"confirmations.redraft.confirm": "Efasar i reeskrivir",
"confirmations.redraft.message": "Estas siguro ke keres efasar esta publikasyon i reeskrivirla? Pedreras todos los favoritos i repartajasyones asosiados kon esta publikasyon i repuestas a eya seran guerfanadas.",
"confirmations.reply.confirm": "Arisponde",
"confirmations.reply.message": "Arispondir agora kitara el mesaj kualo estas eskriviendo aktualmente. Estas siguro ke keres fazerlo?",
"confirmations.unfollow.confirm": "Desige",
"confirmations.unfollow.message": "Estas siguro ke keres deshar de segir a {name}?",
"conversation.delete": "Efasa konversasyon",
"conversation.mark_as_read": "Marka komo meldado",
"conversation.open": "Ve konversasyon",
"conversation.with": "Kon {names}",
"copy_icon_button.copied": "Kopiado al portapapeles",
"copypaste.copied": "Kopiado",
"copypaste.copy_to_clipboard": "Kopia al portapapeles",
"directory.federated": "Dizde el fediverso konesido",
"directory.local": "Solo de {domain}",
"directory.new_arrivals": "Arivados resientemente",
"directory.recently_active": "Aktivos resientemente",
"disabled_account_banner.account_settings": "Preferensyas de kuento",
"disabled_account_banner.text": "Tu kuento {disabledAccount} esta aktualmente inkapasitado.",
"dismissable_banner.community_timeline": "Estas son las publikasyones publikas mas resientes de las personas kualos kuentos estan balabayados en {domain}.",
"dismissable_banner.dismiss": "Kita",
"dismissable_banner.explore_links": "Estos haberes estan diskutidos agora por djente en este sirvidor i otros de la red desentralizada.",
"dismissable_banner.explore_statuses": "Estas publikasyones de este sirvidor i otros de la red desentralizada estan agora popularas. Publikasyones mas muevas, kon mas repartajasiones i favoritadas por mas djente aparesen primero.",
"dismissable_banner.explore_tags": "Estas etiketas estan agora popularas en la red sosyala. Etiketas uzadas por mas djente aparesen primero.",
"dismissable_banner.public_timeline": "Estas son las publikasyones publikas mas resientes de personas en la red sosyala a las kualas la djente de {domain} sige.",
"embed.instructions": "Enkrusta esta publikasyon en tu sitio internetiko kopiando este kodiche.",
"embed.preview": "Ansi paresera:",
"emoji_button.activity": "Aktivita",
"emoji_button.clear": "Alimpia",
"emoji_button.custom": "Personalizado",
"emoji_button.flags": "Bandieras",
"emoji_button.food": "Kumidas i beverajes",
"emoji_button.label": "Adjustar emoji",
"emoji_button.nature": "Natura",
"emoji_button.not_found": "Emojis no topados",
"emoji_button.objects": "Objektos",
"emoji_button.people": "Djente",
"emoji_button.recent": "Uzados frekuentemente",
"emoji_button.search": "Bushka...",
"emoji_button.search_results": "Rizultados de bushkeda",
"emoji_button.symbols": "Simbolos",
"emoji_button.travel": "Viajes i lugares",
"empty_column.account_suspended": "Kuento suspendido",
"empty_column.account_timeline": "No ay publikasyones aki!",
"empty_column.account_unavailable": "Profil no desponivle",
"empty_column.blocks": "Ainda no tienes blokado a dingun utilizador.",
"empty_column.bookmarked_statuses": "Ainda no tienes dinguna publikasyon kon markador. Kuando adjustes un markador a una, se amostrara aki.",
"empty_column.community": "La linya de tiempo lokala esta vaziya. Eskrive algo publikamente para ampesar la fiesta!",
"empty_column.direct": "Ainda no tienes enmentaduras privadas. Kuando embies o risives una, se amostra aki.",
"empty_column.domain_blocks": "Ainda no ay domenos blokados.",
"empty_column.explore_statuses": "No ay dingunos trendes agora. Mira mas tadre!",
"empty_column.favourited_statuses": "Ainda no tienes publikasyones favoritas. Kuando indikes ke una te plaze, se amostrara aki.",
"empty_column.favourites": "Nadie tiene indikado ke le plaze una de tus publikasyones. Kuando algun lo aga, se amostrara aki.",
"empty_column.follow_requests": "No tienes dinguna solisitud de suivante. Kuando risivas una, se amostrara aki.",
"empty_column.followed_tags": "Ainda no tienes segido dinguna etiketa. Kuando lo agas, se amostraran aki.",
"empty_column.hashtag": "Ainda no ay niente en esta etiketa.",
"empty_column.home": "Tu linya de tiempo esta vaziya! Sige a mas personas para inchirla.",
"empty_column.list": "Ainda no ay niente en esta lista. Kuando miembros de esta lista publiken muevas publikasyones, se amostraran aki.",
"empty_column.lists": "Ainda no tienes dinguna lista. Kuando kriyes una, aperesera aki.",
"empty_column.mutes": "Ainda no tienes silensiado a dingun utilizador.",
"empty_column.notifications": "Ainda no tienes dingun avizo. Kuando otras personas enteraktuen kontigo, se amostraran aki.",
"empty_column.public": "No ay niente aki! Eskrive algo publikamente o manualmente sige utilizadores de otros sirvidores para inchirlo",
"error.unexpected_crash.explanation": "Por un yerro en muestro kodiche o un problem de kompatibilita kon el navigador, no se puede amostrar esta pajina djustamente.",
"error.unexpected_crash.explanation_addons": "No se puede amostrar esta pajina djustamente. Este yerro probavlemente fue kauzado por un komplimento del navigador o por un enstrumento de traduksion.",
"error.unexpected_crash.next_steps": "Aprova arefreskar la pajina. Si esto no ayuda, es posivle ke ainda puedas kulaenar Mastodon kon otro navigador u otra aplikasyon nativa.",
"error.unexpected_crash.next_steps_addons": "Aprova inkapasitarlos i arefreskar la pajina. Si esto no ayuda, es posivle ke ainda puedas kulanear Mastodon kon otro navigador u otra aplikasyon nativa.",
"errors.unexpected_crash.copy_stacktrace": "Kopiar stacktrace al portapapeles",
"errors.unexpected_crash.report_issue": "Raportar problema",
"explore.search_results": "Rizultados de bushkeda",
"explore.suggested_follows": "Djente",
"explore.title": "Eksplorar",
"explore.trending_links": "Haberes",
"explore.trending_statuses": "Publikasyones",
"explore.trending_tags": "Etiketas",
"filter_modal.added.context_mismatch_explanation": "Esta kategoria del filtro no se aplika al konteksto en ke tienes aksesido esta publikasyon. Si keres ke la publikasyon sea filtrada en este konteksto tamyen, kale editar el filtro.",
"filter_modal.added.context_mismatch_title": "El konteksto no koensida!",
"filter_modal.added.expired_explanation": "Esta kategoria de filtros tiene kadukado. Kale ke trokar la data de kadukasion para aplikarla.",
"filter_modal.added.expired_title": "Filtro kadukado!",
"filter_modal.added.review_and_configure": "Para revizar i konfigurar esta kategoria de filtros, va a {settings_link}.",
"filter_modal.added.review_and_configure_title": "Konfigurasyon de filtro",
"filter_modal.added.settings_link": "pajina de konfigurasyon",
"filter_modal.added.short_explanation": "Esta publikasyon fue adjustada a la sigiente kategoria de filtros: {title}.",
"filter_modal.added.title": "Filtro adjustado!",
"filter_modal.select_filter.context_mismatch": "no se aplika a este konteksto",
"filter_modal.select_filter.expired": "kadukado",
"filter_modal.select_filter.prompt_new": "Mueva kategoria: {name}",
"filter_modal.select_filter.search": "Bushkar o kriyar",
"filter_modal.select_filter.subtitle": "Kulanear una kategoria egzistente o kriya mueva",
"filter_modal.select_filter.title": "Filtrar esta publikasyon",
"filter_modal.title.status": "Filtrar una publikasyon",
"firehose.all": "Todo",
"firehose.local": "Este sirvidor",
"firehose.remote": "Otros sirvidores",
"follow_request.authorize": "Autoriza",
"follow_request.reject": "Refuza",
"follow_requests.unlocked_explanation": "Aunke tu kuento no esta serrado, la taifa de {domain} kreye ke talvez keres revizar manualmente las solisitudes de segimento de estos kuentos.",
"followed_tags": "Etiketas segidas",
"footer.about": "Sovre mozotros",
"footer.directory": "Katalogo de profiles",
"footer.get_app": "Abasha aplikasyon",
"footer.invite": "Envitar a djente",
"footer.keyboard_shortcuts": "Akortamientos de klavye",
"footer.privacy_policy": "Politika de privasita",
"footer.source_code": "Ve kodiche fuente",
"footer.status": "Estado",
"generic.saved": "Guadrado",
"getting_started.heading": "Primos pasos",
"hashtag.column_header.tag_mode.all": "i {additional}",
"hashtag.column_header.tag_mode.any": "o {additional}",
"hashtag.column_header.tag_mode.none": "sin {additional}",
"hashtag.column_settings.select.no_options_message": "Rekomendasyones no topadas",
"hashtag.column_settings.select.placeholder": "Meter etiketas…",
"hashtag.column_settings.tag_mode.all": "Todos estos",
"hashtag.column_settings.tag_mode.any": "Kualsekera de estos",
"hashtag.column_settings.tag_mode.none": "Dinguno de estos",
"hashtag.column_settings.tag_toggle": "Inkluir etiketas adisionalas en esta kolumna",
"hashtag.follow": "Segir etiketa",
"hashtag.unfollow": "Desegir etiketa",
"home.column_settings.basic": "Opsyones bazikas",
"home.column_settings.show_reblogs": "Amostrar repartajasyones",
"home.column_settings.show_replies": "Amostrar repuestas",
"home.hide_announcements": "Eskonde pregones",
"home.pending_critical_update.link": "Ve aktualizasyones",
"home.show_announcements": "Amostra pregones",
"interaction_modal.description.favourite": "Kon un kuento en Mastodon, puedes markar esta publikasyon komo favorita para ke el autor sepa ke te plaze i para guadrarla para dempues.",
"interaction_modal.description.follow": "Kon un kuento en Mastodon, puedes segir a {name} para risivir sus publikasyones en tu linya temporal prinsipala.",
"interaction_modal.description.reblog": "Kon un kuento en Mastodon, puedes repartajar esta publikasyon para amostrarla a tus suivantes.",
"interaction_modal.description.reply": "Kon un kuento en Mastodon, puedes arispondir a esta publikasyon.",
"interaction_modal.on_another_server": "En otro sirvidor",
"interaction_modal.on_this_server": "En este sirvidor",
"interaction_modal.title.favourite": "Endika ke te plaze publikasyon de {name}",
"interaction_modal.title.follow": "Sige a {name}",
"interaction_modal.title.reblog": "Repartaja publikasyon de {name}",
"interaction_modal.title.reply": "Arisponde a publikasyon de {name}",
"intervals.full.days": "{number, plural, one {# diya} other {# diyas}}",
"intervals.full.hours": "{number, plural, one {# ora} other {# oras}}",
"intervals.full.minutes": "{number, plural, one {# minuto} other {# minutos}}",
"keyboard_shortcuts.back": "Volta atras",
"keyboard_shortcuts.blocked": "Avre lista de utilizadores blokados",
"keyboard_shortcuts.boost": "Repartaja publikasyon",
"keyboard_shortcuts.column": "Enfoka en una kolumna",
"keyboard_shortcuts.compose": "Enfoka en el area de eskrivir publikasyon",
"keyboard_shortcuts.description": "Deskripsyon",
"keyboard_shortcuts.direct": "Avre la kolumna de enmentaduras privadas",
"keyboard_shortcuts.down": "Move verso abasho en la lista",
"keyboard_shortcuts.enter": "Avre publikasyon",
"keyboard_shortcuts.favourite": "Endika ke te plaze una publikasyon",
"keyboard_shortcuts.favourites": "Avre lista de favoritos",
"keyboard_shortcuts.federated": "Avre linya federada",
"keyboard_shortcuts.heading": "Akortamientos de klavye",
"keyboard_shortcuts.home": "Avre linya prinsipala",
"keyboard_shortcuts.hotkey": "Klave rapido",
"keyboard_shortcuts.legend": "Amostra esta lejenda",
"keyboard_shortcuts.local": "Avre linya lokala",
"keyboard_shortcuts.mention": "Enmenta al autor",
"keyboard_shortcuts.muted": "Avre lista de utilizadores silensiados",
"keyboard_shortcuts.my_profile": "Avre tu profil",
"keyboard_shortcuts.notifications": "Avre kolumna de avizos",
"keyboard_shortcuts.open_media": "Avre multimedia",
"keyboard_shortcuts.pinned": "Avre lista de publikasyones fiksadas",
"keyboard_shortcuts.profile": "Avre profil del autor",
"keyboard_shortcuts.reply": "Arisponde a publikasyon",
"keyboard_shortcuts.requests": "Avre lista de solisitudes de suivantes",
"keyboard_shortcuts.search": "Enfoka en la vara de bushkeda",
"keyboard_shortcuts.spoilers": "Amostra/eskonde el kampo de avertensya de kontenido (CW)",
"keyboard_shortcuts.start": "Avre la kolumna \"para ampesar\"",
"keyboard_shortcuts.toggle_hidden": "Amostra/eskonde teksto detras de avertensya de kontenido (CW)",
"keyboard_shortcuts.toggle_sensitivity": "Amostra/eskonde multimedia",
"keyboard_shortcuts.toot": "Eskrive mueva publikasyon",
"keyboard_shortcuts.unfocus": "No enfoka en el area de eskrivir/bushkeda",
"keyboard_shortcuts.up": "Move verso arriva en la lista",
"lightbox.close": "Serra",
"lightbox.compress": "Kompresa kuadro de imaje",
"lightbox.expand": "Espande kuadro de imaje",
"lightbox.next": "Sigiente",
"lightbox.previous": "Anterior",
"limited_account_hint.action": "Amostra el profil entanto",
"limited_account_hint.title": "Este profil fue eskondido por los moderadores de {domain}.",
"lists.account.add": "Adjusta a lista",
"lists.account.remove": "Kita de lista",
"lists.delete": "Efasa lista",
"lists.edit": "Edita lista",
"lists.edit.submit": "Troka titolo",
"lists.new.create": "Adjusta lista",
"lists.new.title_placeholder": "Titolo de mueva lista",
"lists.replies_policy.followed": "Kualseker utilizardo segido",
"lists.replies_policy.list": "Miembros de la lista",
"lists.replies_policy.none": "Dinguno",
"lists.replies_policy.title": "Amostra repuestas a:",
"lists.search": "Bushka entre personas a las kualas siges",
"lists.subheading": "Tus listas",
"load_pending": "{count, plural, one {# muevo elemento} other {# muevos elementos}}",
"loading_indicator.label": "Eskargando…",
"media_gallery.toggle_visible": "{number, plural, one {Eskonde imaje} other {Eskonde imajes}}",
"moved_to_account_banner.text": "Tu kuento {disabledAccount} esta aktualmente inkapasitado porke transferates a {movedToAccount}.",
"mute_modal.duration": "Durasyon",
"mute_modal.hide_notifications": "Eskonder avizos de este utilizador?",
"mute_modal.indefinite": "Indefinida",
"navigation_bar.about": "Sovre mozotros",
"navigation_bar.blocks": "Utilizadores blokados",
"navigation_bar.bookmarks": "Markadores",
"navigation_bar.community_timeline": "Linya de tiempo lokala",
"navigation_bar.compose": "Eskrivir mueva publikasyon",
"navigation_bar.direct": "Enmentaduras privadas",
"navigation_bar.discover": "Diskuvre",
"navigation_bar.domain_blocks": "Domenos blokados",
"navigation_bar.edit_profile": "Edita profil",
"navigation_bar.explore": "Eksplorar",
"navigation_bar.favourites": "Te plazen",
"navigation_bar.filters": "Biervos silensiados",
"navigation_bar.follow_requests": "Solisitudes de segimiento",
"navigation_bar.followed_tags": "Etiketas segidas",
"navigation_bar.follows_and_followers": "Segidos i suivantes",
"navigation_bar.lists": "Listas",
"navigation_bar.logout": "Salir",
"navigation_bar.mutes": "Utilizadores silensiados",
"navigation_bar.personal": "Personal",
"navigation_bar.pins": "Publikasyones fiksadas",
"navigation_bar.preferences": "Preferensyas",
"navigation_bar.public_timeline": "Linya de tiempo federada",
"navigation_bar.search": "Bushka",
"navigation_bar.security": "Segurita",
"not_signed_in_indicator.not_signed_in": "Nesesitas konektarse kon tu kuento para akseder este rekurso.",
"notification.admin.report": "{name} raporto {target}",
"notification.admin.sign_up": "{name} kriyo un konto",
"notification.favourite": "A {name} le plaze tu publikasyon",
"notification.follow": "{name} te ampeso a segir",
"notification.follow_request": "{name} tiene solisitado segirte",
"notification.mention": "{name} te enmento",
"notification.own_poll": "Tu anketa eskapo",
"notification.poll": "Anketa en ke votates eskapo",
"notification.reblog": "{name} repartajo tu publikasyon",
"notification.status": "{name} publiko algo",
"notification.update": "{name} edito una publikasyon",
"notifications.clear": "Efasar avizos",
"notifications.clear_confirmation": "Estas siguro ke keres permanentemente efasar todos tus avizos?",
"notifications.column_settings.admin.report": "Muveos raportos:",
"notifications.column_settings.admin.sign_up": "Muevas enrejistrasyones:",
"notifications.column_settings.alert": "Avizos de ensimameza",
"notifications.column_settings.favourite": "Te plazen:",
"notifications.column_settings.filter_bar.advanced": "Amostra todas las kategorias",
"notifications.column_settings.filter_bar.category": "Vara de filtrado rapido",
"notifications.column_settings.filter_bar.show_bar": "Amostra vara de filtros",
"notifications.column_settings.follow": "Muevos suivantes:",
"notifications.column_settings.follow_request": "Muevas solisitudes de segimiento:",
"notifications.column_settings.mention": "Enmentaduras:",
"notifications.column_settings.poll": "Rizultados de anketas:",
"notifications.column_settings.push": "Avizos arrepushados",
"notifications.column_settings.reblog": "Repartajasyones:",
"notifications.column_settings.show": "Amostra en kolumna",
"notifications.column_settings.sound": "Reproduzir son",
"notifications.column_settings.status": "Publikasyones muevas:",
"notifications.column_settings.unread_notifications.category": "Avizos no meldados",
"notifications.column_settings.unread_notifications.highlight": "Avaliar avizos no meldados",
"notifications.column_settings.update": "Edisyones:",
"notifications.filter.all": "Todos",
"notifications.filter.boosts": "Repartajasyones",
"notifications.filter.favourites": "Te plazen",
"notifications.filter.follows": "Segidos",
"notifications.filter.mentions": "Enmentaduras",
"notifications.filter.polls": "Rizultados de anketa",
"notifications.filter.statuses": "Aktualizasyones de personas a las kualas siges",
"notifications.grant_permission": "Da permiso.",
"notifications.group": "{count} avizos",
"notifications.mark_as_read": "Marka todos avizos komo meldados",
"notifications.permission_denied": "Avizos de ensimameza no estan desponivles porke ya se tiene refuzado el permiso",
"notifications.permission_denied_alert": "\"No se pueden kapasitar los avizos de ensimameza, porke ya se tiene refuzado el permiso de navigador",
"notifications.permission_required": "Avizos de ensimameza no estan desponivles porke los nesesarios permisos no tienen sido risividos.",
"notifications_permission_banner.enable": "Kapasitar avizos de ensimameza",
"notifications_permission_banner.how_to_control": "Para risivir avizos kuando Mastodon no esta avierto, kapasita avizos de ensimameza. Puedes kontrolar presizamente kualos tipos de enteraksiones djeneren avizos de ensimameza kon el boton {icon} arriva kuando esten kapasitadas.",
"notifications_permission_banner.title": "Nunka te piedres niente",
"onboarding.action.back": "Va atras",
"onboarding.actions.back": "Va atras",
"onboarding.profile.display_name": "Nombre amostrado",
"picture_in_picture.restore": "Restora",
"poll.closed": "Serrado",
"poll.refresh": "Arefreska",
"poll.total_people": "{count, plural, one {# persona} other {# personas}}",
"poll.total_votes": "{count, plural, one {# voto} other {# votos}}",
"poll.vote": "Vota",
"poll.voted": "Votates por esta repuesta",
"poll.votes": "{votes, plural, one {# voto} other {# votos}}",
"poll_button.add_poll": "Adjusta anketa",
"poll_button.remove_poll": "Kita anketa",
"privacy.change": "Troka privasita de publikasyon",
"privacy.direct.long": "Vizivle solo para utilizadores enmentados",
"privacy.direct.short": "Solo personas enmentadas",
"privacy.private.long": "Vizivle solo para suivantes",
"privacy.private.short": "Solo suivantes",
"privacy.public.long": "Vizivle para todos",
"privacy.public.short": "Publiko",
"privacy.unlisted.long": "Vizivle para todos, ama eskluido de las fonksiones de diskuvrimyento",
"privacy.unlisted.short": "No listado",
"privacy_policy.last_updated": "Ultima aktualizasyon: {date}",
"privacy_policy.title": "Politika de privasita",
"refresh": "Arefreska",
"regeneration_indicator.label": "Eskargando…",
"regeneration_indicator.sublabel": "Tu linya de tiempo prinsipala esta preparando!",
"relative_time.days": "{number} d",
"relative_time.full.days": "antes {number, plural, one {# diya} other {# diyas}}",
"relative_time.full.hours": "antes {number, plural, one {# ora} other {# oras}}",
"relative_time.full.just_now": "agora",
"relative_time.full.minutes": "antes {number, plural, one {# minuto} other {# minutos}}",
"relative_time.full.seconds": "antes {number, plural, one {# sigundo} other {# sigundos}}",
"relative_time.hours": "{number} o",
"relative_time.just_now": "agora",
"relative_time.minutes": "{number} m",
"relative_time.seconds": "{number} s",
"relative_time.today": "oy",
"reply_indicator.cancel": "Anula",
"report.block": "Bloka",
"report.block_explanation": "No veras sus publikasyones. No podra ver tus publikasyones ni segirte. Podra saver ke le blokates.",
"report.categories.other": "Otros",
"report.categories.spam": "Spam",
"report.categories.violation": "El kontenido viola una o mas reglas del sirvidor",
"report.category.subtitle": "Eskoje la mijor koensidensya",
"report.category.title": "Deskrive el problem kon {type}",
"report.category.title_account": "profil",
"report.category.title_status": "publikasyon",
"report.close": "Fecho",
"report.comment.title": "Ay algo mas ke deveriamos saver?",
"report.forward": "Reembiar a {target}",
"report.forward_hint": "Este kuento es de otro sirvidor. Embiar una kopia anonimizada del raporto ayi tamyen?",
"report.mute": "Silensia",
"report.mute_explanation": "No veras sus publikasyones. Ainda pueden segirte i no va saver ke le silensiates.",
"report.placeholder": "Otros komentos",
"report.reasons.dislike": "No me plaze",
"report.reasons.dislike_description": "\"No es algo ke kero ver",
"report.reasons.other": "Es otra koza",
"report.reasons.other_description": "El problem no es de las otras kategorias",
"report.reasons.spam": "Es spam",
"report.reasons.spam_description": "Atadijos malisiozos, enteraksyones falsas o repuestas repetitivas",
"report.reasons.violation": "Viola las reglas del sirvidor",
"report.reasons.violation_description": "Saves ke viola reglas espesifikas",
"report.rules.subtitle": "Eskoje todas ke korespondan",
"report.rules.title": "Kualas reglas estan violadas?",
"report.statuses.subtitle": "Eskoje todas ke korespondan",
"report.statuses.title": "Ay alguna publikasyon ke suporta este raporto?",
"report.submit": "Embiar",
"report.target": "Raportando a {target}",
"report.thanks.take_action": "Aki estan tus opsyones para kontrolar lo ke ves en Mastodon:",
"report.thanks.take_action_actionable": "Mientres revizamos esto, puedes tomar aksyones kontra @{name}:",
"report.thanks.title": "No keres ver esto?",
"report.thanks.title_actionable": "Mersi por raportarlo, vamos revizarlo.",
"report.unfollow": "Desegir a @{name}",
"report.unfollow_explanation": "Estas sigiendo este kuento. Para no ver sus publikasyones en tu linya de tiempo, puedes deshar de segirlo.",
"report_notification.attached_statuses": "{count, plural, one {{count} publikasyon} other {{count} publikasyones}} atadas",
"report_notification.categories.other": "Otros",
"report_notification.categories.spam": "Spam",
"report_notification.categories.violation": "Violasion de reglas",
"report_notification.open": "Avre raporto",
"search.no_recent_searches": "No ay bushkedas resientes",
"search.placeholder": "Bushka",
"search.quick_action.account_search": "Profiles ke koresponden kon {x}",
"search.quick_action.go_to_account": "Va al profil {x}",
"search.quick_action.go_to_hashtag": "Va a la etiketa {x}",
"search.quick_action.open_url": "Avre URL en Mastodon",
"search.quick_action.status_search": "Publikasyones ke koresponden kon {x}",
"search.search_or_paste": "Bushka o apega URL",
"search_popout.quick_actions": "Aksiones rapidas",
"search_popout.recent": "Bushkedas resientes",
"search_results.accounts": "Profiles",
"search_results.all": "Todos",
"search_results.hashtags": "Etiketas",
"search_results.nothing_found": "No se pudo topar niente para estos terminos de bushkeda",
"search_results.see_all": "Ve todo",
"search_results.statuses": "Publikasyones",
"search_results.title": "Bushka por {q}",
"server_banner.about_active_users": "Utilizadores aktivos en este sirvidor durante los ultimos 30 diyas (utilizadores aktivos mensuales)",
"server_banner.active_users": "utilizadores aktivos",
"server_banner.administered_by": "Administrado por:",
"server_banner.introduction": "{domain} es parte de la red sosyala desentralizada liderada por {mastodon}.",
"server_banner.learn_more": "Ambezate mas",
"server_banner.server_stats": "Estatistikas del sirvidor:",
"sign_in_banner.create_account": "Kriya kuento",
"sign_in_banner.sign_in": "Konektate",
"sign_in_banner.sso_redirect": "Konektate o enrejistrate",
"status.filter": "Filtra esta publikasyon",
"status.filtered": "Filtrado",
"status.hide": "Eskonde publikasyon",
"status.history.created": "{name} kriyo {date}",
"status.history.edited": "{name} edito {date}",
"status.load_more": "Eskarga mas",
"status.media_hidden": "Multimedia eskondidos",
"status.mention": "Enmenta a @{name}",
"status.more": "Mas",
"status.mute": "Silensia a @{name}",
"status.mute_conversation": "Silensia konversasyon",
"status.open": "Espande publikasyon",
"status.pin": "Fiksa en profil",
"status.pinned": "Publikasyon fiksada",
"status.read_more": "Melda mas",
"status.reblog": "Repartaja",
"status.reblog_private": "Repartaja kon vizibilita orijinala",
"status.reblogged_by": "{name} repartajo",
"status.reblogs.empty": "Ainda nadie tiene repartajado esta publikasyon. Kuando algien lo aga, se amostrara aki.",
"status.redraft": "Efasa i eskrive de muevo",
"status.remove_bookmark": "Kita markador",
"status.replied_to": "Arispondio a {name}",
"status.reply": "Arisponde",
"status.replyAll": "Arisponde al filo",
"status.report": "Raporta @{name}",
"status.sensitive_warning": "Kontenido sensivle",
"status.share": "Partaja",
"status.show_filter_reason": "Amostra entanto",
"status.show_less": "Amostra manko",
"status.show_less_all": "Amostra manko para todo",
"status.show_more": "Amostra mas",
"status.show_more_all": "Amostra mas para todo",
"status.show_original": "Amostra orijinal",
"status.translate": "Trezlada",
"status.translated_from_with": "Trezladado dizde {lang} kon {provider}",
"status.uncached_media_warning": "Vista previa no desponivle",
"status.unmute_conversation": "Desilensiar konversasyon",
"status.unpin": "Defiksar del profil",
"subscribed_languages.lead": "Solo publikasyones en linguas eskojidas se amostraran en tus linya de tiempo prinsipala i listas dempues del trokamiento. Eskoje dinguna para risivir publikasyones en todas las linguas.",
"subscribed_languages.save": "Guadra trokamientos",
"subscribed_languages.target": "Troka linguas abonadas para {target}",
"tabs_bar.home": "Linya prinsipala",
"tabs_bar.notifications": "Avizos",
"time_remaining.days": "{number, plural, one {# diya restante} other {# diyas restantes}}",
"time_remaining.hours": "{number, plural, one {# ora restante} other {# oras restantes}}",
"time_remaining.minutes": "{number, plural, one {# minuto restante} other {# minutos restantes}}",
"time_remaining.moments": "Momentos restantes",
"time_remaining.seconds": "{number, plural, one {# sigundo restante} other {# sigundos restantes}}",
"timeline_hint.remote_resource_not_displayed": "{resource} de otros sirvidores no se amostran.",
"timeline_hint.resources.followers": "Suivantes",
"timeline_hint.resources.follows": "Segidos",
"timeline_hint.resources.statuses": "Publikasyones mas viejas",
"trends.counter_by_accounts": "{count, plural, one {{counter} kuento} other {{counter} kuentos}} en los ultimos {days, plural, one {diyas} other {{days} diyas}}",
"trends.trending_now": "Trendes",
"ui.beforeunload": "La publikasyon ke estas eskriviendo se pedrera si sales de Mastodon.",
"units.short.billion": "{count} MM",
"units.short.million": "{count} M",
"units.short.thousand": "{count} K",
"upload_area.title": "Arastra i mete para kargar",
"upload_button.label": "Adjusta imajes, un video or una dosya audio",
"upload_error.limit": "Limito de dosyas kargadas eksedido.",
"upload_error.poll": "No se permite kargar dosyas kon anketas.",
"upload_form.audio_description": "Deskrive para personas sodras o kon problemes auditivos",
"upload_form.description": "Deskrive para personas siegas o kon problemes vizuales",
"upload_form.description_missing": "No adjustates deskripsion",
"upload_form.edit": "Edita",
"upload_form.thumbnail": "Troka minyatura",
"upload_form.undo": "Efasa",
"upload_form.video_description": "Deskrive para personas sodras, kon problemes auditivos, siegas o kon problemes vizuales",
"upload_modal.analyzing_picture": "Analizando imaje…",
"upload_modal.apply": "Aplika",
"upload_modal.applying": "Aplikando…",
"upload_modal.choose_image": "Eskoje imaje",
"upload_modal.description_placeholder": "Lorem ipsum dolor sit amet",
"upload_modal.detect_text": "Detektar teksto de la imaje",
"upload_modal.edit_media": "Edita multimedia",
"upload_modal.hint": "Klika o arrastra el sirkolo en la vista previa para eskojer el punto fokal ke siempre estara en vista en todas las minyaturas.",
"upload_modal.preparing_ocr": "Preparando OCR…",
"upload_modal.preview_label": "Vista previa ({ratio})",
"upload_progress.label": "Kargando...",
"upload_progress.processing": "Prosesando…",
"video.close": "Serra video",
"video.download": "Abasha dosya",
"video.exit_fullscreen": "Sal de ekran kompleto",
"video.expand": "Espande video",
"video.fullscreen": "Ekran kompleto",
"video.hide": "Eskonde video",
"video.mute": "Silensia son",
"video.pause": "Pauza",
"video.play": "Reproduze",
"video.unmute": "Desilensia son"
}

View file

@ -49,5 +49,32 @@
"admin.dashboard.retention.average": "औसत",
"admin.dashboard.retention.cohort_size": "नयाँ प्रयोगकर्ताहरू",
"alert.rate_limited.message": "कृपया {retry_time, time, medium} पछि पुन: प्रयास गर्नुहोस्।",
"alert.unexpected.message": "एउटा अनपेक्षित त्रुटि भयो।"
"alert.unexpected.message": "एउटा अनपेक्षित त्रुटि भयो।",
"bundle_column_error.retry": "पुन: प्रयास गर्नुहोस्",
"bundle_modal_error.close": "बन्द गर्नुहोस्",
"bundle_modal_error.message": "यो कम्पोनेन्ट लोड गर्दा केही गडबड भयो।",
"bundle_modal_error.retry": "Try again",
"closed_registrations.other_server_instructions": "Mastodon विकेन्द्रीकृत भएकोले, तपाइँ अर्को सर्भरमा खाता खोल्न सक्नुहुन्छ र पनि यो सर्भरसँग अन्तरक्रिया गर्न सक्नुहुन्छ।",
"closed_registrations_modal.description": "हाल {domain} मा खाता सिर्जना गर्न सम्भव छैन, तर कृपया ध्यान राख्नुहोस् कि तपाईंले Mastodon प्रयोग गर्नको लागि {domain} मा नै खाता खोल्न आवश्यक छैन।",
"closed_registrations_modal.find_another_server": "अर्को सर्भर खोज्नुहोस्",
"closed_registrations_modal.title": "Mastodon मा साइन अप गर्दै",
"column.blocks": "ब्लक गरिएको प्रयोगकर्ताहरु",
"column.directory": "प्रोफाइल ब्राउज गर्नुहोस्",
"column.domain_blocks": "ब्लक गरिएको डोमेन",
"column.follow_requests": "फलो अनुरोधहरू",
"column.lists": "सूचीहरू",
"column.notifications": "सूचनाहरू",
"column_header.hide_settings": "सेटिङ्हरू लुकाउनुहोस्",
"column_subheading.settings": "सेटिङहरू",
"compose.language.change": "भाषा परिवर्तन गर्नुहोस्",
"compose.language.search": "भाषाहरू खोज्नुहोस्...",
"compose_form.direct_message_warning_learn_more": "थप जान्नुहोस्",
"compose_form.poll.add_option": "विकल्प थप्नुहोस्",
"compose_form.poll.remove_option": "यो विकल्प हटाउनुहोस्",
"compose_form.publish_form": "नयाँ पोस्ट",
"compose_form.save_changes": "परिवर्तनहरू सेभ गर्नुहोस",
"compose_form.sensitive.hide": "{count, plural, one {संवेदनशील मिडियाको रूपमा चिन्ह लगाउनुहोस्} other {संवेदनशील मिडियाहरूको रूपमा चिन्ह लगाउनुहोस्}}",
"compose_form.sensitive.marked": "{count, plural, one {मिडियालाई संवेदनशील रूपमा चिन्ह लगाइएको छ} other {मिडियाहरूलाई संवेदनशील रूपमा चिन्ह लगाइएको छ}}",
"compose_form.sensitive.unmarked": "{count, plural, one {मिडियालाई संवेदनशील रूपमा चिन्ह लगाइएको छैन} other {मिडियाहरूलाई संवेदनशील रूपमा चिन्ह लगाइएको छैन}}",
"compose_form.spoiler_placeholder": "यहाँ आफ्नो चेतावनी लेख्नुहोस्"
}

View file

@ -1,25 +1,39 @@
{
"about.contact": "ਸੰਪਰਕ:",
"about.domain_blocks.silenced.title": "ਸੀਮਿਤ",
"about.domain_blocks.suspended.title": "ਮੁਅੱਤਲ ਕੀਤੀ",
"about.rules": "ਸਰਵਰ ਨਿਯਮ",
"account.account_note_header": "ਨੋਟ",
"account.badges.bot": "Bot",
"account.add_or_remove_from_list": "ਸੂਚੀ ਵਿੱਚ ਜੋੜੋ ਜਾਂ ਹਟਾਓ",
"account.badges.bot": "ਆਟੋਮੇਟ ਕੀਤਾ",
"account.badges.group": "ਗਰੁੱਪ",
"account.block": "@{name} ਉੱਤੇ ਪਾਬੰਦੀ ਲਾਓ",
"account.block_domain": "{domain} ਡੋਮੇਨ ਉੱਤੇ ਪਾਬੰਦੀ ਲਾਓ",
"account.block_short": "ਪਾਬੰਦੀ",
"account.blocked": "ਪਾਬੰਦੀਸ਼ੁਦਾ",
"account.cancel_follow_request": "Withdraw follow request",
"account.follow": "ਪ੍ਰਸ਼ੰਸਕ ਬਣੋ",
"account.followers": "ਪ੍ਰਸ਼ੰਸਕ",
"account.following": "ਪ੍ਰਸ਼ੰਸਕ ਹਾਂ",
"account.cancel_follow_request": "ਫ਼ਾਲੋ ਕਰਨ ਨੂੰ ਰੱਦ ਕਰੋ",
"account.edit_profile": "ਪਰੋਫਾਈਲ ਨੂੰ ਸੋਧੋ",
"account.follow": "ਫ਼ਾਲੋ",
"account.followers": "ਫ਼ਾਲੋਅਰ",
"account.followers.empty": "ਇਸ ਵਰਤੋਂਕਾਰ ਨੂੰ ਹਾਲੇ ਕੋਈ ਫ਼ਾਲੋ ਨਹੀਂ ਕਰਦਾ ਹੈ।",
"account.following": "ਫ਼ਾਲੋ ਕੀਤਾ",
"account.follows.empty": "ਇਹ ਵਰਤੋਂਕਾਰ ਹਾਲੇ ਕਿਸੇ ਨੂੰ ਫ਼ਾਲੋ ਨਹੀਂ ਕਰਦਾ ਹੈ।",
"account.follows_you": "ਤੁਹਾਨੂੰ ਫ਼ਾਲੋ ਕਰੋ",
"account.media": "ਮੀਡੀਆ",
"account.muted": "ਮੌਨ ਕੀਤੀਆਂ",
"account.posts": "Toots",
"account.posts_with_replies": "Toots and replies",
"account.requested": "Awaiting approval",
"account.posts": "ਪੋਸਟਾਂ",
"account.posts_with_replies": "ਪੋਸਤਾਂ ਅਤੇ ਜਵਾਬ",
"account.requested": "ਮਨਜ਼ੂਰੀ ਕੀਤੀ ਜਾ ਰਹੀ ਹੈ। ਫ਼ਾਲੋ ਬੇਨਤੀਆਂ ਨੂੰ ਰੱਦ ਕਰਨ ਲਈ ਕਲਿੱਕ ਕਰੋ",
"account.requested_follow": "{name} ਨੇ ਤੁਹਾਨੂੰ ਫ਼ਾਲੋ ਕਰਨ ਦੀ ਬੇਨਤੀ ਕੀਤੀ ਹੈ",
"account.statuses_counter": "{count, plural, one {{counter} Toot} other {{counter} Toots}}",
"account.unblock": "@{name} ਤੋਂ ਪਾਬੰਦੀ ਹਟਾਓ",
"account.unblock_domain": "{domain} ਡੋਮੇਨ ਤੋਂ ਪਾਬੰਦੀ ਹਟਾਓ",
"account.unblock_short": "ਪਾਬੰਦੀ ਹਟਾਓ",
"account.unfollow": "ਪ੍ਰਸ਼ੰਸਕੀ ਰੱਦ ਕਰੋ",
"account.unfollow": "ਅਣ-ਫ਼ਾਲੋ",
"account.unmute_short": "ਮੌਨ-ਰਹਿਤ ਕਰੋ",
"account_note.placeholder": "Click to add a note",
"admin.dashboard.retention.average": "ਔਸਤ",
"admin.dashboard.retention.cohort_size": "ਨਵੇਂ ਵਰਤੋਂਕਾਰ",
"alert.unexpected.title": "ਓਹੋ!",
"announcement.announcement": "ਹੋਕਾ",
"bundle_column_error.network.title": "ਨੈੱਟਵਰਕ ਦੀ ਸਮੱਸਿਆ",
@ -27,35 +41,50 @@
"bundle_modal_error.close": "ਬੰਦ ਕਰੋ",
"bundle_modal_error.retry": "ਮੁੜ-ਕੋਸ਼ਿਸ਼ ਕਰੋ",
"column.about": "ਸਾਡੇ ਬਾਰੇ",
"column.blocks": "ਪਾਬੰਦੀ ਲਾਏ ਵਰਤੋਂਕਾਰ",
"column.bookmarks": "ਬੁੱਕਮਾਰਕ",
"column.home": "ਮੁੱਖ ਪੰਨਾ",
"column.community": "ਲੋਕਲ ਸਮਾਂ-ਲਾਈਨ",
"column.direct": "ਨਿੱਜੀ ਜ਼ਿਕਰ",
"column.favourites": "ਮਨਪਸੰਦ",
"column.follow_requests": "ਫ਼ਾਲੋ ਦੀਆਂ ਬੇਨਤੀਆਂ",
"column.home": "ਮੁੱਖ ਸਫ਼ਾ",
"column.lists": "ਸੂਚੀਆਂ",
"column.notifications": "ਸੂਚਨਾਵਾਂ",
"column.pins": "Pinned toot",
"column.pins": "ਟੰਗੀਆਂ ਪੋਸਟਾਂ",
"column_back_button.label": "ਪਿੱਛੇ",
"column_header.pin": "ਟੰਗੋ",
"column_header.show_settings": "ਸੈਟਿੰਗਾਂ ਦਿਖਾਓ",
"column_header.unpin": "ਲਾਹੋ",
"column_subheading.settings": "ਸੈਟਿੰਗਾਂ",
"community.column_settings.media_only": "Media only",
"community.column_settings.local_only": "ਸਿਰਫ ਲੋਕਲ ਹੀ",
"community.column_settings.media_only": "ਸਿਰਫ ਮੀਡੀਆ ਹੀ",
"community.column_settings.remote_only": "ਸਿਰਫ਼ ਰਿਮੋਟ ਹੀ",
"compose.language.change": "ਭਾਸ਼ਾ ਬਦਲੋ",
"compose.language.search": "ਭਾਸ਼ਾਵਾਂ ਦੀ ਖੋਜ...",
"compose.published.open": "ਖੋਲ੍ਹੋ",
"compose.saved.body": "ਪੋਸਟ ਸੰਭਾਲੀ ਗਈ।",
"compose_form.direct_message_warning_learn_more": "ਹੋਰ ਜਾਣੋ",
"compose_form.encryption_warning": "Posts on Mastodon are not end-to-end encrypted. Do not share any dangerous information over Mastodon.",
"compose_form.hashtag_warning": "This post won't be listed under any hashtag as it is unlisted. Only public posts can be searched by hashtag.",
"compose_form.lock_disclaimer.lock": "ਲਾਕ ਹੈ",
"compose_form.placeholder": "What is on your mind?",
"compose_form.publish": "ਪ੍ਰਕਾਸ਼ਨ ਕਰੋ",
"compose_form.publish_form": "Publish",
"compose_form.save_changes": "ਤਬਦੀਲੀਆਂ ਸਾਂਭੋ",
"compose_form.spoiler.marked": "Text is hidden behind warning",
"compose_form.spoiler.unmarked": "Text is not hidden",
"compose_form.spoiler.marked": "ਸਮੱਗਰੀ ਚੇਤਾਵਨੀ ਨੂੰ ਹਟਾਓ",
"compose_form.spoiler.unmarked": "ਸਮੱਗਰੀ ਬਾਰੇ ਚੇਤਾਵਨੀ ਜੋੜੋ",
"confirmation_modal.cancel": "ਰੱਦ ਕਰੋ",
"confirmations.block.confirm": "ਬਲਾਕ",
"confirmations.delete.confirm": "ਮਿਟਾਓ",
"confirmations.delete.message": "Are you sure you want to delete this status?",
"confirmations.delete_list.confirm": "ਮਿਟਾਓ",
"confirmations.block.confirm": "ਪਾਬੰਦੀ",
"confirmations.delete.confirm": "ਟਾਓ",
"confirmations.delete.message": "ਕੀ ਤੁਸੀਂ ਇਹ ਪੋਸਟ ਨੂੰ ਹਟਾਉਣਾ ਚਾਹੁੰਦੇ ਹੋ?",
"confirmations.delete_list.confirm": "ਟਾਓ",
"confirmations.discard_edit_media.confirm": "ਰੱਦ ਕਰੋ",
"confirmations.domain_block.confirm": "Hide entire domain",
"confirmations.domain_block.confirm": "ਪੂਰੀ ਡੋਮੇਨ ਉੱਤੇ ਪਾਬੰਦੀ ਲਾਓ",
"confirmations.edit.confirm": "ਸੋਧ",
"confirmations.logout.confirm": "ਬਾਹਰ ਹੋਵੋ",
"confirmations.mute.confirm": "ਮੌਨ ਕਰੋ",
"confirmations.reply.confirm": "ਜਵਾਬ ਦੇਵੋ",
"confirmations.unfollow.confirm": "ਪ੍ਰਸ਼ੰਸਕੀ ਰੱਦ ਕਰੋ",
"confirmations.unfollow.confirm": "ਅਣ-ਫ਼ਾਲੋ",
"copypaste.copied": "ਕਾਪੀ ਕੀਤਾ",
"copypaste.copy_to_clipboard": "ਕਲਿੱਪਬੋਰਡ 'ਤੇ ਕਾਪੀ ਕਰੋ",
"disabled_account_banner.account_settings": "ਖਾਤੇ ਦੀਆਂ ਸੈਟਿੰਗਾਂ",
@ -63,165 +92,252 @@
"dismissable_banner.explore_links": "These news stories are being talked about by people on this and other servers of the decentralized network right now.",
"dismissable_banner.explore_tags": "These hashtags are gaining traction among people on this and other servers of the decentralized network right now.",
"embed.instructions": "Embed this status on your website by copying the code below.",
"emoji_button.activity": "ਗਤੀਵਿਧੀਆਂ",
"emoji_button.clear": "ਸਾਫ਼ ਕਰੋ",
"emoji_button.activity": "ਗਤੀਵਿਧੀ",
"emoji_button.clear": "ਮਿਟਾਓ",
"emoji_button.custom": "ਕਸਟਮ",
"emoji_button.flags": "ਝੰਡੀਆਂ",
"emoji_button.food": "ਖਾਣਾ-ਪੀਣਾ",
"emoji_button.nature": "ਕੁਦਰਤ",
"emoji_button.objects": "ਇਕਾਈ",
"emoji_button.people": "ਲੋਕ",
"empty_column.account_timeline": "No toots here!",
"emoji_button.search": "ਖੋਜ ਕਰੋ...",
"emoji_button.search_results": "ਖੋਜ ਨਤੀਜੇ",
"emoji_button.symbols": "ਚਿੰਨ੍ਹ",
"emoji_button.travel": "ਸੈਰ ਸਪਾਟਾ ਤੇ ਥਾਵਾਂ",
"empty_column.account_timeline": "ਇੱਥੇ ਕੋਈ ਪੋਸਟ ਨਹੀਂ ਹੈ!",
"empty_column.bookmarked_statuses": "You don't have any bookmarked toots yet. When you bookmark one, it will show up here.",
"empty_column.home": "Your home timeline is empty! Follow more people to fill it up. {suggestions}",
"empty_column.home": "ਤੁਹਾਡੀ ਟਾਈਮ-ਲਾਈਨ ਖਾਲੀ ਹੈ! ਇਸ ਨੂੰ ਭਰਨ ਲਈ ਹੋਰ ਲੋਕਾਂ ਨੂੰ ਫ਼ਾਲੋ ਕਰੋ।",
"empty_column.list": "There is nothing in this list yet. When members of this list post new statuses, they will appear here.",
"errors.unexpected_crash.report_issue": "ਮੁੱਦੇ ਦੀ ਰਿਪੋਰਟ ਕਰੋ",
"explore.suggested_follows": "ਲੋਕ",
"explore.title": "ਪੜਚੋਲ ਕਰੋ",
"explore.trending_links": "ਖ਼ਬਰਾਂ",
"explore.trending_statuses": "ਸੰਪਾਦਨਾਵਾਂ",
"follow_request.reject": "ਅਸਵੀਕਾਰ ਕਰੋ",
"explore.trending_statuses": "ਪੋਸਟਾਂ",
"explore.trending_tags": "ਹੈਸ਼ਟੈਗ",
"filter_modal.added.settings_link": "ਸੈਟਿੰਗਾਂ ਸਫ਼ਾ",
"firehose.all": "ਸਭ",
"firehose.local": "ਇਹ ਸਰਵਰ",
"firehose.remote": "ਹੋਰ ਸਰਵਰ",
"follow_request.reject": "ਰੱਦ ਕਰੋ",
"footer.about": "ਸਾਡੇ ਬਾਰੇ",
"footer.get_app": "ਐਪ ਲਵੋ",
"footer.invite": "ਲੋਕਾਂ ਨੂੰ ਸੱਦਾ ਭੇਜੋ",
"footer.keyboard_shortcuts": "ਕੀਬੋਰਡ ਸ਼ਾਰਟਕੱਟ",
"footer.privacy_policy": "ਪਰਦੇਦਾਰੀ ਨੀਤੀ",
"footer.source_code": "ਸਰੋਤ ਕੋਡ ਵੇਖੋ",
"footer.status": "ਹਾਲਤ",
"generic.saved": "ਸਾਂਭੀ ਗਈ",
"getting_started.heading": "ਸ਼ੁਰੂ ਕਰੀਏ",
"hashtag.column_header.tag_mode.all": "ਅਤੇ {additional}",
"hashtag.column_header.tag_mode.any": "ਜਾਂ {additional}",
"hashtag.column_header.tag_mode.none": "{additional} ਬਿਨਾਂ",
"hashtag.column_settings.tag_mode.any": "ਇਹਨਾਂ ਵਿੱਚੋਂ ਕੋਈ",
"hashtag.column_settings.tag_mode.none": "ਇਹਨਾਂ ਵਿੱਚੋਂ ਕੋਈ ਨਹੀਂ",
"hashtag.column_settings.tag_toggle": "Include additional tags in this column",
"hashtag.follow": "ਹੈਸ਼ਟੈਗ ਨੂੰ ਫ਼ਾਲੋ ਕਰੋ",
"hashtag.unfollow": "ਹੈਸ਼ਟੈਗ ਨੂੰ ਅਣ-ਫ਼ਾਲੋ ਕਰੋ",
"home.column_settings.basic": "ਆਮ",
"keyboard_shortcuts.back": "to navigate back",
"keyboard_shortcuts.blocked": "to open blocked users list",
"keyboard_shortcuts.boost": "to boost",
"keyboard_shortcuts.column": "to focus a status in one of the columns",
"interaction_modal.title.follow": "{name} ਨੂੰ ਫ਼ਾਲੋ ਕਰੋ",
"keyboard_shortcuts.back": "ਪਿੱਛੇ ਜਾਓ",
"keyboard_shortcuts.blocked": "ਪਾਬੰਦੀ ਲਾਏ ਵਰਤੋਂਕਾਰਾਂ ਦੀ ਸੂਚੀ ਖੋਲ੍ਹੋ",
"keyboard_shortcuts.boost": "ਪੋਸਟ ਨੂੰ ਬੂਸਟ ਕਰੋ",
"keyboard_shortcuts.column": "ਫੋਕਸ ਕਾਲਮ",
"keyboard_shortcuts.compose": "to focus the compose textarea",
"keyboard_shortcuts.description": "ਵਰਣਨ",
"keyboard_shortcuts.direct": "to open direct messages column",
"keyboard_shortcuts.down": "to move down in the list",
"keyboard_shortcuts.enter": "to open status",
"keyboard_shortcuts.federated": "to open federated timeline",
"keyboard_shortcuts.heading": "Keyboard Shortcuts",
"keyboard_shortcuts.heading": "ਕੀਬੋਰਡ ਸ਼ਾਰਟਕੱਟ",
"keyboard_shortcuts.home": "to open home timeline",
"keyboard_shortcuts.legend": "to display this legend",
"keyboard_shortcuts.local": "to open local timeline",
"keyboard_shortcuts.mention": "to mention author",
"keyboard_shortcuts.muted": "to open muted users list",
"keyboard_shortcuts.my_profile": "to open your profile",
"keyboard_shortcuts.notifications": "to open notifications column",
"keyboard_shortcuts.notifications": "ਨੋਟੀਫਿਕੇਸ਼ਨ ਕਾਲਮ ਖੋਲ੍ਹੋ",
"keyboard_shortcuts.open_media": "to open media",
"keyboard_shortcuts.pinned": "to open pinned toots list",
"keyboard_shortcuts.profile": "to open author's profile",
"keyboard_shortcuts.reply": "to reply",
"keyboard_shortcuts.profile": "ਲੇਖਕ ਦਾ ਪਰੋਫਾਈਲ ਖੋਲ੍ਹੋ",
"keyboard_shortcuts.reply": "ਪੋਸਟ ਨੂੰ ਜਵਾਬ ਦਿਓ",
"keyboard_shortcuts.requests": "to open follow requests list",
"keyboard_shortcuts.search": "to focus search",
"keyboard_shortcuts.spoilers": "to show/hide CW field",
"keyboard_shortcuts.start": "to open \"get started\" column",
"keyboard_shortcuts.toggle_hidden": "to show/hide text behind CW",
"keyboard_shortcuts.toggle_sensitivity": "to show/hide media",
"keyboard_shortcuts.toot": "to start a brand new toot",
"keyboard_shortcuts.toggle_sensitivity": "ਮੀਡੀਆ ਦਿਖਾਉਣ/ਲੁਕਾਉਣ ਲਈ",
"keyboard_shortcuts.toot": "ਨਵੀਂ ਪੋਸਟ ਸ਼ੁਰੂ ਕਰੋ",
"keyboard_shortcuts.unfocus": "to un-focus compose textarea/search",
"keyboard_shortcuts.up": "to move up in the list",
"lightbox.close": "ਬੰਦ ਕਰੋ",
"lightbox.next": "ਅਗਲੀ",
"lightbox.previous": "ਪਿਛਲੀ",
"lists.delete": "ਸੂਚੀ ਮਿਟਾਓ",
"link_preview.author": "{name} ਵਲੋਂ",
"lists.account.add": "ਸੂਚੀ ਵਿੱਚ ਜੋੜੋ",
"lists.account.remove": "ਸੂਚੀ ਵਿਚੋਂ ਹਟਾਓ",
"lists.delete": "ਸੂਚੀ ਹਟਾਓ",
"lists.replies_policy.followed": "ਕੋਈ ਵੀ ਫ਼ਾਲੋ ਕੀਤਾ ਵਰਤੋਂਕਾਰ",
"lists.replies_policy.none": "ਕੋਈ ਨਹੀਂ",
"loading_indicator.label": "ਲੋਡ ਹੋ ਰਿਹਾ ਹੈ…",
"mute_modal.duration": "ਮਿਆਦ",
"navigation_bar.about": "ਸਾਡੇ ਬਾਰੇ",
"navigation_bar.about": "ਇਸ ਬਾਰੇ",
"navigation_bar.advanced_interface": "ਤਕਨੀਕੀ ਵੈੱਬ ਇੰਟਰਫੇਸ ਵਿੱਚ ਖੋਲ੍ਹੋ",
"navigation_bar.blocks": "ਪਾਬੰਦੀ ਲਾਏ ਵਰਤੋਂਕਾਰ",
"navigation_bar.bookmarks": "ਬੁੱਕਮਾਰਕ",
"navigation_bar.compose": "Compose new toot",
"navigation_bar.community_timeline": "ਲੋਕਲ ਸਮਾਂ-ਲਾਈਨ",
"navigation_bar.compose": "ਨਵੀਂ ਪੋਸਟ ਲਿਖੋ",
"navigation_bar.direct": "ਨਿੱਜੀ ਜ਼ਿਕਰ",
"navigation_bar.discover": "ਖੋਜ",
"navigation_bar.domain_blocks": "Hidden domains",
"navigation_bar.domain_blocks": "ਪਾਬੰਦੀ ਲਾਏ ਡੋਮੇਨ",
"navigation_bar.edit_profile": "ਪਰੋਫਾਈਲ ਨੂੰ ਸੋਧੋ",
"navigation_bar.explore": "ਪੜਚੋਲ ਕਰੋ",
"navigation_bar.favourites": "ਮਨਪਸੰਦ",
"navigation_bar.follow_requests": "ਫ਼ਾਲੋ ਦੀਆਂ ਬੇਨਤੀਆਂ",
"navigation_bar.followed_tags": "ਫ਼ਾਲੋ ਕੀਤੇ ਹੈਸ਼ਟੈਗ",
"navigation_bar.follows_and_followers": "ਫ਼ਾਲੋ ਅਤੇ ਫ਼ਾਲੋ ਕਰਨ ਵਾਲੇ",
"navigation_bar.lists": "ਸੂਚੀਆਂ",
"navigation_bar.logout": "ਲਾੱਗ ਆਊਟ, ਬਾਹਰ ਆਉਣਾ",
"navigation_bar.logout": "ਲਾਗ ਆਉਟ",
"navigation_bar.personal": "ਨਿੱਜੀ",
"navigation_bar.pins": "Pinned toots",
"navigation_bar.preferences": "ਤਰਜੀਹਾਂ",
"navigation_bar.pins": "ਟੰਗੀਆਂ ਪੋਸਟਾਂ",
"navigation_bar.preferences": "ਪਸੰਦਾਂ",
"navigation_bar.search": "ਖੋਜੋ",
"navigation_bar.security": "ਸੁਰੱਖਿਆ",
"not_signed_in_indicator.not_signed_in": "You need to sign in to access this resource.",
"not_signed_in_indicator.not_signed_in": "ਇਹ ਸਰੋਤ ਵਰਤਣ ਲਈ ਤੁਹਾਨੂੰ ਲਾਗਇਨ ਕਰਨ ਦੀ ਲੋੜ ਹੈ।",
"notification.follow": "{name} ਨੇ ਤੁਹਾਨੂੰ ਫ਼ਾਲੋ ਕੀਤਾ",
"notification.follow_request": "{name} ਨੇ ਤੁਹਾਨੂੰ ਫ਼ਾਲੋ ਕਰਨ ਦੀ ਬੇਨਤੀ ਕੀਤੀ ਹੈ",
"notification.reblog": "{name} boosted your status",
"notifications.column_settings.status": "New toots:",
"notifications.column_settings.follow": "ਨਵੇਂ ਫ਼ਾਲੋਅਰ:",
"notifications.column_settings.follow_request": "ਨਵੀਆਂ ਫ਼ਾਲੋ ਬੇਨਤੀਆਂ:",
"notifications.column_settings.status": "ਨਵੀਆਂ ਪੋਸਟਾਂ:",
"notifications.column_settings.update": "ਸੋਧ:",
"notifications.filter.all": "ਸਭ",
"notifications.filter.follows": "ਪ੍ਰਸ਼ੰਸਕ ਬਣਨ 'ਤੇ",
"onboarding.actions.go_to_explore": "See what's trending",
"onboarding.actions.go_to_home": "Go to your home feed",
"onboarding.follows.lead": "You curate your own home feed. The more people you follow, the more active and interesting it will be. These profiles may be a good starting point—you can always unfollow them later!",
"onboarding.follows.title": "Popular on Mastodon",
"notifications.filter.boosts": "ਬੂਸਟ",
"notifications.filter.favourites": "ਮਨਪਸੰਦ",
"notifications.filter.follows": "ਫ਼ਾਲੋ",
"notifications.filter.mentions": "ਜ਼ਿਕਰ",
"onboarding.actions.go_to_explore": "ਮੈਨੂੰ ਰੁਝਾਨ ਵੇਖਾਓ",
"onboarding.actions.go_to_home": "ਮੇਰੀ ਮੁੱਖ ਫੀਡ ਉੱਤੇ ਲੈ ਜਾਓ",
"onboarding.follows.lead": "",
"onboarding.follows.title": "ਆਪਣੀ ਹੋਮ ਫੀਡ ਨੂੰ ਨਿੱਜੀ ਬਣਾਓ",
"onboarding.profile.note": "ਜਾਣਕਾਰੀ",
"onboarding.profile.save_and_continue": "ਸੰਭਾਲੋ ਅਤੇ ਜਾਰੀ ਰੱਖੋ",
"onboarding.profile.title": "ਪਰੋਫਾਈਲ ਸੈਟਅੱਪ",
"onboarding.profile.upload_avatar": "ਪਰੋਫਾਈਲ ਤਸਵੀਰ ਅੱਪਲੋਡ ਕਰੋ",
"onboarding.share.title": "ਆਪਣਾ ਪਰੋਫਾਈਲ ਸਾਂਝਾ ਕਰੋ",
"onboarding.start.lead": "Your new Mastodon account is ready to go. Here's how you can make the most of it:",
"onboarding.start.skip": "Want to skip right ahead?",
"onboarding.steps.follow_people.body": "You curate your own feed. Lets fill it with interesting people.",
"onboarding.steps.follow_people.title": "Follow {count, plural, one {one person} other {# people}}",
"onboarding.start.skip": "ਸ਼ੁਰੂ ਕਰਨ ਲਈ ਮਦਦ ਨਹੀਂ ਚਾਹੀਦੀ ਹੈ?",
"onboarding.start.title": "ਤੁਸੀਂ ਪੂਰਾ ਕਰਨ ਲਿਆ!",
"onboarding.steps.follow_people.body": "ਦਿਲਚਸਪ ਲੋਕਾਂ ਨੂੰ ਫ਼ਾਲੋ ਕਰੋ, ਇਹ ਤਾਂ ਮਸਟਾਡੋਨ ਹੈ।",
"onboarding.steps.follow_people.title": "ਆਪਣੀ ਹੋਮ ਫੀਡ ਨੂੰ ਨਿੱਜੀ ਬਣਾਓ",
"onboarding.steps.publish_status.body": "Say hello to the world.",
"onboarding.steps.publish_status.title": "ਆਪਣੀ ਪਹਿਲੀ ਪੋਸਟ ਕਰੋ",
"onboarding.steps.setup_profile.body": "Others are more likely to interact with you with a filled out profile.",
"onboarding.steps.setup_profile.title": "Customize your profile",
"onboarding.steps.share_profile.body": "Let your friends know how to find you on Mastodon!",
"onboarding.steps.share_profile.title": "Share your profile",
"poll.closed": "ਬੰਦ ਹੋਇਆ",
"onboarding.steps.setup_profile.title": "ਆਪਣੇ ਪਰੋਫਾਈਲ ਨੂੰ ਆਪਣਾ ਬਣਾਓ",
"onboarding.steps.share_profile.body": "ਆਪਣੇ ਮਿੱਤਰਾਂ ਨੂੰ ਦੱਸੋ ਤੁਹਾਨੂੰ ਮਸਟਾਡੋਨ ਕਿਵੇਂ ਲੱਗਿਆ",
"onboarding.steps.share_profile.title": "ਆਪਣੇ ਮਸਟਾਡੋਨ ਪਰੋਫਾਈਲ ਨੂੰ ਸਾਂਝਾ ਕਰੋ",
"poll.closed": "ਬੰਦ ਹ",
"poll.refresh": "ਤਾਜ਼ਾ ਕਰੋ",
"poll.vote": "ਵੋਟ ਪਾਓ",
"privacy.change": "Adjust status privacy",
"privacy.direct.short": "Direct",
"privacy.private.short": "Followers-only",
"privacy.change": "ਪੋਸਟ ਦੀ ਪਰਦੇਦਾਰੀ ਨੂੰ ਬਦਲੋ",
"privacy.direct.short": "ਸਿੱਧਾ ਲੋਕਾਂ ਦਾ ਜ਼ਿਕਰ ਕਰੋ",
"privacy.private.short": "ਸਿਰਫ਼ ਫ਼ਾਲੋਅਰ",
"privacy.public.short": "ਜਨਤਕ",
"privacy_policy.title": "ਪਰਦੇਦਾਰੀ ਨੀਤੀ",
"refresh": "ਤਾਜ਼ਾ ਕਰੋ",
"regeneration_indicator.label": "ਲੋਡ ਹੋ ਰਿਹਾ ਹੈ...",
"relative_time.full.just_now": "ਹੁਣੇ ਹੀ",
"relative_time.just_now": "ਹੁਣੇ",
"relative_time.minutes": "{number}ਮਿੰ",
"relative_time.seconds": "{number}ਸ",
"relative_time.today": "ਅੱਜ",
"reply_indicator.cancel": "ਰੱਦ ਕਰੋ",
"report.block": "ਬਲਾਕ",
"report.categories.legal": "ਕਨੂੰਨੀ",
"report.categories.other": "ਬਾਕੀ",
"report.categories.spam": "ਸਪਾਮ",
"report.category.title_status": "ਸੰਪਾਦਨਾ",
"report.categories.spam": "ਸਪੈਮ",
"report.category.title_account": "ਪਰੋਫਾਈਲ",
"report.category.title_status": "ਪੋਸਟ",
"report.close": "ਮੁਕੰਮਲ",
"report.mute": "ਮੌਨ ਕਰੋ",
"report.next": "ਅਗਲੀ",
"report.placeholder": "Type or paste additional comments",
"report.submit": "Submit report",
"report.target": "Report {target}",
"report.placeholder": "ਵਧੀਕ ਟਿੱਪਣੀਆਂ",
"report.reasons.dislike": "ਮੈਨੂੰ ਇਹ ਪਸੰਦ ਨਹੀਂ ਹੈ",
"report.reasons.spam": "ਇਹ ਸਪੈਮ ਹੈ",
"report.submit": "ਭੇਜੋ",
"report.target": "{target} ਰਿਪੋਰਟ",
"report.unfollow": "@{name} ਨੂੰ ਅਣ-ਫ਼ਾਲੋ ਕਰੋ",
"report_notification.attached_statuses": "{count, plural, one {# post} other {# posts}} attached",
"report_notification.categories.other": "ਬਾਕੀ",
"report_notification.categories.spam": "ਸਪਾਮ",
"report_notification.categories.spam": "ਸਪੈਮ",
"report_notification.categories.violation": "ਨਿਯਮ ਦੀ ਉਲੰਘਣਾ",
"search.placeholder": "ਖੋਜੋ",
"search_popout.quick_actions": "ਫੌਰੀ ਕਾਰਵਾਈਆਂ",
"search_popout.specific_date": "ਖਾਸ ਤਾਰੀਖ",
"search_popout.user": "ਵਰਤੋਂਕਾਰ",
"search_results.accounts": "ਪਰੋਫਾਈਲ",
"search_results.all": "ਸਭ",
"search_results.statuses": "Toots",
"search_results.hashtags": "ਹੈਸ਼ਟੈਗ",
"search_results.statuses": "ਪੋਸਟਾਂ",
"server_banner.learn_more": "ਹੋਰ ਜਾਣੋ",
"sign_in_banner.create_account": "ਖਾਤਾ ਬਣਾਓ",
"sign_in_banner.sign_in": "Sign in",
"status.admin_status": "Open this status in the moderation interface",
"status.copy": "Copy link to status",
"status.delete": "ਮਿਟਾਓ",
"sign_in_banner.sign_in": "ਲਾਗਇਨ",
"status.admin_status": "",
"status.block": "@{name} ਉੱਤੇ ਪਾਬੰਦੀ ਲਾਓ",
"status.bookmark": "ਬੁੱਕਮਾਰਕ",
"status.copy": "ਪੋਸਟ ਲਈ ਲਿੰਕ ਕਾਪੀ ਕਰੋ",
"status.delete": "ਹਟਾਓ",
"status.edit": "ਸੋਧ",
"status.edited": "{date} ਨੂੰ ਸੋਧਿਆ",
"status.edited_x_times": "Edited {count, plural, one {# time} other {# times}}",
"status.embed": "ਮੜ੍ਹੋ",
"status.favourite": "ਪਸੰਦ",
"status.history.created": "{name} ਨੇ {date} ਨੂੰ ਬਣਾਇਆ",
"status.history.edited": "{name} ਨੇ {date} ਨੂੰ ਸੋਧਿਆ",
"status.load_more": "ਹੋਰ ਦਿਖਾਓ",
"status.media.open": "ਖੋਲ੍ਹਣ ਲਈ ਕਲਿੱਕ ਕਰੋ",
"status.media.show": "ਵੇਖਾਉਣ ਲਈ ਕਲਿੱਕ ਕਰੋ",
"status.mention": "@{name} ਦਾ ਜ਼ਿਕਰ",
"status.more": "ਹੋਰ",
"status.open": "Expand this status",
"status.pinned": "Pinned toot",
"status.open": "ਇਹ ਪੋਸਟ ਨੂੰ ਫੈਲਾਓ",
"status.pin": "ਪਰੋਫਾਈਲ ਉੱਤੇ ਟੰਗੋ",
"status.pinned": "ਟੰਗੀ ਹੋਈ ਪੋਸਟ",
"status.read_more": "ਹੋਰ ਪੜ੍ਹੋ",
"status.reblog": "ਵਧਾਓ",
"status.reblogs.empty": "No one has boosted this toot yet. When someone does, they will show up here.",
"status.replied_to": "{name} ਨੂੰ ਜਵਾਬ ਦਿੱਤਾ",
"status.reply": "ਜਵਾਬ ਦੇਵੋ",
"status.replyAll": "ਮਾਮਲੇ ਨੂੰ ਜਵਾਬ ਦਿਓ",
"status.report": "@{name} ਦੀ ਰਿਪੋਰਟ ਕਰੋ",
"status.sensitive_warning": "ਸੰਵੇਦਨਸ਼ੀਲ ਸਮੱਗਰੀ",
"status.share": "ਸਾਂਝਾ ਕਰੋ",
"status.show_filter_reason": "ਕਿਵੇਂ ਵੀ ਵੇਖਾਓ",
"status.show_less": "ਘੱਟ ਦਿਖਾਓ",
"status.title.with_attachments": "{user} posted {attachmentCount, plural, one {an attachment} other {# attachments}}",
"subscribed_languages.save": "ਤਬਦੀਲੀਆਂ ਸਾਂਭੋ",
"tabs_bar.home": "ਮੁੱਖ ਪੰਨਾ",
"status.show_more": "ਹੋਰ ਦਿਖਾਓ",
"status.title.with_attachments": "{user} ਨੇ {attachmentCount, plural,one {ਅਟੈਚਮੈਂਟ} other {{attachmentCount}ਅਟੈਚਮੈਂਟਾਂ}} ਪੋਸਟ ਕੀਤੀਆਂ",
"status.translate": "ਉਲੱਥਾ ਕਰੋ",
"subscribed_languages.save": "ਤਬਦੀਲੀਆਂ ਸੰਭਾਲੋ",
"tabs_bar.home": "ਘਰ",
"tabs_bar.notifications": "ਸੂਚਨਾਵਾਂ",
"timeline_hint.resources.followers": "ਪ੍ਰਸ਼ੰਸਕ",
"timeline_hint.resources.follows": "ਪ੍ਰਸ਼ੰਸਕ ਬਣਨ 'ਤੇ",
"timeline_hint.resources.statuses": "Older toots",
"timeline_hint.resources.followers": "ਫ਼ਾਲੋਅਰ",
"timeline_hint.resources.follows": "ਫ਼ਾਲੋ",
"timeline_hint.resources.statuses": "ਪੂਰਾਣੀਆਂ ਪੋਸਟਾਂ",
"trends.counter_by_accounts": "{count, plural, one {{counter} person} other {{counter} people}} in the past {days, plural, one {day} other {# days}}",
"upload_form.audio_description": "Describe for people with hearing loss",
"upload_form.description": "Describe for the visually impaired",
"units.short.billion": "{count}ਿਬ",
"units.short.million": "{count}ਮਿ",
"units.short.thousand": "{count}ਹਜ਼ਾਰ",
"upload_form.audio_description": "ਬੋਲ਼ੇ ਜਾਂ ਸੁਣਨ ਵਿੱਚ ਮੁਸ਼ਕਿਲ ਵਾਲੇ ਲੋਕਾਂ ਲਈ ਵੇਰਵੇ",
"upload_form.description": "ਅੰਨ੍ਹੇ ਜਾਂ ਦੇਖਣ ਲਈ ਮੁਸ਼ਕਲ ਵਾਲੇ ਲੋਕਾਂ ਲਈ ਵੇਰਵੇ",
"upload_form.edit": "ਸੋਧ",
"upload_form.undo": "ਮਿਟਾਓ",
"upload_form.video_description": "Describe for people with hearing loss or visual impairment",
"upload_form.undo": "ਟਾਓ",
"upload_form.video_description": "ਬੋਲ਼ੇ, ਸੁਣਨ ਵਿੱਚ ਮੁਸ਼ਕਿਲ, ਅੰਨ੍ਹੇ ਜਾਂ ਘੱਟ ਨਿਗ੍ਹਾ ਵਾਲੇ ਲੋਕਾਂ ਲਈ ਵੇਰਵਾ",
"upload_modal.apply": "ਲਾਗੂ ਕਰੋ",
"upload_modal.applying": "ਲਾਗੂ ਕੀਤਾ ਜਾ ਰਿਹਾ ਹੈ…",
"upload_modal.choose_image": "ਤਸਵੀਰ ਚੁਣੋ",
"upload_modal.edit_media": "ਮੀਡੀਆ ਸੋਧੋ",
"upload_progress.label": "Uploading…",
"upload_progress.processing": "ਕਾਰਜ ਅਧੀਨ ਹੈ…",
"upload_progress.label": "ਅੱਪਲੋਡ ਕੀਤਾ ਜਾ ਰਿਹਾ ਹੈ...",
"upload_progress.processing": "ਕਾਰਵਾਈ ਚੱਲ ਰਹੀ ਹੈ…",
"video.exit_fullscreen": "ਪੂਰੀ ਸਕਰੀਨ ਵਿੱਚੋਂ ਬਾਹਰ ਨਿਕਲੋ",
"video.fullscreen": "ਪੂਰੀ ਸਕਰੀਨ",
"video.pause": "ਰਹਾਉ",
"video.pause": "ਠਹਿਰੋ",
"video.play": "ਚਲਾਓ"
}

View file

@ -488,6 +488,7 @@
"onboarding.profile.note": "O tebe",
"onboarding.profile.note_hint": "Môžeš @spomenúť iných ľudí, alebo #haštagy…",
"onboarding.profile.save_and_continue": "Ulož a pokračuj",
"onboarding.profile.title": "Nastavenie profilu",
"onboarding.profile.upload_avatar": "Nahraj profilový obrázok",
"onboarding.profile.upload_header": "Nahraj profilové záhlavie",
"onboarding.share.lead": "Daj ľudom vedieť, ako ťa môžu na Mastodone nájsť!",

View file

@ -496,7 +496,7 @@
"onboarding.share.message": "ฉันคือ {username} ใน #Mastodon! มาติดตามฉันที่ {url}",
"onboarding.share.next_steps": "ขั้นตอนถัดไปที่เป็นไปได้:",
"onboarding.share.title": "แชร์โปรไฟล์ของคุณ",
"onboarding.start.lead": "ตอนนี้คุณเป็นส่วนหนึ่งของ Mastodon แพลตฟอร์มสื่อสังคมที่มีเอกลักษณ์เฉพาะตัว กระจายศูนย์ ที่ซึ่งคุณ—ไม่ใช่อัลกอริทึม—เรียบเรียงประสบการณ์ของคุณเอง มาช่วยให้คุณเริ่มต้นใช้งานพรมแดนทางสังคมใหม่นี้กันเลย:",
"onboarding.start.lead": "ตอนนี้คุณเป็นส่วนหนึ่งของ Mastodon แพลตฟอร์มสื่อสังคมแบบกระจายศูนย์ที่มีเอกลักษณ์เฉพาะตัว ที่ซึ่งคุณ ไม่ใช่อัลกอริทึม เรียบเรียงประสบการณ์ของคุณเอง มาช่วยให้คุณเริ่มต้นใช้งานพรมแดนทางสังคมใหม่นี้กันเลย:",
"onboarding.start.skip": "ไม่ต้องการความช่วยเหลือในการเริ่มต้นใช้งาน?",
"onboarding.start.title": "คุณทำสำเร็จแล้ว!",
"onboarding.steps.follow_people.body": "การติดตามผู้คนที่น่าสนใจคือสิ่งที่ Mastodon ให้ความสำคัญ",

View file

@ -1,4 +1,6 @@
{
"about.blocks": "ئوتتۇراھال مۇلازىمېتىر",
"about.contact": "ئالاقىلاشقۇچى:",
"account.badges.bot": "Bot",
"account.cancel_follow_request": "Withdraw follow request",
"account.posts": "Toots",

View file

@ -34,9 +34,9 @@
"account.follow": "跟隨",
"account.followers": "跟隨者",
"account.followers.empty": "尚未有人跟隨這位使用者。",
"account.followers_counter": "被 {count, plural,one {{counter} 人}other {{counter} 人}}跟隨",
"account.followers_counter": "被 {count, plural, other {{counter} 人}}跟隨",
"account.following": "跟隨中",
"account.following_counter": "正在跟隨 {count, plural, one {{counter} 人} other {{counter} 人}}",
"account.following_counter": "正在跟隨 {count,plural,other {{counter} 人}}",
"account.follows.empty": "這位使用者尚未跟隨任何人。",
"account.follows_you": "跟隨了您",
"account.go_to_profile": "前往個人檔案",
@ -72,8 +72,8 @@
"account.unmute_notifications_short": "取消靜音推播通知",
"account.unmute_short": "解除靜音",
"account_note.placeholder": "按此新增備註",
"admin.dashboard.daily_retention": "註冊後使用者存留率(日)",
"admin.dashboard.monthly_retention": "註冊後使用者存留率(月)",
"admin.dashboard.daily_retention": "註冊後使用者存留率(日)",
"admin.dashboard.monthly_retention": "註冊後使用者存留率(月)",
"admin.dashboard.retention.average": "平均",
"admin.dashboard.retention.cohort": "註冊月份",
"admin.dashboard.retention.cohort_size": "新使用者",
@ -103,9 +103,9 @@
"bundle_modal_error.message": "載入此元件時發生錯誤。",
"bundle_modal_error.retry": "重試",
"closed_registrations.other_server_instructions": "因為 Mastodon 是去中心化的,所以您也能於其他伺服器上建立帳號,並仍然與這個伺服器互動。",
"closed_registrations_modal.description": "目前無法於 {domain} 建立新帳號,但也請別忘了,您並不一定需要有 {domain} 伺服器的帳號,也能使用 Mastodon 。",
"closed_registrations_modal.description": "目前無法於 {domain} 建立新帳號,但也請別忘了,您並不一定需要有 {domain} 伺服器的帳號,也能使用 Mastodon。",
"closed_registrations_modal.find_another_server": "尋找另一個伺服器",
"closed_registrations_modal.preamble": "Mastodon 是去中心化的,所以無論您於哪個伺服器新增帳號,都可以與此伺服器上的任何人跟隨及互動。您甚至能自行架一個自己的伺服器!",
"closed_registrations_modal.preamble": "Mastodon 是去中心化的,所以無論您於哪個伺服器新增帳號,都可以與此伺服器上的任何人跟隨及互動。您甚至能自行架一個自己的伺服器!",
"closed_registrations_modal.title": "註冊 Mastodon",
"column.about": "關於",
"column.blocks": "已封鎖的使用者",
@ -155,7 +155,7 @@
"compose_form.publish_form": "嘟出去",
"compose_form.publish_loud": "{publish}",
"compose_form.save_changes": "儲存變更",
"compose_form.sensitive.hide": "標記媒體為敏感內容",
"compose_form.sensitive.hide": "{count, plural, other {將媒體標記為敏感內容}}",
"compose_form.sensitive.marked": "此媒體被標記為敏感內容",
"compose_form.sensitive.unmarked": "此媒體未被標記為敏感內容",
"compose_form.spoiler.marked": "移除內容警告",
@ -452,7 +452,7 @@
"notifications.column_settings.push": "推播通知",
"notifications.column_settings.reblog": "轉嘟:",
"notifications.column_settings.show": "於欄位中顯示",
"notifications.column_settings.sound": "播放音",
"notifications.column_settings.sound": "播放",
"notifications.column_settings.status": "新嘟文:",
"notifications.column_settings.unread_notifications.category": "未讀通知",
"notifications.column_settings.unread_notifications.highlight": "突顯未讀通知",
@ -540,7 +540,7 @@
"regeneration_indicator.label": "載入中…",
"regeneration_indicator.sublabel": "您的首頁時間軸正在準備中!",
"relative_time.days": "{number} 天",
"relative_time.full.days": "{number, plural, one {# 天} other {# 天}}前",
"relative_time.full.days": "{number, plural, other {# 天}}前",
"relative_time.full.hours": "{number, plural, one {# 小時} other {# 小時}}前",
"relative_time.full.just_now": "剛剛",
"relative_time.full.minutes": "{number, plural, one {# 分鐘} other {# 分鐘}}前",
@ -620,7 +620,7 @@
"search_results.see_all": "檢視全部",
"search_results.statuses": "嘟文",
"search_results.title": "搜尋:{q}",
"server_banner.about_active_users": "最近三十日內使用此伺服器的人 (月活躍使用者)",
"server_banner.about_active_users": "最近三十日內使用此伺服器的人(月活躍使用者)",
"server_banner.active_users": "活躍使用者",
"server_banner.administered_by": "管理者:",
"server_banner.introduction": "{domain} 是由 {mastodon} 提供之去中心化社群網路一部分。",

View file

@ -2,13 +2,6 @@ import { Map as ImmutableMap } from 'immutable';
import { STORE_HYDRATE } from '../actions/store';
export let currentMedia = null;
export function setCurrentMedia(value) {
currentMedia = value;
}
const initialState = ImmutableMap({
accept_content_types: [],
});

View file

@ -1,3 +1,9 @@
import {
isAsyncThunkAction,
isPending as isThunkActionPending,
isFulfilled as isThunkActionFulfilled,
isRejected as isThunkActionRejected,
} from '@reduxjs/toolkit';
import { showLoading, hideLoading } from 'react-redux-loading-bar';
import type { AnyAction, Middleware } from 'redux';
@ -21,25 +27,43 @@ export const loadingBarMiddleware = (
return ({ dispatch }) =>
(next) =>
(action: AnyAction) => {
if (action.type && !action.skipLoading) {
let isPending = false;
let isFulfilled = false;
let isRejected = false;
if (
isAsyncThunkAction(action)
// TODO: once we get the first use-case for it, add a check for skipLoading
) {
if (isThunkActionPending(action)) isPending = true;
else if (isThunkActionFulfilled(action)) isFulfilled = true;
else if (isThunkActionRejected(action)) isRejected = true;
} else if (
action.type &&
!action.skipLoading &&
typeof action.type === 'string'
) {
const [PENDING, FULFILLED, REJECTED] = promiseTypeSuffixes;
const isPending = new RegExp(`${PENDING}$`, 'g');
const isFulfilled = new RegExp(`${FULFILLED}$`, 'g');
const isRejected = new RegExp(`${REJECTED}$`, 'g');
const isPendingRegexp = new RegExp(`${PENDING}$`, 'g');
const isFulfilledRegexp = new RegExp(`${FULFILLED}$`, 'g');
const isRejectedRegexp = new RegExp(`${REJECTED}$`, 'g');
if (typeof action.type === 'string') {
if (action.type.match(isPending)) {
dispatch(showLoading());
} else if (
action.type.match(isFulfilled) ??
action.type.match(isRejected)
) {
dispatch(hideLoading());
}
if (action.type.match(isPendingRegexp)) {
isPending = true;
} else if (action.type.match(isFulfilledRegexp)) {
isFulfilled = true;
} else if (action.type.match(isRejectedRegexp)) {
isRejected = true;
}
}
if (isPending) {
dispatch(showLoading());
} else if (isFulfilled || isRejected) {
dispatch(hideLoading());
}
return next(action);
};
};

View file

@ -4398,11 +4398,6 @@ a.status-card {
align-items: center;
justify-content: center;
@supports (display: grid) {
// hack to fix Chrome <57
contain: strict;
}
& > span {
max-width: 500px;
}

View file

@ -37,13 +37,13 @@ class InlineRenderer
private
def preload_associations_for_status
ActiveRecord::Associations::Preloader.new(records: @object, associations: {
ActiveRecord::Associations::Preloader.new(records: [@object], associations: {
active_mentions: :account,
reblog: {
active_mentions: :account,
},
})
}).call
end
def current_user

View file

@ -52,7 +52,7 @@ class OStatus::TagManager
ActivityPub::TagManager.instance.uri_to_local_id(tag)
else
matches = Regexp.new("objectId=([\\d]+):objectType=#{expected_type}").match(tag)
return matches[1] unless matches.nil?
matches[1] unless matches.nil?
end
end

View file

@ -1,31 +0,0 @@
# frozen_string_literal: true
class PotentialFriendshipTracker
EXPIRE_AFTER = 90.days.seconds
MAX_ITEMS = 80
WEIGHTS = {
reply: 1,
favourite: 10,
reblog: 20,
}.freeze
class << self
include Redisable
def record(account_id, target_account_id, action)
return if account_id == target_account_id
key = "interactions:#{account_id}"
weight = WEIGHTS[action]
redis.zincrby(key, weight, target_account_id)
redis.zremrangebyrank(key, 0, -MAX_ITEMS)
redis.expire(key, EXPIRE_AFTER)
end
def remove(account_id, target_account_id)
redis.zrem("interactions:#{account_id}", target_account_id)
end
end
end

View file

@ -12,7 +12,7 @@ class ApplicationMailer < ActionMailer::Base
protected
def locale_for_account(account, &block)
I18n.with_locale(account.user_locale || I18n.default_locale, &block)
I18n.with_locale(account.user_locale || I18n.locale || I18n.default_locale, &block)
end
def set_autoreply_headers!

View file

@ -202,6 +202,6 @@ class UserMailer < Devise::Mailer
end
def locale
@resource.locale.presence || I18n.default_locale
@resource.locale.presence || I18n.locale || I18n.default_locale
end
end

View file

@ -457,8 +457,8 @@ class Account < ApplicationRecord
end
def inverse_alias(key, original_key)
define_method("#{key}=") do |value|
public_send("#{original_key}=", !ActiveModel::Type::Boolean.new.cast(value))
define_method(:"#{key}=") do |value|
public_send(:"#{original_key}=", !ActiveModel::Type::Boolean.new.cast(value))
end
define_method(key) do

View file

@ -18,16 +18,17 @@ class AccountDomainBlock < ApplicationRecord
belongs_to :account
validates :domain, presence: true, uniqueness: { scope: :account_id }, domain: true
after_commit :remove_blocking_cache
after_commit :remove_relationship_cache
after_commit :invalidate_domain_blocking_cache
after_commit :invalidate_follow_recommendations_cache
private
def remove_blocking_cache
def invalidate_domain_blocking_cache
Rails.cache.delete("exclude_domains_for:#{account_id}")
Rails.cache.delete(['exclude_domains', account_id, domain])
end
def remove_relationship_cache
Rails.cache.delete_matched("relationship:#{account_id}:*")
def invalidate_follow_recommendations_cache
Rails.cache.delete("follow_recommendations/#{account_id}")
end
end

View file

@ -1,28 +1,48 @@
# frozen_string_literal: true
class AccountSuggestions
include DatabaseHelper
SOURCES = [
AccountSuggestions::SettingSource,
AccountSuggestions::PastInteractionsSource,
AccountSuggestions::FriendsOfFriendsSource,
AccountSuggestions::SimilarProfilesSource,
AccountSuggestions::GlobalSource,
].freeze
def self.get(account, limit)
SOURCES.each_with_object([]) do |source_class, suggestions|
source_suggestions = source_class.new.get(
account,
skip_account_ids: suggestions.map(&:account_id),
limit: limit - suggestions.size
)
BATCH_SIZE = 40
suggestions.concat(source_suggestions)
def initialize(account)
@account = account
end
def get(limit, offset = 0)
with_read_replica do
account_ids_with_sources = Rails.cache.fetch("follow_recommendations/#{@account.id}", expires_in: 15.minutes) do
SOURCES.flat_map { |klass| klass.new.get(@account, limit: BATCH_SIZE) }.each_with_object({}) do |(account_id, source), h|
(h[account_id] ||= []).concat(Array(source).map(&:to_sym))
end.to_a.shuffle
end
# The sources deliver accounts that haven't yet been followed, are not blocked,
# and so on. Since we reset the cache on follows, blocks, and so on, we don't need
# a complicated query on this end.
account_ids = account_ids_with_sources[offset, limit]
accounts_map = Account.where(id: account_ids.map(&:first)).includes(:account_stat).index_by(&:id)
account_ids.filter_map do |(account_id, source)|
next unless accounts_map.key?(account_id)
AccountSuggestions::Suggestion.new(
account: accounts_map[account_id],
source: source
)
end
end
end
def self.remove(account, target_account_id)
SOURCES.each do |source_class|
source = source_class.new
source.remove(account, target_account_id)
end
def remove(target_account_id)
FollowRecommendationMute.create(account_id: @account.id, target_account_id: target_account_id)
end
end

View file

@ -0,0 +1,37 @@
# frozen_string_literal: true
class AccountSuggestions::FriendsOfFriendsSource < AccountSuggestions::Source
def get(account, limit: 10)
Account.find_by_sql([<<~SQL.squish, { id: account.id, limit: limit }]).map { |row| [row.id, key] }
WITH first_degree AS (
SELECT target_account_id
FROM follows
JOIN accounts AS target_accounts ON follows.target_account_id = target_accounts.id
WHERE account_id = :id
AND NOT target_accounts.hide_collections
)
SELECT accounts.id, COUNT(*) AS frequency
FROM accounts
JOIN follows ON follows.target_account_id = accounts.id
JOIN account_stats ON account_stats.account_id = accounts.id
LEFT OUTER JOIN follow_recommendation_mutes ON follow_recommendation_mutes.target_account_id = accounts.id AND follow_recommendation_mutes.account_id = :id
WHERE follows.account_id IN (SELECT * FROM first_degree)
AND follows.target_account_id NOT IN (SELECT * FROM first_degree)
AND follows.target_account_id <> :id
AND accounts.discoverable
AND accounts.suspended_at IS NULL
AND accounts.silenced_at IS NULL
AND accounts.moved_to_account_id IS NULL
AND follow_recommendation_mutes.target_account_id IS NULL
GROUP BY accounts.id, account_stats.id
ORDER BY frequency DESC, account_stats.followers_count ASC
LIMIT :limit
SQL
end
private
def key
:friends_of_friends
end
end

View file

@ -1,39 +1,13 @@
# frozen_string_literal: true
class AccountSuggestions::GlobalSource < AccountSuggestions::Source
include Redisable
def key
:global
end
def get(account, skip_account_ids: [], limit: 40)
account_ids = account_ids_for_locale(I18n.locale.to_s.split(/[_-]/).first) - [account.id] - skip_account_ids
as_ordered_suggestions(
scope(account).where(id: account_ids),
account_ids
).take(limit)
end
def remove(_account, _target_account_id)
nil
def get(account, limit: 10)
FollowRecommendation.localized(content_locale).joins(:account).merge(base_account_scope(account)).order(rank: :desc).limit(limit).pluck(:account_id, :reason)
end
private
def scope(account)
Account.searchable
.followable_by(account)
.not_excluded_by_account(account)
.not_domain_blocked_by_account(account)
end
def account_ids_for_locale(locale)
redis.zrevrange("follow_recommendations:#{locale}", 0, -1).map(&:to_i)
end
def to_ordered_list_key(account)
account.id
def content_locale
I18n.locale.to_s.split(/[_-]/).first
end
end

View file

@ -1,36 +0,0 @@
# frozen_string_literal: true
class AccountSuggestions::PastInteractionsSource < AccountSuggestions::Source
include Redisable
def key
:past_interactions
end
def get(account, skip_account_ids: [], limit: 40)
account_ids = account_ids_for_account(account.id, limit + skip_account_ids.size) - skip_account_ids
as_ordered_suggestions(
scope.where(id: account_ids),
account_ids
).take(limit)
end
def remove(account, target_account_id)
redis.zrem("interactions:#{account.id}", target_account_id)
end
private
def scope
Account.searchable
end
def account_ids_for_account(account_id, limit)
redis.zrevrange("interactions:#{account_id}", 0, limit).map(&:to_i)
end
def to_ordered_list_key(account)
account.id
end
end

View file

@ -1,32 +1,18 @@
# frozen_string_literal: true
class AccountSuggestions::SettingSource < AccountSuggestions::Source
def key
:staff
end
def get(account, skip_account_ids: [], limit: 40)
return [] unless setting_enabled?
as_ordered_suggestions(
scope(account).where(setting_to_where_condition).where.not(id: skip_account_ids),
usernames_and_domains
).take(limit)
end
def remove(_account, _target_account_id)
nil
def get(account, limit: 10)
if setting_enabled?
base_account_scope(account).where(setting_to_where_condition).limit(limit).pluck(:id).zip([key].cycle)
else
[]
end
end
private
def scope(account)
Account.searchable
.followable_by(account)
.not_excluded_by_account(account)
.not_domain_blocked_by_account(account)
.where(locked: false)
.where.not(id: account.id)
def key
:featured
end
def usernames_and_domains
@ -61,8 +47,4 @@ class AccountSuggestions::SettingSource < AccountSuggestions::Source
def setting
Setting.bootstrap_timeline_accounts
end
def to_ordered_list_key(account)
[account.username.downcase, account.domain&.downcase]
end
end

View file

@ -0,0 +1,67 @@
# frozen_string_literal: true
class AccountSuggestions::SimilarProfilesSource < AccountSuggestions::Source
class QueryBuilder < AccountSearchService::QueryBuilder
def must_clauses
[
{
more_like_this: {
fields: %w(text text.stemmed),
like: @query.map { |id| { _index: 'accounts', _id: id } },
},
},
{
term: {
properties: 'discoverable',
},
},
]
end
def must_not_clauses
[
{
terms: {
id: following_ids,
},
},
{
term: {
properties: 'bot',
},
},
]
end
def should_clauses
{
term: {
properties: {
value: 'verified',
boost: 2,
},
},
}
end
end
def get(account, limit: 10)
recently_followed_account_ids = account.active_relationships.recent.limit(5).pluck(:target_account_id)
if Chewy.enabled? && !recently_followed_account_ids.empty?
QueryBuilder.new(recently_followed_account_ids, account).build.limit(limit).hits.pluck('_id').map(&:to_i).zip([key].cycle)
else
[]
end
rescue Faraday::ConnectionFailed
[]
end
private
def key
:similar_to_recently_followed
end
end

View file

@ -1,34 +1,18 @@
# frozen_string_literal: true
class AccountSuggestions::Source
def key
raise NotImplementedError
end
def get(_account, **kwargs)
raise NotImplementedError
end
def remove(_account, target_account_id)
raise NotImplementedError
end
protected
def as_ordered_suggestions(scope, ordered_list)
return [] if ordered_list.empty?
map = scope.index_by { |account| to_ordered_list_key(account) }
ordered_list.filter_map { |ordered_list_key| map[ordered_list_key] }.map do |account|
AccountSuggestions::Suggestion.new(
account: account,
source: key
)
end
end
def to_ordered_list_key(_account)
raise NotImplementedError
def base_account_scope(account)
Account.searchable
.followable_by(account)
.not_excluded_by_account(account)
.not_domain_blocked_by_account(account)
.where.not(id: account.id)
.joins("LEFT OUTER JOIN follow_recommendation_mutes ON follow_recommendation_mutes.target_account_id = accounts.id AND follow_recommendation_mutes.account_id = #{account.id}").where(follow_recommendation_mutes: { target_account_id: nil })
end
end

View file

@ -78,9 +78,9 @@ class Announcement < ApplicationRecord
else
scope.select("name, custom_emoji_id, count(*) as count, exists(select 1 from announcement_reactions r where r.account_id = #{account.id} and r.announcement_id = announcement_reactions.announcement_id and r.name = announcement_reactions.name) as me")
end
end
end.to_a
ActiveRecord::Associations::Preloader.new(records: records, associations: :custom_emoji)
ActiveRecord::Associations::Preloader.new(records: records, associations: :custom_emoji).call
records
end

View file

@ -26,15 +26,20 @@ class Block < ApplicationRecord
end
before_validation :set_uri, only: :create
after_commit :remove_blocking_cache
after_commit :invalidate_blocking_cache
after_commit :invalidate_follow_recommendations_cache
private
def remove_blocking_cache
def invalidate_blocking_cache
Rails.cache.delete("exclude_account_ids_for:#{account_id}")
Rails.cache.delete("exclude_account_ids_for:#{target_account_id}")
end
def invalidate_follow_recommendations_cache
Rails.cache.delete("follow_recommendations/#{account_id}")
end
def set_uri
self.uri = ActivityPub::TagManager.instance.generate_uri_for(self) if uri.nil?
end

View file

@ -64,6 +64,7 @@ module Account::Associations
has_one :deletion_request, class_name: 'AccountDeletionRequest', inverse_of: :account, dependent: :destroy
# Follow recommendations
has_one :follow_recommendation, inverse_of: :account, dependent: nil
has_one :follow_recommendation_suppression, inverse_of: :account, dependent: :destroy
# Account statuses cleanup policy

View file

@ -60,12 +60,6 @@ module Account::Interactions
end
end
def domain_blocking_map(target_account_ids, account_id)
accounts_map = Account.where(id: target_account_ids).select('id, domain').each_with_object({}) { |a, h| h[a.id] = a.domain }
blocked_domains = domain_blocking_map_by_domain(accounts_map.values.compact, account_id)
accounts_map.reduce({}) { |h, (id, domain)| h.merge(id => blocked_domains[domain]) }
end
def domain_blocking_map_by_domain(target_domains, account_id)
follow_mapping(AccountDomainBlock.where(account_id: account_id, domain: target_domains), :domain)
end
@ -122,8 +116,6 @@ module Account::Interactions
rel.save! if rel.changed?
remove_potential_friendship(other_account)
rel
end
@ -137,13 +129,10 @@ module Account::Interactions
rel.save! if rel.changed?
remove_potential_friendship(other_account)
rel
end
def block!(other_account, uri: nil)
remove_potential_friendship(other_account)
block_relationships.create_with(uri: uri)
.find_or_create_by!(target_account: other_account)
end
@ -154,8 +143,6 @@ module Account::Interactions
mute.expires_in = duration.zero? ? nil : duration
mute.save!
remove_potential_friendship(other_account)
# When toggling a mute between hiding and allowing notifications, the mute will already exist, so the find_or_create_by! call will return the existing Mute without updating the hide_notifications attribute. Therefore, we check that hide_notifications? is what we want and set it if it isn't.
mute.update!(hide_notifications: notifications) if mute.hide_notifications? != notifications
@ -313,10 +300,4 @@ module Account::Interactions
domain_blocking_by_domain: Account.domain_blocking_map_by_domain(domains, id),
})
end
private
def remove_potential_friendship(other_account)
PotentialFriendshipTracker.remove(id, other_account.id)
end
end

View file

@ -116,6 +116,7 @@ module Account::Search
[].tap do |properties|
properties << 'bot' if bot?
properties << 'verified' if fields.any?(&:verified?)
properties << 'discoverable' if discoverable?
end
end
@ -124,7 +125,7 @@ module Account::Search
tsquery = generate_query_for_search(terms)
find_by_sql([BASIC_SEARCH_SQL, { limit: limit, offset: offset, tsquery: tsquery }]).tap do |records|
ActiveRecord::Associations::Preloader.new(records: records, associations: :account_stat)
ActiveRecord::Associations::Preloader.new(records: records, associations: [:account_stat, { user: :role }]).call
end
end
@ -133,7 +134,7 @@ module Account::Search
sql_template = following ? ADVANCED_SEARCH_WITH_FOLLOWING : ADVANCED_SEARCH_WITHOUT_FOLLOWING
find_by_sql([sql_template, { id: account.id, limit: limit, offset: offset, tsquery: tsquery }]).tap do |records|
ActiveRecord::Associations::Preloader.new(records: records, associations: :account_stat)
ActiveRecord::Associations::Preloader.new(records: records, associations: [:account_stat, { user: :role }]).call
end
end

View file

@ -10,7 +10,7 @@ module RelationshipCacheable
private
def remove_relationship_cache
Rails.cache.delete("relationship:#{account_id}:#{target_account_id}")
Rails.cache.delete("relationship:#{target_account_id}:#{account_id}")
Rails.cache.delete(['relationship', account_id, target_account_id])
Rails.cache.delete(['relationship', target_account_id, account_id])
end
end

View file

@ -7,7 +7,7 @@ module Remotable
def remotable_attachment(attachment_name, limit, suppress_errors: true, download_on_assign: true, attribute_name: nil)
attribute_name ||= :"#{attachment_name}_remote_url"
define_method("download_#{attachment_name}!") do |url = nil|
define_method(:"download_#{attachment_name}!") do |url = nil|
url ||= self[attribute_name]
return if url.blank?
@ -24,29 +24,29 @@ module Remotable
Request.new(:get, url).perform do |response|
raise Mastodon::UnexpectedResponseError, response unless (200...300).cover?(response.code)
public_send("#{attachment_name}=", ResponseWithLimit.new(response, limit))
public_send(:"#{attachment_name}=", ResponseWithLimit.new(response, limit))
end
rescue Mastodon::UnexpectedResponseError, HTTP::TimeoutError, HTTP::ConnectionError, OpenSSL::SSL::SSLError => e
Rails.logger.debug { "Error fetching remote #{attachment_name}: #{e}" }
public_send("#{attachment_name}=", nil) if public_send("#{attachment_name}_file_name").present?
public_send(:"#{attachment_name}=", nil) if public_send(:"#{attachment_name}_file_name").present?
raise e unless suppress_errors
rescue Paperclip::Errors::NotIdentifiedByImageMagickError, Addressable::URI::InvalidURIError, Mastodon::HostValidationError, Mastodon::LengthValidationError, Paperclip::Error, Mastodon::DimensionsValidationError, Mastodon::StreamValidationError => e
Rails.logger.debug { "Error fetching remote #{attachment_name}: #{e}" }
public_send("#{attachment_name}=", nil) if public_send("#{attachment_name}_file_name").present?
public_send(:"#{attachment_name}=", nil) if public_send(:"#{attachment_name}_file_name").present?
end
nil
end
define_method("#{attribute_name}=") do |url|
return if self[attribute_name] == url && public_send("#{attachment_name}_file_name").present?
define_method(:"#{attribute_name}=") do |url|
return if self[attribute_name] == url && public_send(:"#{attachment_name}_file_name").present?
self[attribute_name] = url if has_attribute?(attribute_name)
public_send("download_#{attachment_name}!", url) if download_on_assign
public_send(:"download_#{attachment_name}!", url) if download_on_assign
end
alias_method("reset_#{attachment_name}!", "download_#{attachment_name}!")
alias_method(:"reset_#{attachment_name}!", "download_#{attachment_name}!")
end
end
end

View file

@ -91,7 +91,7 @@ class CustomFilter < ApplicationRecord
filters_hash.values.map { |cache| [cache.delete(:filter), cache] }
end.to_a
active_filters.select { |custom_filter, _| !custom_filter.expired? }
active_filters.reject { |custom_filter, _| custom_filter.expired? }
end
def self.apply_cached_filters(cached_filters, status)

View file

@ -44,10 +44,10 @@ class Follow < ApplicationRecord
before_validation :set_uri, only: :create
after_create :increment_cache_counters
after_create :invalidate_hash_cache
after_destroy :remove_endorsements
after_destroy :decrement_cache_counters
after_destroy :invalidate_hash_cache
after_commit :invalidate_follow_recommendations_cache
after_commit :invalidate_hash_cache
private
@ -74,4 +74,8 @@ class Follow < ApplicationRecord
Rails.cache.delete("followers_hash:#{target_account_id}:#{account.synchronization_uri_prefix}")
end
def invalidate_follow_recommendations_cache
Rails.cache.delete("follow_recommendations/#{account_id}")
end
end

View file

@ -17,12 +17,9 @@ class FollowRecommendationFilter
def results
if params['status'] == 'suppressed'
Account.joins(:follow_recommendation_suppression).order(FollowRecommendationSuppression.arel_table[:id].desc).to_a
Account.includes(:account_stat).joins(:follow_recommendation_suppression).order(FollowRecommendationSuppression.arel_table[:id].desc)
else
account_ids = redis.zrevrange("follow_recommendations:#{@language}", 0, -1).map(&:to_i)
accounts = Account.where(id: account_ids).index_by(&:id)
account_ids.filter_map { |id| accounts[id] }
Account.includes(:account_stat).joins(:follow_recommendation).merge(FollowRecommendation.localized(@language).order(rank: :desc))
end
end
end

View file

@ -0,0 +1,26 @@
# frozen_string_literal: true
# == Schema Information
#
# Table name: follow_recommendation_mutes
#
# id :bigint(8) not null, primary key
# account_id :bigint(8) not null
# target_account_id :bigint(8) not null
# created_at :datetime not null
# updated_at :datetime not null
#
class FollowRecommendationMute < ApplicationRecord
belongs_to :account
belongs_to :target_account, class_name: 'Account'
validates :target_account, uniqueness: { scope: :account_id }
after_commit :invalidate_follow_recommendations_cache
private
def invalidate_follow_recommendations_cache
Rails.cache.delete("follow_recommendations/#{account_id}")
end
end

View file

@ -11,19 +11,5 @@
#
class FollowRecommendationSuppression < ApplicationRecord
include Redisable
belongs_to :account
after_commit :remove_follow_recommendations, on: :create
private
def remove_follow_recommendations
redis.pipelined do |pipeline|
I18n.available_locales.each do |locale|
pipeline.zrem("follow_recommendations:#{locale}", account_id)
end
end
end
end

View file

@ -45,10 +45,15 @@ class FollowRequest < ApplicationRecord
end
before_validation :set_uri, only: :create
after_commit :invalidate_follow_recommendations_cache
private
def set_uri
self.uri = ActivityPub::TagManager.instance.generate_uri_for(self) if uri.nil?
end
def invalidate_follow_recommendations_cache
Rails.cache.delete("follow_recommendations/#{account_id}")
end
end

View file

@ -84,7 +84,7 @@ class Form::AdminSettings
KEYS.each do |key|
define_method(key) do
return instance_variable_get("@#{key}") if instance_variable_defined?("@#{key}")
return instance_variable_get(:"@#{key}") if instance_variable_defined?(:"@#{key}")
stored_value = if UPLOAD_KEYS.include?(key)
SiteUpload.where(var: key).first_or_initialize(var: key)
@ -94,12 +94,12 @@ class Form::AdminSettings
Setting.public_send(key)
end
instance_variable_set("@#{key}", stored_value)
instance_variable_set(:"@#{key}", stored_value)
end
end
UPLOAD_KEYS.each do |key|
define_method("#{key}=") do |file|
define_method(:"#{key}=") do |file|
value = public_send(key)
value.file = file
rescue Mastodon::DimensionsValidationError => e
@ -114,13 +114,13 @@ class Form::AdminSettings
return false unless errors.empty? && valid?
KEYS.each do |key|
next unless instance_variable_defined?("@#{key}")
next unless instance_variable_defined?(:"@#{key}")
if UPLOAD_KEYS.include?(key)
public_send(key).save
else
setting = Setting.where(var: key).first_or_initialize(var: key)
setting.update(value: typecast_value(key, instance_variable_get("@#{key}")))
setting.update(value: typecast_value(key, instance_variable_get(:"@#{key}")))
end
end
end
@ -139,9 +139,9 @@ class Form::AdminSettings
def validate_site_uploads
UPLOAD_KEYS.each do |key|
next unless instance_variable_defined?("@#{key}")
next unless instance_variable_defined?(:"@#{key}")
upload = instance_variable_get("@#{key}")
upload = instance_variable_get(:"@#{key}")
next if upload.valid?
upload.errors.each do |error|

View file

@ -43,14 +43,19 @@ class Form::Import
validate :validate_data
def guessed_type
return :muting if csv_headers_match?('Hide notifications')
return :following if csv_headers_match?('Show boosts') || csv_headers_match?('Notify on new posts') || csv_headers_match?('Languages')
return :following if file_name_matches?('follows') || file_name_matches?('following_accounts')
return :blocking if file_name_matches?('blocks') || file_name_matches?('blocked_accounts')
return :muting if file_name_matches?('mutes') || file_name_matches?('muted_accounts')
return :domain_blocking if file_name_matches?('domain_blocks') || file_name_matches?('blocked_domains')
return :bookmarks if file_name_matches?('bookmarks')
return :lists if file_name_matches?('lists')
if csv_headers_match?('Hide notifications') || file_name_matches?('mutes') || file_name_matches?('muted_accounts')
:muting
elsif csv_headers_match?('Show boosts') || csv_headers_match?('Notify on new posts') || csv_headers_match?('Languages') || file_name_matches?('follows') || file_name_matches?('following_accounts')
:following
elsif file_name_matches?('blocks') || file_name_matches?('blocked_accounts')
:blocking
elsif file_name_matches?('domain_blocks') || file_name_matches?('blocked_domains')
:domain_blocking
elsif file_name_matches?('bookmarks')
:bookmarks
elsif file_name_matches?('lists')
:lists
end
end
# Whether the uploaded CSV file seems to correspond to a different import type than the one selected

View file

@ -23,11 +23,16 @@ class Mute < ApplicationRecord
validates :account_id, uniqueness: { scope: :target_account_id }
after_commit :remove_blocking_cache
after_commit :invalidate_blocking_cache
after_commit :invalidate_follow_recommendations_cache
private
def remove_blocking_cache
def invalidate_blocking_cache
Rails.cache.delete("exclude_account_ids_for:#{account_id}")
end
def invalidate_follow_recommendations_cache
Rails.cache.delete("follow_recommendations/#{account_id}")
end
end

View file

@ -111,7 +111,7 @@ class Notification < ApplicationRecord
# Instead of using the usual `includes`, manually preload each type.
# If polymorphic associations are loaded with the usual `includes`, other types of associations will be loaded more.
ActiveRecord::Associations::Preloader.new(records: grouped_notifications, associations: associations)
ActiveRecord::Associations::Preloader.new(records: grouped_notifications, associations: associations).call
end
unique_target_statuses = notifications.filter_map(&:target_status).uniq

View file

@ -4,8 +4,8 @@
#
# Table name: preview_cards_statuses
#
# preview_card_id :bigint(8) not null
# status_id :bigint(8) not null
# preview_card_id :bigint(8) not null, primary key
# status_id :bigint(8) not null, primary key
# url :string
#
class PreviewCardsStatus < ApplicationRecord

View file

@ -5,8 +5,9 @@ class AccountRelationshipsPresenter
:muting, :requested, :requested_by, :domain_blocking,
:endorsed, :account_note
def initialize(account_ids, current_account_id, **options)
@account_ids = account_ids.map { |a| a.is_a?(Account) ? a.id : a.to_i }
def initialize(accounts, current_account_id, **options)
@accounts = accounts.to_a
@account_ids = @accounts.pluck(:id)
@current_account_id = current_account_id
@following = cached[:following].merge(Account.following_map(@uncached_account_ids, @current_account_id))
@ -16,10 +17,11 @@ class AccountRelationshipsPresenter
@muting = cached[:muting].merge(Account.muting_map(@uncached_account_ids, @current_account_id))
@requested = cached[:requested].merge(Account.requested_map(@uncached_account_ids, @current_account_id))
@requested_by = cached[:requested_by].merge(Account.requested_by_map(@uncached_account_ids, @current_account_id))
@domain_blocking = cached[:domain_blocking].merge(Account.domain_blocking_map(@uncached_account_ids, @current_account_id))
@endorsed = cached[:endorsed].merge(Account.endorsed_map(@uncached_account_ids, @current_account_id))
@account_note = cached[:account_note].merge(Account.account_note_map(@uncached_account_ids, @current_account_id))
@domain_blocking = domain_blocking_map
cache_uncached!
@following.merge!(options[:following_map] || {})
@ -36,6 +38,31 @@ class AccountRelationshipsPresenter
private
def domain_blocking_map
target_domains = @accounts.pluck(:domain).compact.uniq
blocks_by_domain = {}
# Fetch from cache
cache_keys = target_domains.map { |domain| domain_cache_key(domain) }
Rails.cache.read_multi(*cache_keys).each do |key, blocking|
blocks_by_domain[key.last] = blocking
end
uncached_domains = target_domains - blocks_by_domain.keys
# Read uncached values from database
AccountDomainBlock.where(account_id: @current_account_id, domain: uncached_domains).pluck(:domain).each do |domain|
blocks_by_domain[domain] = true
end
# Write database reads to cache
to_cache = uncached_domains.to_h { |domain| [domain_cache_key(domain), blocks_by_domain[domain]] }
Rails.cache.write_multi(to_cache, expires_in: 1.day)
# Return formatted value
@accounts.each_with_object({}) { |account, h| h[account.id] = blocks_by_domain[account.domain] }
end
def cached
return @cached if defined?(@cached)
@ -47,28 +74,23 @@ class AccountRelationshipsPresenter
muting: {},
requested: {},
requested_by: {},
domain_blocking: {},
endorsed: {},
account_note: {},
}
@uncached_account_ids = []
@uncached_account_ids = @account_ids.uniq
@account_ids.each do |account_id|
maps_for_account = Rails.cache.read("relationship:#{@current_account_id}:#{account_id}")
if maps_for_account.is_a?(Hash)
@cached.deep_merge!(maps_for_account)
else
@uncached_account_ids << account_id
end
cache_ids = @account_ids.map { |account_id| relationship_cache_key(account_id) }
Rails.cache.read_multi(*cache_ids).each do |key, maps_for_account|
@cached.deep_merge!(maps_for_account)
@uncached_account_ids.delete(key.last)
end
@cached
end
def cache_uncached!
@uncached_account_ids.each do |account_id|
to_cache = @uncached_account_ids.to_h do |account_id|
maps_for_account = {
following: { account_id => following[account_id] },
followed_by: { account_id => followed_by[account_id] },
@ -77,12 +99,21 @@ class AccountRelationshipsPresenter
muting: { account_id => muting[account_id] },
requested: { account_id => requested[account_id] },
requested_by: { account_id => requested_by[account_id] },
domain_blocking: { account_id => domain_blocking[account_id] },
endorsed: { account_id => endorsed[account_id] },
account_note: { account_id => account_note[account_id] },
}
Rails.cache.write("relationship:#{@current_account_id}:#{account_id}", maps_for_account, expires_in: 1.day)
[relationship_cache_key(account_id), maps_for_account]
end
Rails.cache.write_multi(to_cache, expires_in: 1.day)
end
def domain_cache_key(domain)
['exclude_domains', @current_account_id, domain]
end
def relationship_cache_key(account_id)
['relationship', @current_account_id, account_id]
end
end

View file

@ -13,29 +13,7 @@ class InitialStateSerializer < ActiveModel::Serializer
has_one :role, serializer: REST::RoleSerializer
def meta
store = {
streaming_api_base_url: Rails.configuration.x.streaming_api_base_url,
access_token: object.token,
locale: I18n.locale,
domain: Addressable::IDNA.to_unicode(instance_presenter.domain),
title: instance_presenter.title,
admin: object.admin&.id&.to_s,
search_enabled: Chewy.enabled?,
repository: Mastodon::Version.repository,
source_url: instance_presenter.source_url,
version: instance_presenter.version,
limited_federation_mode: Rails.configuration.x.limited_federation_mode,
mascot: instance_presenter.mascot&.file&.url,
profile_directory: Setting.profile_directory,
trends_enabled: Setting.trends,
registrations_open: Setting.registrations_mode != 'none' && !Rails.configuration.x.single_user_mode,
timeline_preview: Setting.timeline_preview,
activity_api_enabled: Setting.activity_api_enabled,
single_user_mode: Rails.configuration.x.single_user_mode,
trends_as_landing_page: Setting.trends_as_landing_page,
status_page_url: Setting.status_page_url,
sso_redirect: sso_redirect,
}
store = default_meta_store
if object.current_account
store[:me] = object.current_account.id.to_s
@ -86,8 +64,8 @@ class InitialStateSerializer < ActiveModel::Serializer
ActiveRecord::Associations::Preloader.new(
records: [object.current_account, object.admin, object.owner, object.disabled_account, object.moved_to_account].compact,
associations: [:account_stat, :user, { moved_to_account: [:account_stat, :user] }]
)
associations: [:account_stat, { user: :role, moved_to_account: [:account_stat, { user: :role }] }]
).call
store[object.current_account.id.to_s] = serialized_account(object.current_account) if object.current_account
store[object.admin.id.to_s] = serialized_account(object.admin) if object.admin
@ -108,6 +86,32 @@ class InitialStateSerializer < ActiveModel::Serializer
private
def default_meta_store
{
access_token: object.token,
activity_api_enabled: Setting.activity_api_enabled,
admin: object.admin&.id&.to_s,
domain: Addressable::IDNA.to_unicode(instance_presenter.domain),
limited_federation_mode: Rails.configuration.x.limited_federation_mode,
locale: I18n.locale,
mascot: instance_presenter.mascot&.file&.url,
profile_directory: Setting.profile_directory,
registrations_open: Setting.registrations_mode != 'none' && !Rails.configuration.x.single_user_mode,
repository: Mastodon::Version.repository,
search_enabled: Chewy.enabled?,
single_user_mode: Rails.configuration.x.single_user_mode,
source_url: instance_presenter.source_url,
sso_redirect: sso_redirect,
status_page_url: Setting.status_page_url,
streaming_api_base_url: Rails.configuration.x.streaming_api_base_url,
timeline_preview: Setting.timeline_preview,
title: instance_presenter.title,
trends_as_landing_page: Setting.trends_as_landing_page,
trends_enabled: Setting.trends,
version: instance_presenter.version,
}
end
def object_account_user
object.current_account.user
end

View file

@ -23,6 +23,7 @@ class AccountSearchService < BaseService
query: {
bool: {
must: must_clauses,
must_not: must_not_clauses,
},
},
@ -49,6 +50,10 @@ class AccountSearchService < BaseService
end
end
def must_not_clauses
[]
end
def should_clauses
if @account && !@options[:following]
[boost_following_query]
@ -218,7 +223,7 @@ class AccountSearchService < BaseService
records = query_builder.build.limit(limit_for_non_exact_results).offset(offset).objects.compact
ActiveRecord::Associations::Preloader.new(records: records, associations: :account_stat)
ActiveRecord::Associations::Preloader.new(records: records, associations: [:account_stat, { user: :role }]).call
records
rescue Faraday::ConnectionFailed, Parslet::ParseFailed

View file

@ -11,7 +11,7 @@ class BatchedRemoveStatusService < BaseService
ActiveRecord::Associations::Preloader.new(
records: statuses,
associations: options[:skip_side_effects] ? :reblogs : [:account, :tags, reblogs: :account]
)
).call
statuses_and_reblogs = statuses.flat_map { |status| [status] + status.reblogs }
@ -23,7 +23,7 @@ class BatchedRemoveStatusService < BaseService
ActiveRecord::Associations::Preloader.new(
records: statuses_with_account_conversations,
associations: [mentions: :account]
)
).call
statuses_with_account_conversations.each(&:unlink_from_conversations!)

View file

@ -74,6 +74,15 @@ class FanOutOnWriteService < BaseService
LocalNotificationWorker.push_bulk(mentions) do |mention|
[mention.account_id, mention.id, 'Mention', 'mention']
end
next unless update?
# This may result in duplicate update payloads, but this ensures clients
# are aware of edits to posts only appearing in mention notifications
# (e.g. private mentions or mentions by people they do not follow)
PushUpdateWorker.push_bulk(mentions.filter { |mention| subscribed_to_streaming_api?(mention.account_id) }) do |mention|
[mention.account_id, @status.id, "timeline:#{mention.account_id}:notifications", { 'update' => true }]
end
end
end
@ -162,4 +171,8 @@ class FanOutOnWriteService < BaseService
def broadcastable?
@status.public_visibility? && !@status.reblog? && !@account.silenced?
end
def subscribed_to_streaming_api?(account_id)
redis.exists?("subscribed:timeline:#{account_id}") || redis.exists?("subscribed:timeline:#{account_id}:notifications")
end
end

View file

@ -20,7 +20,7 @@ class FavouriteService < BaseService
Trends.statuses.register(status)
create_notification(favourite)
bump_potential_friendship(account, status)
increment_statistics
favourite
end
@ -37,11 +37,8 @@ class FavouriteService < BaseService
end
end
def bump_potential_friendship(account, status)
def increment_statistics
ActivityTracker.increment('activity:interactions')
return if account.following?(status.account_id)
PotentialFriendshipTracker.record(account.id, status.account_id, :favourite)
end
def build_json(favourite)

View file

@ -100,7 +100,7 @@ class FetchOEmbedService
end
def validate(oembed)
oembed if oembed[:version].to_s == '1.0' && oembed[:type].present?
oembed if oembed.present? && oembed[:version].to_s == '1.0' && oembed[:type].present?
end
def html

View file

@ -178,9 +178,6 @@ class PostStatusService < BaseService
return if !@status.reply? || @account.id == @status.in_reply_to_account_id
ActivityTracker.increment('activity:interactions')
return if @account.following?(@status.in_reply_to_account_id)
PotentialFriendshipTracker.record(@account.id, @status.in_reply_to_account_id, :reply)
end
def status_attributes

View file

@ -33,7 +33,7 @@ class ReblogService < BaseService
ActivityPub::DistributionWorker.perform_async(reblog.id)
create_notification(reblog)
bump_potential_friendship(account, reblog)
increment_statistics
reblog
end
@ -50,12 +50,8 @@ class ReblogService < BaseService
end
end
def bump_potential_friendship(account, reblog)
def increment_statistics
ActivityTracker.increment('activity:interactions')
return if account.following?(reblog.reblog.account_id)
PotentialFriendshipTracker.record(account.id, reblog.reblog.account_id, :reblog)
end
def build_json(reblog)

View file

@ -21,7 +21,7 @@ class UpdateAccountService < BaseService
def authorize_all_follow_requests(account)
follow_requests = FollowRequest.where(target_account: account)
follow_requests = follow_requests.preload(:account).select { |req| !req.account.silenced? }
follow_requests = follow_requests.preload(:account).reject { |req| req.account.silenced? }
AuthorizeFollowWorker.push_bulk(follow_requests, limit: 1_000) do |req|
[req.account_id, req.target_account_id]
end

View file

@ -6,8 +6,8 @@
%p.muted-hint= deletion_request.present? ? t('admin.accounts.suspension_reversible_hint_html', date: content_tag(:strong, l(deletion_request.due_at.to_date))) : t('admin.accounts.suspension_irreversible')
= link_to t('admin.accounts.undo_suspension'), unsuspend_admin_account_path(account.id), method: :post, class: 'button' if can?(:unsuspend, account)
= link_to t('admin.accounts.redownload'), redownload_admin_account_path(account.id), method: :post, class: 'button' if can?(:redownload, account) && account.suspension_origin_remote?
- if deletion_request.present?
= link_to t('admin.accounts.delete'), admin_account_path(account.id), method: :delete, class: 'button button--destructive', data: { confirm: t('admin.accounts.are_you_sure') } if can?(:destroy, account)
- if deletion_request.present? && can?(:destroy, account)
= link_to t('admin.accounts.delete'), admin_account_path(account.id), method: :delete, class: 'button button--destructive', data: { confirm: t('admin.accounts.are_you_sure') }
- else
.action-buttons
%div
@ -15,8 +15,8 @@
= link_to t('admin.accounts.warn'), new_admin_account_action_path(account.id, type: 'none'), class: 'button' if can?(:warn, account)
- if account.user_disabled?
= link_to t('admin.accounts.enable'), enable_admin_account_path(account.id), method: :post, class: 'button' if can?(:enable, account.user)
- else
= link_to t('admin.accounts.disable'), new_admin_account_action_path(account.id, type: 'disable'), class: 'button' if can?(:disable, account.user)
- elsif can?(:disable, account.user)
= link_to t('admin.accounts.disable'), new_admin_account_action_path(account.id, type: 'disable'), class: 'button'
- if account.sensitized?
= link_to t('admin.accounts.undo_sensitized'), unsensitive_admin_account_path(account.id), method: :post, class: 'button' if can?(:unsensitive, account)
- elsif !account.local? || account.user_approved?
@ -29,13 +29,13 @@
- if account.user_pending?
= link_to t('admin.accounts.approve'), approve_admin_account_path(account.id), method: :post, data: { confirm: t('admin.accounts.are_you_sure') }, class: 'button' if can?(:approve, account.user)
= link_to t('admin.accounts.reject'), reject_admin_account_path(account.id), method: :post, data: { confirm: t('admin.accounts.are_you_sure') }, class: 'button button--destructive' if can?(:reject, account.user)
- unless account.user_confirmed?
= link_to t('admin.accounts.confirm'), admin_account_confirmation_path(account.id), method: :post, class: 'button' if can?(:confirm, account.user)
- if !account.local? || account.user_approved?
= link_to t('admin.accounts.perform_full_suspension'), new_admin_account_action_path(account.id, type: 'suspend'), class: 'button' if can?(:suspend, account)
- if !account.user_confirmed? && can?(:confirm, account.user)
= link_to t('admin.accounts.confirm'), admin_account_confirmation_path(account.id), method: :post, class: 'button'
- if (!account.local? || account.user_approved?) && can?(:suspend, account)
= link_to t('admin.accounts.perform_full_suspension'), new_admin_account_action_path(account.id, type: 'suspend'), class: 'button'
%div
- if account.local?
- if !account.memorial? && account.user_approved?
= link_to t('admin.accounts.memorialize'), memorialize_admin_account_path(account.id), method: :post, data: { confirm: t('admin.accounts.are_you_sure') }, class: 'button button--destructive' if can?(:memorialize, account)
- else
= link_to t('admin.accounts.redownload'), redownload_admin_account_path(account.id), method: :post, class: 'button' if can?(:redownload, account)
- if !account.memorial? && account.user_approved? && can?(:memorialize, account)
= link_to t('admin.accounts.memorialize'), memorialize_admin_account_path(account.id), method: :post, data: { confirm: t('admin.accounts.are_you_sure') }, class: 'button button--destructive'
- elsif can?(:redownload, account)
= link_to t('admin.accounts.redownload'), redownload_admin_account_path(account.id), method: :post, class: 'button'

View file

@ -47,8 +47,8 @@
- else
= t 'admin.accounts.security_measures.only_password'
%td
- if account.user&.two_factor_enabled?
= table_link_to 'unlock', t('admin.accounts.disable_two_factor_authentication'), admin_user_two_factor_authentication_path(account.user.id), method: :delete if can?(:disable_2fa, account.user)
- if account.user&.two_factor_enabled? && can?(:disable_2fa, account.user)
= table_link_to 'unlock', t('admin.accounts.disable_two_factor_authentication'), admin_user_two_factor_authentication_path(account.user.id), method: :delete
- if can?(:reset_password, account.user)
%tr
%td

View file

@ -38,3 +38,5 @@
= nothing_here 'nothing-here--under-tabs'
- else
= render partial: 'account', collection: @accounts, locals: { f: f }
= paginate @accounts

View file

@ -2,61 +2,11 @@
class Scheduler::FollowRecommendationsScheduler
include Sidekiq::Worker
include Redisable
sidekiq_options retry: 0, lock: :until_executed, lock_ttl: 1.day.to_i
# The maximum number of accounts that can be requested in one page from the
# API is 80, and the suggestions API does not allow pagination. This number
# leaves some room for accounts being filtered during live access
SET_SIZE = 100
def perform
# Maintaining a materialized view speeds-up subsequent queries significantly
AccountSummary.refresh
FollowRecommendation.refresh
fallback_recommendations = FollowRecommendation.order(rank: :desc).limit(SET_SIZE)
Trends.available_locales.each do |locale|
recommendations = if AccountSummary.safe.filtered.localized(locale).exists? # We can skip the work if no accounts with that language exist
FollowRecommendation.localized(locale).order(rank: :desc).limit(SET_SIZE).map { |recommendation| [recommendation.rank, recommendation.account_id] }
else
[]
end
# Use language-agnostic results if there are not enough language-specific ones
missing = SET_SIZE - recommendations.size
if missing.positive? && fallback_recommendations.size.positive?
max_fallback_rank = fallback_recommendations.first.rank || 0
# Language-specific results should be above language-agnostic ones,
# otherwise language-agnostic ones will always overshadow them
recommendations.map! { |(rank, account_id)| [rank + max_fallback_rank, account_id] }
added = 0
fallback_recommendations.each do |recommendation|
next if recommendations.any? { |(_, account_id)| account_id == recommendation.account_id }
recommendations << [recommendation.rank, recommendation.account_id]
added += 1
break if added >= missing
end
end
redis.multi do |multi|
multi.del(key(locale))
multi.zadd(key(locale), recommendations)
end
end
end
private
def key(locale)
"follow_recommendations:#{locale}"
end
end

View file

@ -63,13 +63,6 @@ module Mastodon
# Initialize configuration defaults for originally generated Rails version.
config.load_defaults 7.0
# TODO: Release a version which uses the 7.0 defaults as specified above,
# but preserves the 6.1 cache format as set below. In a subsequent change,
# remove this line setting to 6.1 cache format, and then release another version.
# https://guides.rubyonrails.org/upgrading_ruby_on_rails.html#new-activesupport-cache-serialization-format
# https://github.com/mastodon/mastodon/pull/24241#discussion_r1162890242
config.active_support.cache_format_version = 6.1
# Please, add to the `ignore` list any other `lib` subdirectories that do
# not contain `.rb` files, or that should not be reloaded or eager loaded.
# Common ones are `templates`, `generators`, or `middleware`, for example.

View file

@ -1,7 +1,7 @@
# frozen_string_literal: true
unless ENV.key?('RAILS_ENV')
STDERR.puts 'ERROR: Missing RAILS_ENV environment variable, please set it to "production", "development", or "test".'
warn 'ERROR: Missing RAILS_ENV environment variable, please set it to "production", "development", or "test".'
exit 1
end

View file

@ -79,7 +79,7 @@ Devise.setup do |config|
oidc_options[:client_auth_method] = ENV['OIDC_CLIENT_AUTH_METHOD'] if ENV['OIDC_CLIENT_AUTH_METHOD'] # OPTIONAL (default: basic)
scope_string = ENV['OIDC_SCOPE'] if ENV['OIDC_SCOPE'] # NEED
scopes = scope_string.split(',')
oidc_options[:scope] = scopes.map { |x| x.to_sym }
oidc_options[:scope] = scopes.map(&:to_sym)
oidc_options[:response_type] = ENV['OIDC_RESPONSE_TYPE'] if ENV['OIDC_RESPONSE_TYPE'] # OPTIONAL (default: code)
oidc_options[:response_mode] = ENV['OIDC_RESPONSE_MODE'] if ENV['OIDC_RESPONSE_MODE'] # OPTIONAL (default: query)
oidc_options[:display] = ENV['OIDC_DISPLAY'] if ENV['OIDC_DISPLAY'] # OPTIONAL (default: page)

View file

@ -1,9 +1,6 @@
# frozen_string_literal: true
# TODO: Remove after 4.2.0
Rails.application.configure do
config.active_support.key_generator_hash_digest_class = OpenSSL::Digest::SHA1
end
# TODO: remove this file some time after 4.3.0
Rails.application.config.after_initialize do
Rails.application.config.action_dispatch.cookies_rotations.tap do |cookies|
@ -12,9 +9,8 @@ Rails.application.config.after_initialize do
secret_key_base = Rails.application.secret_key_base
# TODO: Switch to SHA1 after 4.2.0
key_generator = ActiveSupport::KeyGenerator.new(
secret_key_base, iterations: 1000, hash_digest_class: OpenSSL::Digest::SHA256
secret_key_base, iterations: 1000, hash_digest_class: OpenSSL::Digest::SHA1
)
key_len = ActiveSupport::MessageEncryptor.key_len

View file

@ -164,7 +164,7 @@ SimpleForm.setup do |config|
# config.item_wrapper_class = nil
# How the label text should be generated altogether with the required text.
config.label_text = lambda { |label, required, _explicit_label| "#{label} #{required}" }
config.label_text = ->(label, required, _explicit_label) { "#{label} #{required}" }
# You can define the class to use on all labels. Default is nil.
# config.label_class = nil

View file

@ -1,13 +1,8 @@
# frozen_string_literal: true
module Rack
class Request
def trusted_proxy?(ip)
if Rails.application.config.action_dispatch.trusted_proxies.nil?
super
else
Rails.application.config.action_dispatch.trusted_proxies.any? { |proxy| proxy === ip }
end
end
end
unless Rails.application.config.action_dispatch.trusted_proxies.nil?
# Rack is configured with a default collection of trusted proxies
# If Rails has been configured to use a specific list, configure
# Rack to use this Proc, which enforces the Rails-configured list.
Rack::Request.ip_filter = ->(ip) { Rails.application.config.action_dispatch.trusted_proxies.include?(ip) }
end

View file

@ -0,0 +1,8 @@
---
ia:
activerecord:
attributes:
user:
password: Contrasigno
user/account:
username: Nomine de usator

View file

@ -0,0 +1,9 @@
---
ie:
activerecord:
attributes:
poll:
expires_at: Cludent date
options: Optiones
user:
password: Passa-parol

View file

@ -0,0 +1,51 @@
---
lad:
activerecord:
attributes:
poll:
expires_at: Limito temporal
options: Opsyones
user:
agreement: Akodro de servisyo
email: Adreso de posta elektronika
locale: Lingua
password: Kod
user/account:
username: Nombre de uzador
user/invite_request:
text: Razon
errors:
models:
account:
attributes:
username:
invalid: solo puede kontener letras, shifras i sulinyados
reserved: esta rezervado
admin/webhook:
attributes:
url:
invalid: no es adreso URL valido
doorkeeper/application:
attributes:
website:
invalid: no es adreso URL valido
import:
attributes:
data:
malformed: tiene formato yerrado
user:
attributes:
email:
blocked: uza un prokurador de posta no autorizado
unreachable: no parese existir
role_id:
elevated: no puede ser mas alto ke tu rolo aktual
user_role:
attributes:
permissions_as_keys:
dangerous: inkluir permisos ke no son siguros para el rolo de baza
elevated: no se puede inkluir permisos kualos no tiene tu rolo aktual
own_role: no se puede trokar kon tu rolo aktual
position:
elevated: no puede ser mas alto ke tu rolo aktual
own_role: no se puede trokar kon tu rolo aktual

View file

@ -1 +1,23 @@
---
pa:
activerecord:
attributes:
poll:
expires_at: ਆਖਰੀ ਤਾਰੀਖ
options: ਚੋਣਾਂ
user:
agreement: ਸੇਵਾ ਸਮਝੌਤਾ
email: ਈਮੇਲ ਪਤਾ
locale: ਲੋਕੇਲ
password: ਪਾਸਵਰਡ
user/account:
username: ਵਰਤੋਂਕਾਰ-ਨਾਂ
user/invite_request:
text: ਕਾਰਨ
errors:
models:
account:
attributes:
username:
invalid: ਸਿਰਫ਼ ਅੱਖਰ, ਅੰਕ ਅਤੇ ਹੇਠਾਂ-ਰੇਖਾ ਹੀ ਹੋੋਣੀ ਚਾਹੀਦੀ ਹੈ
reserved: ਰਾਖਵਾਂ ਹੈ

View file

@ -28,7 +28,7 @@ zh-TW:
doorkeeper/application:
attributes:
website:
invalid: 不是有效的 URL
invalid: 不是有效的網址
import:
attributes:
data:

View file

@ -0,0 +1 @@
ia:

View file

@ -0,0 +1,28 @@
---
ie:
devise:
failure:
invalid: Ínvalid %{authentication_keys} o passa-parol.
not_found_in_database: Ínvalid %{authentication_keys} o passa-parol.
mailer:
email_changed:
extra: Si tu ne changeat tui email-adresse, it es probabil que alqui ha ganiat accesse a tui conto. Ples changear tui passa-parol strax o contacter li administrator del servitor si tu ne posse intrar tui conto.
password_change:
explanation: Li passa-parol de tui conto ha esset changeat.
extra: Si tu ne changeat tui passa-parol, it es probabil que alqui ha ganiat accesse a tui conto. Ples changear tui passa-parol strax o contacter li administrator del servitor si tu ne posse intrar tui conto.
subject: 'Mastodon: Passa-parol changeat'
title: Passa-parol changeat
reset_password_instructions:
action: Changear passa-parol
explanation: Tu demandat un nov passa-parol por tui conto.
extra: Si tu ne demandat to-ci, ples ignorar ti-ci email. Tui passa-parol ne va changear til que tu accessaye li ligament supra e crear un nov.
subject: 'Mastodon: Instructiones por reiniciar li passa-parol'
title: Reiniciar passa-parol
two_factor_disabled:
explanation: 2-factor autentication por tui conto ha esset desactivisat. Aperter session nu es possibil solmen per email-adresse e passa-parol.
passwords:
no_token: Tu ne posse accessar ti-ci págine sin venir de un email pri reiniciar li passa-parol. Si tu ha venit de un email pri reiniciar li passa-parol, ples far cert que tu usat li complet URL providet.
send_instructions: Si tui email-adresse existe in nor database, tu va reciver un ligament por recuperar li passa-parol a tui email-adresse in quelc minutes. Ples vider tui spam-emails si tu ne recivet ti email.
send_paranoid_instructions: Si tui email-adresse existe in nor database, tu va reciver un ligament por recuperar li passa-parol a tui email-adresse in quelc minutes. Ples vider tui spam-emails si tu ne recivet ti email.
updated: Tui passa-parol ha esset changeat successosimen. Tu nu ha apertet session.
updated_not_active: Tui passa-parol ha esset changeat successosimen.

Some files were not shown because too many files have changed in this diff Show more