Compare commits

...
164 changed files with 5003 additions and 3981 deletions
Generated
+2 -2
View File
@@ -5830,9 +5830,9 @@ dependencies = [
[[package]]
name = "yoke-derive"
version = "0.8.3"
version = "0.8.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "33811428bee40dbceb6d545e95754741d17a6aef9a4849f0fd62e2ba4f412a78"
checksum = "ec8ebde2db3681e8c9980cc27822030e68752690ddfa9473e739aeb4dbde6d71"
dependencies = [
"proc-macro2",
"quote",
-1
View File
@@ -160,7 +160,6 @@ MEILI_MASTER_KEY=CHANGE_ME
# api.pwnedpasswords.com.
#FLUXER_BREACHED_PASSWORD_CHECK_ENABLED=false
#FLUXER_BLOCKLIST_FEEDS_ENABLED=false
#FLUXER_IPINFO_API_KEY=
# A local path, or an s3:// URL read with the S3 credentials of this file.
#FLUXER_GEOIP_DB_PATH=
-1
View File
@@ -33,7 +33,6 @@ x-fluxer-env: &fluxer-env
FLUXER_APP_ORIGIN_ALIASES: ${FLUXER_APP_ORIGIN_ALIASES:-}
FLUXER_BREACHED_PASSWORD_CHECK_ENABLED: ${FLUXER_BREACHED_PASSWORD_CHECK_ENABLED:-}
FLUXER_BLOCKLIST_FEEDS_ENABLED: ${FLUXER_BLOCKLIST_FEEDS_ENABLED:-}
FLUXER_IPINFO_API_KEY: ${FLUXER_IPINFO_API_KEY:-}
FLUXER_GEOIP_DB_PATH: ${FLUXER_GEOIP_DB_PATH:-}
FLUXER_API_ENDPOINT: ${FLUXER_API_ENDPOINT:-}
+11 -6
View File
@@ -1251,7 +1251,7 @@
"content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}
}
},
"description": "Add a value to a blocklist. The request body is the shape the blocklist named by list_type accepts, and the value is validated and canonicalized for that blocklist. Adding an IP address that is on the instance exemption list, or that IPInfo reports as a high blast-radius carrier NAT, is refused with 400 IP_BAN_DECLINED and recorded in the audit log.",
"description": "Add a value to a blocklist. The request body is the shape the blocklist named by list_type accepts, and the value is validated and canonicalized for that blocklist. Adding an IP address that is on the instance exemption list is refused with 400 IP_BAN_DECLINED and recorded in the audit log.",
"security": [{"adminApiKey": []}],
"parameters": [
{
@@ -5435,7 +5435,7 @@
"content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}
}
},
"description": "Queue a worker job that delivers the same content to every listed user as a direct message from the system account. Progress is observable through the Jobs admin resource (task_type=sendSystemDm), and an in-flight broadcast is stopped by cancelling that job. Requires SYSTEM_DM_SEND permission.",
"description": "Queue a worker job that delivers the same content to every listed user, or to every user when all_users is set, as a direct message from the system account. Progress is observable through the Jobs admin resource (task_type=sendSystemDm), and an in-flight broadcast is stopped by cancelling that job. Requires SYSTEM_DM_SEND permission.",
"security": [{"adminApiKey": []}],
"requestBody": {
"required": true,
@@ -10150,20 +10150,25 @@
"description": "Message content to send to each recipient"
},
"user_ids": {
"description": "Recipient user IDs. Each receives the same content as a system DM.",
"minItems": 1,
"maxItems": 10000,
"type": "array",
"items": {"$ref": "#/components/schemas/SnowflakeType"},
"description": "Recipient user IDs. Each receives the same content as a system DM."
"items": {"$ref": "#/components/schemas/SnowflakeType"}
},
"all_users": {
"description": "Send to every user account, skipping bots, system accounts, and deleted or disabled accounts",
"type": "boolean"
}
},
"required": ["content", "user_ids"]
"required": ["content"]
},
"SendSystemDmResponse": {
"type": "object",
"properties": {
"recipient_count": {
"description": "Number of recipients the worker job was queued to deliver to",
"nullable": true,
"description": "Number of recipients the worker job was queued to deliver to, or null when sending to all users",
"allOf": [{"$ref": "#/components/schemas/Int32Type"}]
}
},
+7 -2
View File
@@ -8,13 +8,18 @@ use super::types::SendSystemDmResponse;
impl AdminApiClient {
pub async fn send_system_dm(
&self,
user_ids: &[String],
user_ids: Option<&[String]>,
content: &str,
) -> ApiResult<SendSystemDmResponse> {
let body = generated_types::SendSystemDmRequest {
content: generated_types::SendSystemDmRequestContent::try_from(content)
.map_err(|e| ApiError::Parse(e.to_string()))?,
user_ids: user_ids.iter().map(|id| snowflake(id)).collect(),
user_ids: user_ids
.unwrap_or_default()
.iter()
.map(|id| snowflake(id))
.collect(),
all_users: user_ids.is_none().then_some(true),
};
let response = self
.generated()
+1 -1
View File
@@ -4,5 +4,5 @@ use serde::{Deserialize, Serialize};
#[derive(Clone, Debug, Deserialize, Serialize)]
pub struct SendSystemDmResponse {
pub recipient_count: i64,
pub recipient_count: Option<i64>,
}
+2 -1
View File
@@ -171,7 +171,8 @@ pub(crate) async fn system_dms_post(
let flash = if let Some(content) = content.as_deref()
&& !user_ids.is_empty()
{
match client.send_system_dm(&user_ids, content).await {
let recipients = (user_ids != ["*"]).then_some(user_ids.as_slice());
match client.send_system_dm(recipients, content).await {
Ok(_) => FlashData::success("System DM sent"),
Err(error) => {
tracing::warn!(%error, "admin API request failed: send system DM");
@@ -58,7 +58,7 @@ pub fn system_dm_page(
(form_field_group(
"Recipient user IDs", "system-dm-user-ids",
true, None,
Some("One per line. Snowflake IDs only."),
Some("One per line. Snowflake IDs only, or a single * to send to every user."),
html! {
textarea id="system-dm-user-ids" name="user_ids"
required rows="10"
+1 -4
View File
@@ -11,13 +11,10 @@
},
"dependencies": {
"@aws-sdk/client-s3": "catalog:",
"@pkgs/cassandra": "workspace:*",
"@fluxer/geo_utils": "workspace:*",
"@fluxer/instance_bootstrap": "workspace:*",
"@fluxer/ip_utils": "workspace:*",
"@pkgs/postgres": "workspace:*",
"maxmind": "catalog:",
"zod": "catalog:"
"maxmind": "catalog:"
},
"devDependencies": {
"@types/node": "catalog:",
@@ -1,60 +0,0 @@
// SPDX-License-Identifier: AGPL-3.0-or-later
import type {ICassandraClient} from '@pkgs/cassandra/src/Client';
import type {IpInfoCache} from '@pkgs/geoip/src/IpInfoService';
const TABLE = 'ipinfo_cache';
const SELECT_CQL = `SELECT payload FROM ${TABLE} WHERE cache_key = :cache_key LIMIT 1;`;
const INSERT_WITH_TTL_CQL = `INSERT INTO ${TABLE} (cache_key, payload) VALUES (:cache_key, :payload) USING TTL :ttl;`;
const INSERT_DEFAULT_TTL_CQL = `INSERT INTO ${TABLE} (cache_key, payload) VALUES (:cache_key, :payload);`;
interface CassandraIpInfoCacheOptions {
client?: ICassandraClient;
getClient?: () => ICassandraClient;
}
export function createCassandraIpInfoCache(options: CassandraIpInfoCacheOptions): IpInfoCache {
return {
async get<T>(key: string): Promise<T | null> {
try {
const client = options.client ?? options.getClient?.();
if (!client) {
return null;
}
const result = await client.execute({cql: SELECT_CQL, params: {cache_key: key}});
const row = result.first();
if (!row) return null;
const payload = row.get('payload');
if (typeof payload !== 'string') return null;
return JSON.parse(payload) as T;
} catch {
return null;
}
},
async set<T>(key: string, value: T, ttlSeconds?: number): Promise<void> {
let payload: string;
try {
payload = JSON.stringify(value);
} catch {
return;
}
try {
const client = options.client ?? options.getClient?.();
if (!client) {
return;
}
if (ttlSeconds != null && Number.isFinite(ttlSeconds) && ttlSeconds > 0) {
await client.execute({
cql: INSERT_WITH_TTL_CQL,
params: {cache_key: key, payload, ttl: ttlSeconds},
});
} else {
await client.execute({
cql: INSERT_DEFAULT_TTL_CQL,
params: {cache_key: key, payload},
});
}
} catch {}
},
};
}
@@ -1,119 +0,0 @@
// SPDX-License-Identifier: AGPL-3.0-or-later
import {randomUUID} from 'node:crypto';
import type {ICassandraClient} from '@pkgs/cassandra/src/Client';
import type {IpInfoRequestAuditEvent, IpInfoRequestAuditLogger} from '@pkgs/geoip/src/IpInfoService';
const TABLE = 'ipinfo_requests_by_hour';
const INSERT_CQL = `INSERT INTO ${TABLE} (
bucket_date,
bucket_hour,
requested_at,
event_id,
source,
reason,
ip,
cache_key,
request_url,
http_status,
outcome,
available,
risk_note,
latency_ms,
response_ip,
country_code,
asn,
is_anonymous,
is_tor,
is_vpn,
is_proxy,
is_residential_proxy,
metadata_json
) VALUES (
:bucket_date,
:bucket_hour,
:requested_at,
:event_id,
:source,
:reason,
:ip,
:cache_key,
:request_url,
:http_status,
:outcome,
:available,
:risk_note,
:latency_ms,
:response_ip,
:country_code,
:asn,
:is_anonymous,
:is_tor,
:is_vpn,
:is_proxy,
:is_residential_proxy,
:metadata_json
);`;
interface CassandraIpInfoRequestAuditOptions {
client?: ICassandraClient;
getClient?: () => ICassandraClient;
}
export function createCassandraIpInfoRequestAuditLogger(
options: CassandraIpInfoRequestAuditOptions,
): IpInfoRequestAuditLogger {
return {
async record(event: IpInfoRequestAuditEvent): Promise<void> {
try {
const client = options.client ?? options.getClient?.();
if (!client) {
return;
}
await client.execute({
cql: INSERT_CQL,
params: {
bucket_date: formatUtcDate(event.requestedAt),
bucket_hour: event.requestedAt.getUTCHours(),
requested_at: event.requestedAt,
event_id: randomUUID(),
source: event.source,
reason: event.reason,
ip: event.ip,
cache_key: event.cacheKey,
request_url: event.requestUrl,
http_status: event.httpStatus,
outcome: event.outcome,
available: event.available,
risk_note: event.note,
latency_ms: event.latencyMs,
response_ip: event.responseIp,
country_code: event.countryCode,
asn: event.asnNumber,
is_anonymous: event.isAnonymous,
is_tor: event.isTor,
is_vpn: event.isVpn,
is_proxy: event.isProxy,
is_residential_proxy: event.isResidentialProxy,
metadata_json: serializeMetadata(event.metadata),
},
});
} catch {}
},
};
}
function formatUtcDate(value: Date): string {
return value.toISOString().slice(0, 10);
}
function serializeMetadata(metadata: IpInfoRequestAuditEvent['metadata']): string | null {
if (!metadata || Object.keys(metadata).length === 0) {
return null;
}
try {
return JSON.stringify(metadata);
} catch {
return null;
}
}
-506
View File
@@ -1,506 +0,0 @@
// SPDX-License-Identifier: AGPL-3.0-or-later
import {getSameIpDecisionKey} from '@fluxer/ip_utils/src/IpAddress';
import {z} from 'zod';
const IPINFO_BASE_URL = 'https://api.ipinfo.io/lookup';
const FETCH_TIMEOUT_MS = 3000;
const CACHE_KEY_PREFIX = 'ipinfo:max:';
const ISO_DATE_REGEX = /^\d{4}-\d{2}-\d{2}$/u;
const POSITIVE_CACHE_TTL_SECONDS = 7 * 24 * 60 * 60;
const NEGATIVE_CACHE_TTL_SECONDS = 14 * 24 * 60 * 60;
const FAILURE_TTL_REQUEST_FAILED_SECONDS = 60;
const FAILURE_TTL_HTTP_ERROR_SECONDS = 300;
const FAILURE_TTL_QUOTA_SECONDS = 900;
const FAILURE_TTL_SCHEMA_MISMATCH_SECONDS = 600;
export interface IpInfoGeoBlock {
countryCode: string | null;
countryName: string | null;
continent: string | null;
continentCode: string | null;
region: string | null;
regionCode: string | null;
city: string | null;
postalCode: string | null;
timezone: string | null;
latitude: number | null;
longitude: number | null;
accuracyRadiusKm: number | null;
}
export interface IpInfoAsnBlock {
asn: string | null;
number: number | null;
name: string | null;
domain: string | null;
type: string | null;
}
export interface IpInfoMobileBlock {
name: string | null;
mcc: string | null;
mnc: string | null;
}
export interface IpInfoAnonymousBlock {
isAnonymous: boolean;
providerName: string | null;
isVpn: boolean;
isProxy: boolean;
isResidentialProxy: boolean;
isTor: boolean;
isRelay: boolean;
percentDaysSeen: number | null;
}
export interface IpInfoFlags {
isAnycast: boolean;
isHosting: boolean;
isMobile: boolean;
isSatellite: boolean;
}
export interface IpInfoLookupResult {
ip: string;
available: boolean;
note: string;
geo: IpInfoGeoBlock;
asn: IpInfoAsnBlock;
mobile: IpInfoMobileBlock;
anonymous: IpInfoAnonymousBlock;
flags: IpInfoFlags;
}
export interface IpInfoCache {
get<T>(key: string): Promise<T | null>;
set<T>(key: string, value: T, ttlSeconds?: number): Promise<void>;
}
export interface CachedIpInfoFailure extends IpInfoLookupResult {
cachedFailure: true;
failureOutcome: 'http_error' | 'request_failed' | 'schema_mismatch';
failureHttpStatus: number | null;
cachedAtMs: number;
}
export function isCachedIpInfoFailure(value: unknown): value is CachedIpInfoFailure {
return typeof value === 'object' && value !== null && (value as {available?: unknown}).available === false;
}
function failureCacheTtlSeconds(outcome: CachedIpInfoFailure['failureOutcome'], httpStatus: number | null): number {
if (outcome === 'request_failed') return FAILURE_TTL_REQUEST_FAILED_SECONDS;
if (outcome === 'schema_mismatch') return FAILURE_TTL_SCHEMA_MISMATCH_SECONDS;
if (httpStatus === 402 || httpStatus === 403 || httpStatus === 429) return FAILURE_TTL_QUOTA_SECONDS;
return FAILURE_TTL_HTTP_ERROR_SECONDS;
}
export interface IpInfoLookupContext {
source?: string;
reason?: string;
metadata?: Record<string, string | number | boolean | null>;
}
export interface IpInfoRequestAuditEvent {
requestedAt: Date;
ip: string;
cacheKey: string;
source: string;
reason: string | null;
metadata?: Record<string, string | number | boolean | null>;
outcome: 'http_success' | 'http_error' | 'request_failed' | 'schema_mismatch';
httpStatus: number | null;
available: boolean;
note: string;
latencyMs: number;
requestUrl: string;
responseIp: string | null;
countryCode: string | null;
asnNumber: number | null;
isAnonymous: boolean;
isTor: boolean;
isVpn: boolean;
isProxy: boolean;
isResidentialProxy: boolean;
}
export interface IpInfoRequestAuditLogger {
record(event: IpInfoRequestAuditEvent): Promise<void>;
}
interface IpInfoServiceContext {
apiKey: string;
cache: IpInfoCache;
auditLogger?: IpInfoRequestAuditLogger;
}
export interface IpInfoService {
lookup(ip: string, context?: IpInfoLookupContext): Promise<IpInfoLookupResult>;
}
const IpInfoDateSchema = z.string().regex(ISO_DATE_REGEX);
const RawIpInfoGeoSchema = z.object({
city: z.string().optional(),
region: z.string().optional(),
region_code: z.string().optional(),
country: z.string().optional(),
country_code: z.string().optional(),
continent: z.string().optional(),
continent_code: z.string().optional(),
latitude: z.number().optional(),
longitude: z.number().optional(),
timezone: z.string().optional(),
postal_code: z.string().optional(),
dma_code: z.string().optional(),
geoname_id: z.string().optional(),
radius: z.number().int().optional(),
last_changed: IpInfoDateSchema.optional(),
});
const RawIpInfoAsSchema = z.object({
asn: z.string().optional(),
name: z.string().optional(),
domain: z.string().optional(),
type: z.string().optional(),
last_changed: IpInfoDateSchema.optional(),
});
const RawIpInfoMobileSchema = z.object({
name: z.string().optional(),
mcc: z.string().optional(),
mnc: z.string().optional(),
});
const RawIpInfoAnonymousSchema = z.object({
name: z.string().optional(),
last_seen: IpInfoDateSchema.optional(),
percent_days_seen: z.number().int().optional(),
is_proxy: z.boolean().optional(),
is_relay: z.boolean().optional(),
is_tor: z.boolean().optional(),
is_vpn: z.boolean().optional(),
is_res_proxy: z.boolean().optional(),
});
const RawIpInfoResponseSchema = z.object({
ip: z.string(),
hostname: z.string().optional(),
geo: RawIpInfoGeoSchema,
as: RawIpInfoAsSchema,
mobile: RawIpInfoMobileSchema.optional(),
anonymous: RawIpInfoAnonymousSchema,
is_anonymous: z.boolean().optional(),
is_anycast: z.boolean().optional(),
is_hosting: z.boolean().optional(),
is_mobile: z.boolean().optional(),
is_satellite: z.boolean().optional(),
});
type RawIpInfoResponse = z.infer<typeof RawIpInfoResponseSchema>;
export function createIpInfoService(ctx: IpInfoServiceContext): IpInfoService {
const inflight: Map<string, Promise<IpInfoLookupResult>> = new Map();
return {
async lookup(ip: string, context?: IpInfoLookupContext): Promise<IpInfoLookupResult> {
const cacheKey = `${CACHE_KEY_PREFIX}${getSameIpDecisionKey(ip) ?? ip}`;
const cached = await ctx.cache.get<IpInfoLookupResult>(cacheKey);
if (cached !== null) {
if (isCachedIpInfoFailure(cached)) {
return unavailable(ip, cached.note);
}
return {...cached, ip};
}
const existing = inflight.get(cacheKey);
if (existing) {
const result = await existing;
return {...result, ip};
}
const requestedAt = new Date();
const startedAt = Date.now();
const requestUrl = `${IPINFO_BASE_URL}/${encodeURIComponent(ip)}`;
const fetchUrl = `${requestUrl}?token=${encodeURIComponent(ctx.apiKey)}`;
const finalize = async (params: {
result: IpInfoLookupResult;
outcome: IpInfoRequestAuditEvent['outcome'];
httpStatus: number | null;
}): Promise<IpInfoLookupResult> => {
await ctx.auditLogger
?.record({
requestedAt,
ip,
cacheKey,
source: context?.source ?? 'unknown',
reason: context?.reason ?? null,
metadata: context?.metadata,
outcome: params.outcome,
httpStatus: params.httpStatus,
available: params.result.available,
note: params.result.note,
latencyMs: Date.now() - startedAt,
requestUrl,
responseIp: params.result.available ? params.result.ip : null,
countryCode: params.result.geo.countryCode,
asnNumber: params.result.asn.number,
isAnonymous: params.result.anonymous.isAnonymous,
isTor: params.result.anonymous.isTor,
isVpn: params.result.anonymous.isVpn,
isProxy: params.result.anonymous.isProxy,
isResidentialProxy: params.result.anonymous.isResidentialProxy,
})
.catch(() => {});
return params.result;
};
const performLookup = async (): Promise<IpInfoLookupResult> => {
const finalizeFailure = async (params: {
result: IpInfoLookupResult;
outcome: CachedIpInfoFailure['failureOutcome'];
httpStatus: number | null;
}): Promise<IpInfoLookupResult> => {
const entry: CachedIpInfoFailure = {
...params.result,
cachedFailure: true,
failureOutcome: params.outcome,
failureHttpStatus: params.httpStatus,
cachedAtMs: Date.now(),
};
await ctx.cache
.set(cacheKey, entry, failureCacheTtlSeconds(params.outcome, params.httpStatus))
.catch(() => {});
return finalize(params);
};
const controller = new AbortController();
const timer = setTimeout(() => {
controller.abort(new DOMException('The operation was aborted due to timeout', 'TimeoutError'));
}, FETCH_TIMEOUT_MS);
timer.unref();
let payload: unknown;
try {
const res = await fetch(fetchUrl, {
signal: controller.signal,
headers: {Accept: 'application/json'},
});
if (!res.ok) {
return finalizeFailure({
result: unavailable(ip, `IPInfo HTTP ${res.status}`),
outcome: 'http_error',
httpStatus: res.status,
});
}
payload = await res.json();
} catch (err) {
const detail = err instanceof Error ? err.message : String(err);
return finalizeFailure({
result: unavailable(ip, `IPInfo request failed: ${detail}`),
outcome: 'request_failed',
httpStatus: null,
});
} finally {
clearTimeout(timer);
controller.abort();
}
const parsedResponse = RawIpInfoResponseSchema.safeParse(payload);
if (!parsedResponse.success) {
return finalizeFailure({
result: unavailable(ip, formatSchemaMismatch(parsedResponse.error)),
outcome: 'schema_mismatch',
httpStatus: 200,
});
}
const result = parseIpInfoResponse(parsedResponse.data);
const ttl = result.anonymous.isAnonymous ? POSITIVE_CACHE_TTL_SECONDS : NEGATIVE_CACHE_TTL_SECONDS;
await ctx.cache.set(cacheKey, result, ttl).catch(() => {});
return finalize({
result,
outcome: 'http_success',
httpStatus: 200,
});
};
const promise: Promise<IpInfoLookupResult> = performLookup().finally(() => {
if (inflight.get(cacheKey) === promise) {
inflight.delete(cacheKey);
}
});
inflight.set(cacheKey, promise);
return promise;
},
};
}
export function createUnavailableIpInfoService(reason = 'IPInfo not configured'): IpInfoService {
return {
async lookup(ip: string): Promise<IpInfoLookupResult> {
return unavailable(ip, reason);
},
};
}
function unavailable(ip: string, reason: string): IpInfoLookupResult {
return {
ip,
available: false,
note: reason,
geo: emptyGeo(),
asn: emptyAsn(),
mobile: emptyMobile(),
anonymous: emptyAnonymous(),
flags: emptyFlags(),
};
}
function emptyGeo(): IpInfoGeoBlock {
return {
countryCode: null,
countryName: null,
continent: null,
continentCode: null,
region: null,
regionCode: null,
city: null,
postalCode: null,
timezone: null,
latitude: null,
longitude: null,
accuracyRadiusKm: null,
};
}
function emptyAsn(): IpInfoAsnBlock {
return {asn: null, number: null, name: null, domain: null, type: null};
}
function emptyMobile(): IpInfoMobileBlock {
return {name: null, mcc: null, mnc: null};
}
function emptyAnonymous(): IpInfoAnonymousBlock {
return {
isAnonymous: false,
providerName: null,
isVpn: false,
isProxy: false,
isResidentialProxy: false,
isTor: false,
isRelay: false,
percentDaysSeen: null,
};
}
function emptyFlags(): IpInfoFlags {
return {isAnycast: false, isHosting: false, isMobile: false, isSatellite: false};
}
function parseIpInfoResponse(raw: RawIpInfoResponse): IpInfoLookupResult {
const geo = raw.geo;
const anon = raw.anonymous;
const isAnonymous =
raw.is_anonymous === true ||
anon.is_res_proxy === true ||
anon.is_vpn === true ||
anon.is_proxy === true ||
anon.is_tor === true ||
anon.is_relay === true;
return {
ip: raw.ip,
available: true,
note: describeAnonymity(isAnonymous, anon),
geo: {
countryCode: normalizeCountryCode(geo.country_code),
countryName: geo.country ?? null,
continent: geo?.continent ?? null,
continentCode: normalizeContinentCode(geo.continent_code),
region: geo.region ?? null,
regionCode: normalizeRegionCode(geo.region_code),
city: geo.city ?? null,
postalCode: geo.postal_code ?? null,
timezone: geo.timezone ?? null,
latitude: normalizeCoordinate(geo.latitude),
longitude: normalizeCoordinate(geo.longitude),
accuracyRadiusKm: typeof geo?.radius === 'number' && Number.isFinite(geo.radius) ? geo.radius : null,
},
asn: parseAsnBlock(raw.as),
mobile: {
name: raw.mobile?.name ?? null,
mcc: raw.mobile?.mcc ?? null,
mnc: raw.mobile?.mnc ?? null,
},
anonymous: {
isAnonymous,
providerName: anon?.name ?? null,
isVpn: anon?.is_vpn === true,
isProxy: anon?.is_proxy === true,
isResidentialProxy: anon?.is_res_proxy === true,
isTor: anon?.is_tor === true,
isRelay: anon?.is_relay === true,
percentDaysSeen: typeof anon?.percent_days_seen === 'number' ? anon.percent_days_seen : null,
},
flags: {
isAnycast: raw.is_anycast === true,
isHosting: raw.is_hosting === true,
isMobile: raw.is_mobile === true,
isSatellite: raw.is_satellite === true,
},
};
}
function formatSchemaMismatch(error: z.ZodError): string {
const issue = error.issues[0];
if (!issue) {
return 'IPInfo response schema mismatch';
}
const path = issue.path.length > 0 ? issue.path.join('.') : '<root>';
return `IPInfo response schema mismatch at ${path}: ${issue.message}`;
}
function parseAsnBlock(as: RawIpInfoResponse['as']): IpInfoAsnBlock {
const raw = as?.asn ?? null;
const numeric = raw ? Number(raw.replace(/^AS/i, '')) : Number.NaN;
return {
asn: raw,
number: Number.isFinite(numeric) ? numeric : null,
name: as?.name ?? null,
domain: as?.domain ?? null,
type: as?.type ?? null,
};
}
function describeAnonymity(isAnonymous: boolean, anon: RawIpInfoResponse['anonymous']): string {
if (!isAnonymous) {
return 'IPInfo: IP is not anonymous';
}
if (!anon) {
return 'IPInfo: anonymous IP';
}
const flags: Array<string> = [];
if (anon.is_res_proxy) flags.push('residential proxy');
if (anon.is_vpn) flags.push('VPN');
if (anon.is_proxy) flags.push('proxy');
if (anon.is_tor) flags.push('Tor');
if (anon.is_relay) flags.push('relay');
const provider = anon.name ? ` (provider: ${anon.name})` : '';
const seen = anon.percent_days_seen != null ? `, seen ${anon.percent_days_seen}% of days` : '';
return `IPInfo: anonymous IP${provider} — ${flags.join(', ')}${seen}`;
}
function normalizeCountryCode(value: string | undefined): string | null {
if (!value) {
return null;
}
const normalized = value.trim().toUpperCase();
return /^[A-Z]{2}$/u.test(normalized) ? normalized : null;
}
function normalizeContinentCode(value: string | undefined): string | null {
if (!value) {
return null;
}
const normalized = value.trim().toUpperCase();
return /^[A-Z]{2}$/u.test(normalized) ? normalized : null;
}
function normalizeRegionCode(value: string | undefined): string | null {
if (!value) {
return null;
}
const normalized = value.trim().toUpperCase();
return normalized.length > 0 ? normalized : null;
}
function normalizeCoordinate(value: number | undefined): number | null {
return typeof value === 'number' && Number.isFinite(value) ? value : null;
}
@@ -1,153 +0,0 @@
// SPDX-License-Identifier: AGPL-3.0-or-later
import {randomUUID} from 'node:crypto';
import type {IpInfoCache, IpInfoRequestAuditEvent, IpInfoRequestAuditLogger} from '@pkgs/geoip/src/IpInfoService';
import {type IPostgresClient, quoteIdentifier} from '@pkgs/postgres/src/Client';
interface PostgresIpInfoOptions {
client?: IPostgresClient;
getClient?: () => IPostgresClient;
onError?: (error: unknown, operation: string) => void;
}
const VALUE_SEPARATOR = '\u001f';
export const IPINFO_CACHE_TTL_SECONDS = 14 * 24 * 60 * 60;
export const IPINFO_REQUEST_AUDIT_TTL_SECONDS = 90 * 24 * 60 * 60;
function getClient(options: PostgresIpInfoOptions): IPostgresClient | null {
return options.client ?? options.getClient?.() ?? null;
}
function valueKey(value: unknown): string {
return JSON.stringify(value);
}
function rowKey(values: ReadonlyArray<unknown>): string {
return values.map(valueKey).join(VALUE_SEPARATOR);
}
function table(client: IPostgresClient): string {
return quoteIdentifier(client.kvTable());
}
async function upsertKvRow(
client: IPostgresClient,
tableName: string,
partitionKey: string,
key: string,
row: Record<string, unknown>,
ttlSeconds: number,
): Promise<void> {
const expiresAt = new Date(Date.now() + ttlSeconds * 1000);
await client.query(
`INSERT INTO ${table(client)} (table_name, partition_key, row_key, row_data, expires_at, updated_at)
VALUES ($1, $2, $3, $4::jsonb, $5, now())
ON CONFLICT (table_name, row_key)
DO UPDATE SET partition_key = EXCLUDED.partition_key, row_data = EXCLUDED.row_data, expires_at = EXCLUDED.expires_at, updated_at = now()`,
[tableName, partitionKey, key, JSON.stringify(row), expiresAt],
);
}
export function createPostgresIpInfoCache(options: PostgresIpInfoOptions): IpInfoCache {
return {
async get<T>(key: string): Promise<T | null> {
try {
const client = getClient(options);
if (!client) return null;
const result = await client.query<{row_data: {payload?: string}}>(
`SELECT row_data FROM ${table(client)} WHERE table_name = $1 AND row_key = $2 AND (expires_at IS NULL OR expires_at > now()) LIMIT 1`,
['ipinfo_cache', rowKey([key])],
);
const payload = result.rows[0]?.row_data?.payload;
return typeof payload === 'string' ? (JSON.parse(payload) as T) : null;
} catch (error) {
options.onError?.(error, 'ipinfo_cache_get');
return null;
}
},
async set<T>(key: string, value: T, ttlSeconds?: number): Promise<void> {
let payload: string;
try {
payload = JSON.stringify(value);
} catch (error) {
options.onError?.(error, 'ipinfo_cache_serialize');
return;
}
try {
const client = getClient(options);
if (!client) return;
await upsertKvRow(
client,
'ipinfo_cache',
rowKey([key]),
rowKey([key]),
{cache_key: key, payload},
ttlSeconds != null && Number.isFinite(ttlSeconds) && ttlSeconds > 0 ? ttlSeconds : IPINFO_CACHE_TTL_SECONDS,
);
} catch (error) {
options.onError?.(error, 'ipinfo_cache_set');
}
},
};
}
export function createPostgresIpInfoRequestAuditLogger(options: PostgresIpInfoOptions): IpInfoRequestAuditLogger {
return {
async record(event: IpInfoRequestAuditEvent): Promise<void> {
try {
const client = getClient(options);
if (!client) return;
const bucketDate = formatUtcDate(event.requestedAt);
const bucketHour = event.requestedAt.getUTCHours();
const eventId = randomUUID();
await upsertKvRow(
client,
'ipinfo_requests_by_hour',
rowKey([bucketDate, bucketHour]),
rowKey([bucketDate, bucketHour, event.requestedAt.toISOString(), eventId]),
{
bucket_date: bucketDate,
bucket_hour: bucketHour,
requested_at: event.requestedAt.toISOString(),
event_id: eventId,
source: event.source,
reason: event.reason,
ip: event.ip,
cache_key: event.cacheKey,
request_url: event.requestUrl,
http_status: event.httpStatus,
outcome: event.outcome,
available: event.available,
risk_note: event.note,
latency_ms: event.latencyMs,
response_ip: event.responseIp,
country_code: event.countryCode,
asn: event.asnNumber,
is_anonymous: event.isAnonymous,
is_tor: event.isTor,
is_vpn: event.isVpn,
is_proxy: event.isProxy,
is_residential_proxy: event.isResidentialProxy,
metadata_json: serializeMetadata(event.metadata),
},
IPINFO_REQUEST_AUDIT_TTL_SECONDS,
);
} catch (error) {
options.onError?.(error, 'ipinfo_request_audit_record');
}
},
};
}
function formatUtcDate(value: Date): string {
return value.toISOString().slice(0, 10);
}
function serializeMetadata(metadata: IpInfoRequestAuditEvent['metadata']): string | null {
if (!metadata || Object.keys(metadata).length === 0) return null;
try {
return JSON.stringify(metadata);
} catch {
return null;
}
}
@@ -1,35 +0,0 @@
// SPDX-License-Identifier: AGPL-3.0-or-later
import type {IpInfoCache} from '@pkgs/geoip/src/IpInfoService';
const DEFAULT_HOT_TTL_SECONDS = 10 * 60;
interface TieredIpInfoCacheOptions {
hot: IpInfoCache;
cold: IpInfoCache;
hotTtlSeconds?: number;
skipColdWrite?: (value: unknown) => boolean;
}
export function createTieredIpInfoCache(opts: TieredIpInfoCacheOptions): IpInfoCache {
const hotTtl = opts.hotTtlSeconds ?? DEFAULT_HOT_TTL_SECONDS;
return {
async get<T>(key: string): Promise<T | null> {
const hit = await opts.hot.get<T>(key).catch(() => null);
if (hit !== null) return hit;
const cold = await opts.cold.get<T>(key).catch(() => null);
if (cold === null) return null;
if (opts.skipColdWrite?.(cold) === true) return cold;
void opts.hot.set(key, cold, hotTtl).catch(() => {});
return cold;
},
async set<T>(key: string, value: T, ttlSeconds?: number): Promise<void> {
const effectiveHotTtl = Math.max(1, Math.min(hotTtl, ttlSeconds ?? hotTtl));
const writes: Array<Promise<void>> = [opts.hot.set(key, value, effectiveHotTtl).catch(() => {})];
if (opts.skipColdWrite?.(value) !== true) {
writes.push(opts.cold.set(key, value, ttlSeconds).catch(() => {}));
}
await Promise.all(writes);
},
};
}
-3
View File
@@ -259,9 +259,6 @@ export function buildAPIConfigFromMaster(master: MasterConfig): APIConfig {
}
: undefined,
},
ipinfo: {
apiKey: master.integrations.ipinfo.api_key || undefined,
},
blocklistFeeds: {
enabled: master.integrations.blocklist_feeds.enabled ?? !master.instance.self_hosted,
},
+7 -10
View File
@@ -41,7 +41,6 @@ import type {StoreEntitlementService} from '@app/api/store_billing/StoreEntitlem
import type {UserService} from '@app/api/user/services/UserService';
import type {VoiceRepository} from '@app/api/voice/VoiceRepository';
import type {SendSystemDmResponse} from '@fluxer/schema/src/domains/admin/AdminSchemas';
import type {IpInfoService} from '@pkgs/geoip/src/IpInfoService';
import type Stripe from 'stripe';
export class AdminService {
@@ -81,7 +80,6 @@ export class AdminService {
private readonly applicationRepository: IApplicationRepository,
private readonly stripe: Stripe | null = null,
private readonly jobLedger: IJobLedgerRepository,
private readonly ipInfoService: IpInfoService,
private readonly storeEntitlementService: StoreEntitlementService,
) {
const {users, gateway, worker, snowflake} = this.apiContext.services;
@@ -94,7 +92,6 @@ export class AdminService {
apiContext: this.apiContext,
adminRepository: this.adminRepository,
auditService: this.auditService,
ipInfoService: this.ipInfoService,
});
this.userService = new AdminUserService({
apiContext: this.apiContext,
@@ -181,20 +178,20 @@ export class AdminService {
}
async sendSystemDm(
data: {content: string; userIds: Array<string>},
data: {content: string; recipients: {kind: 'all'} | {kind: 'list'; userIds: Array<string>}},
adminUserId: UserID,
auditLogReason: string | null,
): Promise<SendSystemDmResponse> {
const recipientCount = data.recipients.kind === 'all' ? null : data.recipients.userIds.length;
await this.apiContext.services.worker.addJob(
'sendSystemDm',
{
content: data.content,
user_ids: data.userIds,
},
data.recipients.kind === 'all'
? {content: data.content, all_users: true}
: {content: data.content, user_ids: data.recipients.userIds},
{requireLedger: true},
);
const metadata = new Map<string, string>([
['recipient_count', data.userIds.length.toString()],
['recipient_count', recipientCount === null ? 'all' : recipientCount.toString()],
['content_length', data.content.length.toString()],
]);
await this.auditService.createAuditLog({
@@ -205,6 +202,6 @@ export class AdminService {
auditLogReason,
metadata,
});
return {recipient_count: data.userIds.length};
return {recipient_count: recipientCount};
}
}
@@ -338,7 +338,7 @@ export function BanAdminController(app: HonoApp) {
tags: ['Admin'],
requestSchema: AdminBlocklistEntryCreateRequest,
description:
'Add a value to a blocklist. The request body is the shape the blocklist named by list_type accepts, and the value is validated and canonicalized for that blocklist. Adding an IP address that is on the instance exemption list, or that IPInfo reports as a high blast-radius carrier NAT, is refused with 400 IP_BAN_DECLINED and recorded in the audit log.',
'Add a value to a blocklist. The request body is the shape the blocklist named by list_type accepts, and the value is validated and canonicalized for that blocklist. Adding an IP address that is on the instance exemption list is refused with 400 IP_BAN_DECLINED and recorded in the audit log.',
}),
async (ctx) => {
const adminService = ctx.get('adminService');
@@ -23,7 +23,7 @@ export function SystemDmAdminController(app: HonoApp) {
security: 'adminApiKey',
tags: 'Admin',
description:
'Queue a worker job that delivers the same content to every listed user as a direct message from the system account. Progress is observable through the Jobs admin resource (task_type=sendSystemDm), and an in-flight broadcast is stopped by cancelling that job. Requires SYSTEM_DM_SEND permission.',
'Queue a worker job that delivers the same content to every listed user, or to every user when all_users is set, as a direct message from the system account. Progress is observable through the Jobs admin resource (task_type=sendSystemDm), and an in-flight broadcast is stopped by cancelling that job. Requires SYSTEM_DM_SEND permission.',
}),
async (ctx) => {
const adminService = ctx.get('adminService');
@@ -31,7 +31,12 @@ export function SystemDmAdminController(app: HonoApp) {
const auditLogReason = ctx.get('auditLogReason');
const payload = ctx.req.valid('json');
const result = await adminService.sendSystemDm(
{content: payload.content, userIds: payload.user_ids.map((id) => id.toString())},
{
content: payload.content,
recipients: payload.all_users
? {kind: 'all'}
: {kind: 'list', userIds: (payload.user_ids ?? []).map((id) => id.toString())},
},
adminUserId,
auditLogReason,
);
@@ -4,7 +4,6 @@ import type {ApiContext} from '@app/api/ApiContext';
import type {IAdminRepository} from '@app/api/admin/IAdminRepository';
import type {AdminAuditService} from '@app/api/admin/services/AdminAuditService';
import {createUserID, type UserID} from '@app/api/BrandedTypes';
import {getIpBanBlastRadiusVerdict, isSingleIpBanCandidate} from '@app/api/ban/IpBanCgnatGuard';
import {isIpBanExempt} from '@app/api/ban/IpBanExemptions';
import {
BANNED_AVATAR_HASHES_REFRESH_CHANNEL,
@@ -18,7 +17,6 @@ import {
} from '@app/api/constants/ContentModeration';
import {IP_BAN_REFRESH_CHANNEL} from '@app/api/constants/IpBan';
import type {BannedProfileSubstringScope} from '@app/api/database/types/AdminArchiveTypes';
import {Logger} from '@app/api/Logger';
import {bannedAvatarHashCache} from '@app/api/middleware/BannedAvatarHashCache';
import {fileShaCache} from '@app/api/middleware/FileShaCache';
import {ipBanCache} from '@app/api/middleware/IpBanMiddleware';
@@ -34,13 +32,11 @@ import {InputValidationError} from '@fluxer/errors/src/domains/core/InputValidat
import {NotFoundError} from '@fluxer/errors/src/domains/core/NotFoundError';
import {UnknownUserError} from '@fluxer/errors/src/domains/user/UnknownUserError';
import type {AdminBlocklistListType} from '@fluxer/schema/src/domains/admin/AdminBlocklistSchemas';
import type {IpInfoService} from '@pkgs/geoip/src/IpInfoService';
interface AdminBanManagementServiceDeps {
apiContext: ApiContext;
adminRepository: IAdminRepository;
auditService: AdminAuditService;
ipInfoService: IpInfoService;
}
interface AdminBlocklistEntry {
@@ -146,20 +142,6 @@ export class AdminBanManagementService {
message: 'This IP address is on the instance exemption list',
});
}
if (await this.shouldSkipIpBanForCgnat(data.ip)) {
await auditService.createAuditLog({
adminUserId,
targetType: 'ip',
targetId: BigInt(0),
action: 'ban_ip_skipped_cgnat',
auditLogReason,
metadata: new Map([['ip', data.ip]]),
});
throw new BadRequestError({
code: APIErrorCodes.IP_BAN_DECLINED,
message: 'This IP address is a high blast-radius carrier network',
});
}
await adminRepository.banIp(data.ip);
ipBanCache.ban(data.ip);
await cacheService.publish(IP_BAN_REFRESH_CHANNEL, 'refresh');
@@ -200,25 +182,6 @@ export class AdminBanManagementService {
return {banned};
}
private async shouldSkipIpBanForCgnat(ip: string): Promise<boolean> {
if (!isSingleIpBanCandidate(ip)) {
return false;
}
try {
const {cgnat: highRisk} = await getIpBanBlastRadiusVerdict(ip, this.deps.ipInfoService, {
source: 'admin.ip_ban',
reason: 'pre_write_cgnat_guard',
});
if (highRisk) {
Logger.warn({ip}, 'Skipping IP ban because IPInfo indicates high CGNAT blast-radius risk');
}
return highRisk;
} catch (error) {
Logger.warn({error, ip}, 'IPInfo CGNAT guard failed while adding IP ban');
return false;
}
}
async banEmail(
data: {
email: string;
@@ -1,170 +0,0 @@
// SPDX-License-Identifier: AGPL-3.0-or-later
import type {ApiContext} from '@app/api/ApiContext';
import type {IAdminRepository} from '@app/api/admin/IAdminRepository';
import type {AdminAuditService} from '@app/api/admin/services/AdminAuditService';
import {AdminBanManagementService} from '@app/api/admin/services/AdminBanManagementService';
import {createUserID} from '@app/api/BrandedTypes';
import {resetIpBanExemptionsForTesting} from '@app/api/ban/IpBanExemptions';
import {getConfig} from '@app/api/Config';
import {ipBanCache} from '@app/api/middleware/IpBanMiddleware';
import {APIErrorCodes} from '@fluxer/constants/src/ApiErrorCodes';
import {BadRequestError} from '@fluxer/errors/src/domains/core/BadRequestError';
import type {IpInfoLookupResult, IpInfoService} from '@pkgs/geoip/src/IpInfoService';
import {afterEach, beforeEach, describe, expect, it} from 'vitest';
const ADMIN_ID = createUserID(42n);
const EXEMPT_IP = '10.0.0.1';
const CARRIER_IP = '198.51.100.7';
const LOOKUP_FAILURE_IP = '203.0.113.9';
interface AuditCall {
action: string;
metadata: Map<string, string> | undefined;
}
function ipInfoResult(overrides: Partial<IpInfoLookupResult> = {}): IpInfoLookupResult {
return {
ip: CARRIER_IP,
available: true,
note: 'test',
geo: {
countryCode: 'US',
countryName: 'United States',
continent: 'North America',
continentCode: 'NA',
region: null,
regionCode: null,
city: null,
postalCode: null,
timezone: null,
latitude: null,
longitude: null,
accuracyRadiusKm: null,
},
asn: {
asn: 'AS64500',
number: 64500,
name: 'Test Carrier',
domain: null,
type: null,
},
mobile: {
name: null,
mcc: null,
mnc: null,
},
anonymous: {
isAnonymous: false,
providerName: null,
isVpn: false,
isProxy: false,
isResidentialProxy: false,
isTor: false,
isRelay: false,
percentDaysSeen: null,
},
flags: {
isAnycast: false,
isHosting: false,
isMobile: false,
isSatellite: false,
},
...overrides,
};
}
function createBanManagementService(lookup: (ip: string) => Promise<IpInfoLookupResult>) {
const bannedIps: Array<string> = [];
const auditCalls: Array<AuditCall> = [];
const adminRepository = {
banIp: async (ip: string) => {
bannedIps.push(ip);
},
};
const auditService = {
createAuditLog: async ({action, metadata}: AuditCall) => {
auditCalls.push({action, metadata});
},
};
const ipInfoService = {lookup: (ip: string) => lookup(ip)};
const apiContext = {
services: {
cache: {
publish: async () => {},
},
},
};
const service = new AdminBanManagementService({
apiContext: apiContext as unknown as ApiContext,
adminRepository: adminRepository as unknown as IAdminRepository,
auditService: auditService as unknown as AdminAuditService,
ipInfoService: ipInfoService as unknown as IpInfoService,
});
return {service, bannedIps, auditCalls};
}
describe('AdminBanManagementService banIp guards', () => {
let originalExemptIps: Array<string>;
beforeEach(() => {
const config = getConfig();
originalExemptIps = config.ipBanExemptIps;
config.ipBanExemptIps = [EXEMPT_IP];
resetIpBanExemptionsForTesting();
});
afterEach(() => {
ipBanCache.unban(LOOKUP_FAILURE_IP);
getConfig().ipBanExemptIps = originalExemptIps;
resetIpBanExemptionsForTesting();
});
it('refuses an exempt address with IP_BAN_DECLINED and writes no ban row', async () => {
const {service, bannedIps, auditCalls} = createBanManagementService(async () => ipInfoResult());
const error = await service.banIp({ip: EXEMPT_IP}, ADMIN_ID, null).then(
() => null,
(caught: unknown) => caught,
);
expect(error).toBeInstanceOf(BadRequestError);
expect((error as BadRequestError).code).toBe(APIErrorCodes.IP_BAN_DECLINED);
expect((error as BadRequestError).status).toBe(400);
expect(bannedIps).toEqual([]);
expect(auditCalls.map((call) => call.action)).toEqual(['ban_ip_skipped_exempt']);
expect(auditCalls[0].metadata?.get('ip')).toBe(EXEMPT_IP);
});
it('refuses a high blast-radius carrier address with IP_BAN_DECLINED and writes no ban row', async () => {
const {service, bannedIps, auditCalls} = createBanManagementService(async () =>
ipInfoResult({
mobile: {name: 'Example Mobile', mcc: '001', mnc: '01'},
flags: {isAnycast: false, isHosting: false, isMobile: true, isSatellite: false},
}),
);
const error = await service.banIp({ip: CARRIER_IP}, ADMIN_ID, null).then(
() => null,
(caught: unknown) => caught,
);
expect(error).toBeInstanceOf(BadRequestError);
expect((error as BadRequestError).code).toBe(APIErrorCodes.IP_BAN_DECLINED);
expect((error as BadRequestError).status).toBe(400);
expect(bannedIps).toEqual([]);
expect(auditCalls.map((call) => call.action)).toEqual(['ban_ip_skipped_cgnat']);
expect(auditCalls[0].metadata?.get('ip')).toBe(CARRIER_IP);
});
it('still writes the ban when the IPInfo lookup fails', async () => {
const {service, bannedIps, auditCalls} = createBanManagementService(async () => {
throw new Error('ipinfo is unreachable');
});
await expect(service.banIp({ip: LOOKUP_FAILURE_IP}, ADMIN_ID, null)).resolves.toBeUndefined();
expect(bannedIps).toEqual([LOOKUP_FAILURE_IP]);
expect(auditCalls.map((call) => call.action)).toEqual(['ban_ip']);
});
});
@@ -10,83 +10,24 @@ import {
type TestAccount,
} from '@app/api/auth/tests/AuthTestUtils';
import {createUserID} from '@app/api/BrandedTypes';
import {setInjectedIpInfoService} from '@app/api/middleware/ServiceMiddleware';
import {getAdminRepository} from '@app/api/middleware/ServiceSingletons';
import {type ApiTestHarness, createApiTestHarness} from '@app/api/test/ApiTestHarness';
import {HTTP_STATUS} from '@app/api/test/TestConstants';
import {createBuilder} from '@app/api/test/TestRequestBuilder';
import {UserRepository} from '@app/api/user/repositories/UserRepository';
import {DeletionReasons} from '@fluxer/constants/src/Core';
import type {IpInfoLookupResult} from '@pkgs/geoip/src/IpInfoService';
import {afterEach, beforeEach, describe, expect, test} from 'vitest';
function createUniqueTestIp(): string {
return `198.51.${randomInt(0, 256)}.${randomInt(1, 255)}`;
}
function ipInfoResult(ip: string, overrides: Partial<IpInfoLookupResult> = {}): IpInfoLookupResult {
return {
ip,
available: true,
note: 'test',
geo: {
countryCode: 'US',
countryName: 'United States',
continent: 'North America',
continentCode: 'NA',
region: null,
regionCode: null,
city: null,
postalCode: null,
timezone: null,
latitude: null,
longitude: null,
accuracyRadiusKm: null,
},
asn: {
asn: 'AS64500',
number: 64500,
name: 'Test ISP',
domain: null,
type: null,
},
mobile: {
name: null,
mcc: null,
mnc: null,
},
anonymous: {
isAnonymous: false,
providerName: null,
isVpn: false,
isProxy: false,
isResidentialProxy: false,
isTor: false,
isRelay: false,
percentDaysSeen: null,
},
flags: {
isAnycast: false,
isHosting: false,
isMobile: false,
isSatellite: false,
},
...overrides,
};
}
describe('Admin Deletion Queue', () => {
let harness: ApiTestHarness;
beforeEach(async () => {
harness = await createApiTestHarness();
setInjectedIpInfoService({
async lookup(ip: string) {
return ipInfoResult(ip);
},
});
});
afterEach(async () => {
setInjectedIpInfoService(undefined);
await harness?.shutdown();
});
test('admin scheduling queues deletion and rescheduling replaces the old Cassandra row', async () => {
-80
View File
@@ -1,80 +0,0 @@
// SPDX-License-Identifier: AGPL-3.0-or-later
import {parseIpBanEntry} from '@app/api/utils/IpRangeUtils';
import {getSameIpDecisionKey} from '@fluxer/ip_utils/src/IpAddress';
import type {IpInfoLookupResult, IpInfoService} from '@pkgs/geoip/src/IpInfoService';
const VERDICT_CACHE_TTL_MS = 60 * 60 * 1000;
interface IpBanBlastRadiusVerdict {
cgnat: boolean;
sharedAccess: boolean;
}
interface CachedVerdict {
expiresAtMs: number;
verdict: IpBanBlastRadiusVerdict;
}
const verdictCache = new Map<string, CachedVerdict>();
function isAnonymousAccess(result: IpInfoLookupResult): boolean {
return (
result.anonymous.isAnonymous ||
result.anonymous.isVpn ||
result.anonymous.isProxy ||
result.anonymous.isResidentialProxy ||
result.anonymous.isTor ||
result.anonymous.isRelay
);
}
export function isHighCgnatBlastRadiusRisk(result: IpInfoLookupResult): boolean {
if (!result.available || result.flags.isHosting || isAnonymousAccess(result)) {
return false;
}
const asnType = result.asn.type?.trim().toLowerCase() ?? null;
return result.flags.isMobile || result.mobile.name !== null || asnType === 'mobile';
}
export function isHighSharedAccessBlastRadiusRisk(result: IpInfoLookupResult): boolean {
if (result.flags.isHosting || isAnonymousAccess(result)) {
return false;
}
const asnType = result.asn.type?.trim().toLowerCase() ?? null;
return result.flags.isAnycast || result.flags.isSatellite || asnType === 'education';
}
export function isSingleIpBanCandidate(value: string): boolean {
return parseIpBanEntry(value)?.type === 'single';
}
export async function getIpBanBlastRadiusVerdict(
ip: string,
ipInfoService: IpInfoService,
context: {
source: string;
reason: string;
},
): Promise<IpBanBlastRadiusVerdict> {
const now = Date.now();
const cacheKey = getSameIpDecisionKey(ip) ?? ip;
const cached = verdictCache.get(cacheKey);
if (cached && cached.expiresAtMs > now) {
return cached.verdict;
}
const result = await ipInfoService.lookup(ip, {
source: context.source,
reason: context.reason,
metadata: {policy: 'ip_ban_cgnat_guard'},
});
const verdict: IpBanBlastRadiusVerdict = {
cgnat: isHighCgnatBlastRadiusRisk(result),
sharedAccess: isHighSharedAccessBlastRadiusRisk(result),
};
verdictCache.set(cacheKey, {
verdict,
expiresAtMs: now + VERDICT_CACHE_TTL_MS,
});
return verdict;
}
@@ -1,45 +0,0 @@
// SPDX-License-Identifier: AGPL-3.0-or-later
import {Config} from '@app/api/Config';
import {Logger} from '@app/api/Logger';
import {getDefaultCassandraClient} from '@pkgs/cassandra/src/Client';
import {createCassandraIpInfoCache} from '@pkgs/geoip/src/CassandraIpInfoCache';
import {createCassandraIpInfoRequestAuditLogger} from '@pkgs/geoip/src/CassandraIpInfoRequestAudit';
import {type IpInfoCache, type IpInfoRequestAuditLogger, isCachedIpInfoFailure} from '@pkgs/geoip/src/IpInfoService';
import {createPostgresIpInfoCache, createPostgresIpInfoRequestAuditLogger} from '@pkgs/geoip/src/PostgresIpInfoKv';
import {createTieredIpInfoCache} from '@pkgs/geoip/src/TieredIpInfoCache';
import {getDefaultPostgresClient} from '@pkgs/postgres/src/Client';
interface BuildIpInfoCacheOptions {
hot: IpInfoCache;
}
export function buildIpInfoCache(options: BuildIpInfoCacheOptions): IpInfoCache {
if (Config.database.backend === 'postgres') {
return createTieredIpInfoCache({
hot: options.hot,
cold: createPostgresIpInfoCache({
getClient: getDefaultPostgresClient,
onError: (error, operation) => Logger.warn({error, operation}, 'Postgres IPInfo cache operation failed'),
}),
skipColdWrite: isCachedIpInfoFailure,
});
}
return createTieredIpInfoCache({
hot: options.hot,
cold: createCassandraIpInfoCache({getClient: getDefaultCassandraClient}),
skipColdWrite: isCachedIpInfoFailure,
});
}
export function buildIpInfoRequestAuditLogger(): IpInfoRequestAuditLogger {
if (Config.database.backend === 'postgres') {
return createPostgresIpInfoRequestAuditLogger({
getClient: getDefaultPostgresClient,
onError: (error, operation) => Logger.warn({error, operation}, 'Postgres IPInfo audit operation failed'),
});
}
return createCassandraIpInfoRequestAuditLogger({
getClient: getDefaultCassandraClient,
});
}
@@ -1,162 +0,0 @@
// SPDX-License-Identifier: AGPL-3.0-or-later
import {
isHighCgnatBlastRadiusRisk,
isHighSharedAccessBlastRadiusRisk,
isSingleIpBanCandidate,
} from '@app/api/ban/IpBanCgnatGuard';
import type {IpInfoLookupResult} from '@pkgs/geoip/src/IpInfoService';
import {describe, expect, it} from 'vitest';
function ipInfoResult(overrides: Partial<IpInfoLookupResult> = {}): IpInfoLookupResult {
return {
ip: '198.51.100.1',
available: true,
note: 'test',
geo: {
countryCode: 'US',
countryName: 'United States',
continent: 'North America',
continentCode: 'NA',
region: null,
regionCode: null,
city: null,
postalCode: null,
timezone: null,
latitude: null,
longitude: null,
accuracyRadiusKm: null,
},
asn: {
asn: 'AS64500',
number: 64500,
name: 'Test ISP',
domain: null,
type: null,
},
mobile: {
name: null,
mcc: null,
mnc: null,
},
anonymous: {
isAnonymous: false,
providerName: null,
isVpn: false,
isProxy: false,
isResidentialProxy: false,
isTor: false,
isRelay: false,
percentDaysSeen: null,
},
flags: {
isAnycast: false,
isHosting: false,
isMobile: false,
isSatellite: false,
},
...overrides,
};
}
describe('IpBanCgnatGuard', () => {
it('only treats single IP ban entries as CGNAT guard candidates', () => {
expect(isSingleIpBanCandidate('198.51.100.10')).toBe(true);
expect(isSingleIpBanCandidate('198.51.100.0/24')).toBe(false);
});
it('flags mobile carrier IPs as high blast-radius risk', () => {
expect(
isHighCgnatBlastRadiusRisk(
ipInfoResult({
mobile: {name: 'Example Mobile', mcc: '001', mnc: '01'},
flags: {isAnycast: false, isHosting: false, isMobile: true, isSatellite: false},
}),
),
).toBe(true);
});
it('does not exempt hosting or anonymous infrastructure', () => {
expect(
isHighCgnatBlastRadiusRisk(
ipInfoResult({
flags: {isAnycast: false, isHosting: true, isMobile: true, isSatellite: false},
}),
),
).toBe(false);
expect(
isHighCgnatBlastRadiusRisk(
ipInfoResult({
anonymous: {
isAnonymous: true,
providerName: 'Example VPN',
isVpn: true,
isProxy: false,
isResidentialProxy: false,
isTor: false,
isRelay: false,
percentDaysSeen: null,
},
flags: {isAnycast: false, isHosting: false, isMobile: true, isSatellite: false},
}),
),
).toBe(false);
});
it('flags satellite, anycast and education networks as high blast-radius risk', () => {
expect(
isHighSharedAccessBlastRadiusRisk(
ipInfoResult({
flags: {isAnycast: false, isHosting: false, isMobile: false, isSatellite: true},
}),
),
).toBe(true);
expect(
isHighSharedAccessBlastRadiusRisk(
ipInfoResult({
flags: {isAnycast: true, isHosting: false, isMobile: false, isSatellite: false},
}),
),
).toBe(true);
expect(
isHighSharedAccessBlastRadiusRisk(
ipInfoResult({asn: {asn: 'AS64500', number: 64500, name: 'Test University', domain: null, type: 'education'}}),
),
).toBe(true);
});
it('does not flag ordinary residential networks as shared-access risk', () => {
expect(isHighSharedAccessBlastRadiusRisk(ipInfoResult())).toBe(false);
});
it('does not treat shared-access networks as CGNAT risk', () => {
expect(
isHighCgnatBlastRadiusRisk(
ipInfoResult({
flags: {isAnycast: false, isHosting: false, isMobile: false, isSatellite: true},
}),
),
).toBe(false);
});
it('does not exempt hosting or anonymous shared-access infrastructure', () => {
expect(
isHighSharedAccessBlastRadiusRisk(
ipInfoResult({
flags: {isAnycast: true, isHosting: true, isMobile: false, isSatellite: false},
}),
),
).toBe(false);
expect(
isHighSharedAccessBlastRadiusRisk(
ipInfoResult({
anonymous: {
isAnonymous: true,
providerName: 'Example VPN',
isVpn: true,
isProxy: false,
isResidentialProxy: false,
isTor: false,
isRelay: false,
percentDaysSeen: null,
},
flags: {isAnycast: false, isHosting: false, isMobile: false, isSatellite: true},
}),
),
).toBe(false);
});
});
@@ -1,210 +0,0 @@
// SPDX-License-Identifier: AGPL-3.0-or-later
import {server} from '@app/api/test/msw/server';
import type {
CachedIpInfoFailure,
IpInfoCache,
IpInfoRequestAuditEvent,
IpInfoRequestAuditLogger,
} from '@pkgs/geoip/src/IpInfoService';
import {createIpInfoService} from '@pkgs/geoip/src/IpInfoService';
import {delay, HttpResponse, http} from 'msw';
import {describe, expect, it} from 'vitest';
interface RecordedSet {
key: string;
value: unknown;
ttlSeconds: number | undefined;
}
interface RecordingCache {
cache: IpInfoCache;
sets: Array<RecordedSet>;
}
function createRecordingCache(): RecordingCache {
const store = new Map<string, unknown>();
const sets: Array<RecordedSet> = [];
return {
sets,
cache: {
async get<T>(key: string): Promise<T | null> {
return (store.get(key) as T | undefined) ?? null;
},
async set<T>(key: string, value: T, ttlSeconds?: number): Promise<void> {
store.set(key, value);
sets.push({key, value, ttlSeconds});
},
},
};
}
function createRecordingAuditLogger(): {logger: IpInfoRequestAuditLogger; events: Array<IpInfoRequestAuditEvent>} {
const events: Array<IpInfoRequestAuditEvent> = [];
return {
events,
logger: {
async record(event: IpInfoRequestAuditEvent): Promise<void> {
events.push(event);
},
},
};
}
function useLookupHandler(handler: () => Response | Promise<Response>): {count: () => number} {
let calls = 0;
server.use(
http.get('https://api.ipinfo.io/lookup/:ip', async () => {
calls += 1;
return await handler();
}),
);
return {count: () => calls};
}
function successPayload(ip: string, anonymous: Record<string, boolean> = {}): Response {
return HttpResponse.json({
ip,
geo: {country_code: 'US', country: 'United States'},
as: {asn: 'AS64500', name: 'Test ISP'},
anonymous,
});
}
describe('IpInfoService caching', () => {
it('negative-caches an HTTP error and serves the second lookup without a request', async () => {
const requests = useLookupHandler(() => new HttpResponse(null, {status: 500}));
const {cache, sets} = createRecordingCache();
const service = createIpInfoService({apiKey: 'token', cache});
const first = await service.lookup('203.0.113.1');
const second = await service.lookup('203.0.113.1');
expect(first.available).toBe(false);
expect(second.available).toBe(false);
expect(requests.count()).toBe(1);
expect(sets).toHaveLength(1);
expect(sets[0]?.ttlSeconds).toBe(300);
});
it('negative-caches a request failure for a short window', async () => {
useLookupHandler(async () => {
await delay(5000);
return successPayload('203.0.113.2');
});
const {cache, sets} = createRecordingCache();
const service = createIpInfoService({apiKey: 'token', cache});
const result = await service.lookup('203.0.113.2');
expect(result.available).toBe(false);
expect(sets[0]?.ttlSeconds).toBe(60);
expect((sets[0]?.value as CachedIpInfoFailure)?.failureOutcome).toBe('request_failed');
});
it('negative-caches a schema mismatch', async () => {
useLookupHandler(() => HttpResponse.json({}));
const {cache, sets} = createRecordingCache();
const service = createIpInfoService({apiKey: 'token', cache});
const result = await service.lookup('203.0.113.3');
expect(result.available).toBe(false);
expect(sets[0]?.ttlSeconds).toBe(600);
expect((sets[0]?.value as CachedIpInfoFailure)?.failureOutcome).toBe('schema_mismatch');
expect((sets[0]?.value as CachedIpInfoFailure)?.failureHttpStatus).toBe(200);
});
it('negative-caches a quota rejection for longer', async () => {
useLookupHandler(() => new HttpResponse(null, {status: 429}));
const {cache, sets} = createRecordingCache();
const service = createIpInfoService({apiKey: 'token', cache});
await service.lookup('203.0.113.4');
expect(sets[0]?.ttlSeconds).toBe(900);
});
it('returns a cached failure as a clean unavailable result', async () => {
useLookupHandler(() => new HttpResponse(null, {status: 500}));
const {cache} = createRecordingCache();
const service = createIpInfoService({apiKey: 'token', cache});
await service.lookup('203.0.113.6');
const cached = await service.lookup('203.0.113.6');
expect(cached).not.toHaveProperty('cachedFailure');
expect(cached).not.toHaveProperty('failureOutcome');
expect(cached).not.toHaveProperty('failureHttpStatus');
expect(cached).not.toHaveProperty('cachedAtMs');
expect(cached.ip).toBe('203.0.113.6');
expect(cached.note).toBe('IPInfo HTTP 500');
});
it('writes a cached failure that older readers can still consume', async () => {
useLookupHandler(() => new HttpResponse(null, {status: 500}));
const {cache, sets} = createRecordingCache();
const service = createIpInfoService({apiKey: 'token', cache});
await service.lookup('203.0.113.7');
const entry = sets[0]?.value as CachedIpInfoFailure;
expect(entry.cachedFailure).toBe(true);
expect(entry.failureOutcome).toBe('http_error');
expect(entry.failureHttpStatus).toBe(500);
expect(typeof entry.cachedAtMs).toBe('number');
const legacyView = {...entry, ip: '203.0.113.7'};
expect(legacyView.available).toBe(false);
expect(legacyView.geo.countryCode).toBeNull();
expect(legacyView.asn.number).toBeNull();
expect(legacyView.mobile.name).toBeNull();
expect(legacyView.anonymous.isAnonymous).toBe(false);
expect(legacyView.flags.isMobile).toBe(false);
});
it('keeps the existing success TTL selection', async () => {
useLookupHandler(() => successPayload('203.0.113.8'));
const plain = createRecordingCache();
await createIpInfoService({apiKey: 'token', cache: plain.cache}).lookup('203.0.113.8');
useLookupHandler(() => successPayload('203.0.113.9', {is_vpn: true}));
const anonymous = createRecordingCache();
await createIpInfoService({apiKey: 'token', cache: anonymous.cache}).lookup('203.0.113.9');
expect(plain.sets[0]?.ttlSeconds).toBe(14 * 24 * 60 * 60);
expect(anonymous.sets[0]?.ttlSeconds).toBe(7 * 24 * 60 * 60);
});
it('coalesces concurrent lookups across a failure', async () => {
const requests = useLookupHandler(() => new HttpResponse(null, {status: 500}));
const {cache, sets} = createRecordingCache();
const service = createIpInfoService({apiKey: 'token', cache});
const [first, second] = await Promise.all([service.lookup('203.0.113.10'), service.lookup('203.0.113.10')]);
expect(requests.count()).toBe(1);
expect(sets).toHaveLength(1);
expect(first.available).toBe(false);
expect(second.available).toBe(false);
});
it('coalesces concurrent lookups from different sources into one audited request', async () => {
const requests = useLookupHandler(() => successPayload('203.0.113.13'));
const {cache} = createRecordingCache();
const {logger, events} = createRecordingAuditLogger();
const service = createIpInfoService({apiKey: 'token', cache, auditLogger: logger});
const results = await Promise.all([
service.lookup('203.0.113.13', {source: 'admin.ip_ban', reason: 'ban'}),
service.lookup('203.0.113.13', {source: 'test.b'}),
service.lookup('203.0.113.13', {source: 'test.c'}),
]);
expect(requests.count()).toBe(1);
expect(results.every((result) => result.available)).toBe(true);
expect(events).toHaveLength(1);
expect(events[0]?.source).toBe('admin.ip_ban');
expect(events[0]?.outcome).toBe('http_success');
expect(events[0]?.note).toBe('IPInfo: IP is not anonymous');
});
});
@@ -1,75 +0,0 @@
// SPDX-License-Identifier: AGPL-3.0-or-later
import type {IpInfoRequestAuditEvent} from '@pkgs/geoip/src/IpInfoService';
import {
createPostgresIpInfoCache,
createPostgresIpInfoRequestAuditLogger,
IPINFO_CACHE_TTL_SECONDS,
IPINFO_REQUEST_AUDIT_TTL_SECONDS,
} from '@pkgs/geoip/src/PostgresIpInfoKv';
import type {IPostgresClient} from '@pkgs/postgres/src/Client';
import {describe, expect, it} from 'vitest';
function recordingClient(writes: Array<Array<unknown>>): IPostgresClient {
return {
async query(_text: string, values?: Array<unknown>) {
writes.push(values ?? []);
return {rows: [], rowCount: 1};
},
kvTable() {
return 'kv';
},
} as never;
}
function expectExpiresIn(values: Array<unknown> | undefined, ttlSeconds: number): void {
const expiresAt = values?.[4];
expect(expiresAt).toBeInstanceOf(Date);
const remainingSeconds = ((expiresAt as Date).getTime() - Date.now()) / 1000;
expect(remainingSeconds).toBeGreaterThan(ttlSeconds - 10);
expect(remainingSeconds).toBeLessThanOrEqual(ttlSeconds);
}
const EVENT: IpInfoRequestAuditEvent = {
requestedAt: new Date('2026-09-21T12:00:00.000Z'),
ip: '192.0.2.1',
cacheKey: 'ip:192.0.2.1',
source: 'test',
reason: null,
outcome: 'http_success',
httpStatus: 200,
available: true,
note: 'none',
latencyMs: 12,
requestUrl: 'https://ipinfo.test/192.0.2.1',
responseIp: '192.0.2.1',
countryCode: 'SE',
asnNumber: 64500,
isAnonymous: false,
isTor: false,
isVpn: false,
isProxy: false,
isResidentialProxy: false,
};
describe('Postgres ipinfo KV expiry', () => {
it('expires request audit rows after 90 days', async () => {
const writes: Array<Array<unknown>> = [];
await createPostgresIpInfoRequestAuditLogger({client: recordingClient(writes)}).record(EVENT);
expect(writes).toHaveLength(1);
expect(writes[0]?.[0]).toBe('ipinfo_requests_by_hour');
expectExpiresIn(writes[0], IPINFO_REQUEST_AUDIT_TTL_SECONDS);
});
it('falls back to the 14-day cache default', async () => {
const writes: Array<Array<unknown>> = [];
const cache = createPostgresIpInfoCache({client: recordingClient(writes)});
await cache.set('fallback', {ok: true});
await cache.set('zero', {ok: true}, 0);
await cache.set('short', {ok: true}, 60);
expect(writes.map((values) => values[0])).toEqual(['ipinfo_cache', 'ipinfo_cache', 'ipinfo_cache']);
expectExpiresIn(writes[0], IPINFO_CACHE_TTL_SECONDS);
expectExpiresIn(writes[1], IPINFO_CACHE_TTL_SECONDS);
expectExpiresIn(writes[2], 60);
});
});
@@ -1,130 +0,0 @@
// SPDX-License-Identifier: AGPL-3.0-or-later
import type {IpInfoCache} from '@pkgs/geoip/src/IpInfoService';
import {createTieredIpInfoCache} from '@pkgs/geoip/src/TieredIpInfoCache';
import {describe, expect, it} from 'vitest';
interface RecordedSet {
key: string;
value: unknown;
ttlSeconds: number | undefined;
}
interface RecordingCache {
cache: IpInfoCache;
store: Map<string, unknown>;
sets: Array<RecordedSet>;
}
function createRecordingCache(): RecordingCache {
const store = new Map<string, unknown>();
const sets: Array<RecordedSet> = [];
return {
store,
sets,
cache: {
async get<T>(key: string): Promise<T | null> {
return (store.get(key) as T | undefined) ?? null;
},
async set<T>(key: string, value: T, ttlSeconds?: number): Promise<void> {
store.set(key, value);
sets.push({key, value, ttlSeconds});
},
},
};
}
describe('TieredIpInfoCache', () => {
it('clamps the hot TTL to the requested TTL and passes the raw TTL to the cold tier', async () => {
const hot = createRecordingCache();
const cold = createRecordingCache();
const tiered = createTieredIpInfoCache({hot: hot.cache, cold: cold.cache});
await tiered.set('a', {available: false}, 60);
expect(hot.sets).toEqual([{key: 'a', value: {available: false}, ttlSeconds: 60}]);
expect(cold.sets).toEqual([{key: 'a', value: {available: false}, ttlSeconds: 60}]);
});
it('caps the hot TTL at the configured hot window', async () => {
const hot = createRecordingCache();
const cold = createRecordingCache();
const tiered = createTieredIpInfoCache({hot: hot.cache, cold: cold.cache});
await tiered.set('a', {available: true}, 100000);
expect(hot.sets[0]?.ttlSeconds).toBe(600);
expect(cold.sets[0]?.ttlSeconds).toBe(100000);
});
it('uses the hot window when no TTL is supplied', async () => {
const hot = createRecordingCache();
const cold = createRecordingCache();
const tiered = createTieredIpInfoCache({hot: hot.cache, cold: cold.cache});
await tiered.set('a', {available: true});
expect(hot.sets[0]?.ttlSeconds).toBe(600);
expect(cold.sets[0]?.ttlSeconds).toBeUndefined();
});
it('skips the cold write when skipColdWrite matches', async () => {
const hot = createRecordingCache();
const cold = createRecordingCache();
const tiered = createTieredIpInfoCache({
hot: hot.cache,
cold: cold.cache,
skipColdWrite: (value) => (value as {available?: unknown}).available === false,
});
await tiered.set('a', {available: false}, 60);
await tiered.set('b', {available: true}, 60);
expect(hot.sets.map((entry) => entry.key)).toEqual(['a', 'b']);
expect(cold.sets.map((entry) => entry.key)).toEqual(['b']);
});
it('promotes a cold hit into the hot tier', async () => {
const hot = createRecordingCache();
const cold = createRecordingCache();
cold.store.set('a', {available: true});
const tiered = createTieredIpInfoCache({hot: hot.cache, cold: cold.cache});
const hit = await tiered.get('a');
expect(hit).toEqual({available: true});
expect(hot.sets).toEqual([{key: 'a', value: {available: true}, ttlSeconds: 600}]);
});
it('never promotes a cold hit that skipColdWrite matches', async () => {
const hot = createRecordingCache();
const cold = createRecordingCache();
cold.store.set('a', {available: false});
const tiered = createTieredIpInfoCache({
hot: hot.cache,
cold: cold.cache,
skipColdWrite: (value) => (value as {available?: unknown}).available === false,
});
const hit = await tiered.get('a');
expect(hit).toEqual({available: false});
expect(hot.sets).toEqual([]);
});
it('never writes a zero TTL', async () => {
const hot = createRecordingCache();
const cold = createRecordingCache();
const tiered = createTieredIpInfoCache({hot: hot.cache, cold: cold.cache});
await tiered.set('a', {available: false}, 60);
await tiered.set('b', {available: true}, 100000);
await tiered.set('c', {available: true});
cold.store.set('d', {available: true});
await tiered.get('d');
for (const entry of [...hot.sets, ...cold.sets]) {
expect(entry.ttlSeconds === undefined || entry.ttlSeconds > 0).toBe(true);
}
});
});
-3
View File
@@ -164,9 +164,6 @@ export interface APIConfig {
secure: boolean;
};
};
ipinfo: {
apiKey?: string;
};
blocklistFeeds: {
enabled: boolean;
};
@@ -6,7 +6,6 @@ import {fileURLToPath} from 'node:url';
import {DEFAULT_TTL_TABLES} from '@app/api/database/PostgresKvDefaultTtlExpiry';
import * as DonationTables from '@app/api/donation/DonationTables';
import * as Tables from '@app/api/Tables';
import {IPINFO_CACHE_TTL_SECONDS, IPINFO_REQUEST_AUDIT_TTL_SECONDS} from '@pkgs/geoip/src/PostgresIpInfoKv';
import {describe, expect, it} from 'vitest';
const THIS_DIR = path.dirname(fileURLToPath(import.meta.url));
@@ -32,8 +31,6 @@ const DSL_TABLES = [...Object.values(Tables), ...Object.values(DonationTables)];
const DSL_NAMES = new Set<string>(DSL_TABLES.map((table) => table.name));
const NON_DSL_DEFAULTS: Record<string, number | null> = {
ipinfo_cache: IPINFO_CACHE_TTL_SECONDS,
ipinfo_requests_by_hour: IPINFO_REQUEST_AUDIT_TTL_SECONDS,
billing_webhook_events: null,
forensic_identifier_by_key_day: null,
forensic_identifier_by_request: null,
@@ -333,7 +333,7 @@ RETURNING updated_at::text`,
await seed('attachment_upload_traces_by_key', 'at-29', '29 days');
await seed('oauth2_access_tokens', 'oa-8', '8 days');
await seed('donor_magic_link_tokens', 'dm-hour', '1 hour');
await seed('ipinfo_requests_by_hour', 'ip-day', '1 day');
await seed('push_subscriptions', 'ps-day', '1 day');
await seed('jobs_by_id', 'job', '100 days');
await seed('users', 'user', '100 days');
await seed('recent_mentions', 'rm-forever', '1 day', 'infinity');
@@ -346,8 +346,8 @@ RETURNING updated_at::text`,
});
expect(await remaining()).toEqual([
{table_name: 'attachment_upload_traces_by_key', row_key: 'at-29'},
{table_name: 'ipinfo_requests_by_hour', row_key: 'ip-day'},
{table_name: 'jobs_by_id', row_key: 'job'},
{table_name: 'push_subscriptions', row_key: 'ps-day'},
{table_name: 'recent_mentions', row_key: 'rm-day'},
{table_name: 'recent_mentions', row_key: 'rm-forever'},
{table_name: 'recent_mentions', row_key: 'rm-hour'},
@@ -359,13 +359,13 @@ RETURNING updated_at::text`,
expires_at = updated_at + CASE table_name WHEN 'recent_mentions' THEN interval '7 days' WHEN 'attachment_upload_traces_by_key' THEN interval '30 days' ELSE interval '90 days' END AS exact,
CASE WHEN row_key = 'rm-day' THEN updated_at = $1::timestamptz END AS unchanged
FROM ${KV_TABLE}
WHERE row_key IN ('rm-day', 'at-29', 'ip-day')
WHERE row_key IN ('rm-day', 'at-29', 'ps-day')
ORDER BY row_key`,
[mentionWrittenAt],
);
expect(exact.rows).toEqual([
{row_key: 'at-29', exact: true, unchanged: null},
{row_key: 'ip-day', exact: true, unchanged: null},
{row_key: 'ps-day', exact: true, unchanged: null},
{row_key: 'rm-day', exact: true, unchanged: true},
]);
const untouched = await raw.query<{row_key: string; state: string}>(
@@ -449,18 +449,18 @@ FROM generate_series(1, 2300) g`,
});
it('saves where a run stopped and starts the next run there', async () => {
const first = DEFAULT_TTL_TABLES[0]!.name;
const last = DEFAULT_TTL_TABLES.at(-1)!.name;
await seed(first, 'a', '1 hour');
await seed(first, 'z', '1 hour');
await seed(last, 'k', '1 hour');
const first = DEFAULT_TTL_TABLES[0]!;
const last = DEFAULT_TTL_TABLES.at(-1)!;
await seed(first.name, 'a', `${first.defaultTtlSeconds / 2} seconds`);
await seed(first.name, 'z', `${first.defaultTtlSeconds / 2} seconds`);
await seed(last.name, 'k', `${last.defaultTtlSeconds / 2} seconds`);
expect(await expireLegacyDefaultTtlRows(raw, Date.now() - 1)).toEqual({deleted: 0, expiring: 0, complete: false});
expect(await resumePoint()).toEqual({table: first, row_key: '', unset: 0});
expect(await resumePoint()).toEqual({table: first.name, row_key: '', unset: 0});
await raw.query(
`UPDATE ${KV_TABLE} SET row_data = jsonb_build_object('table', $1::text, 'row_key', 'm', 'unset', 0) WHERE table_name = '__fluxer_schema_migrations' AND row_key = $2`,
[first, DEFAULT_TTL_EXPIRY_RESUME],
[first.name, DEFAULT_TTL_EXPIRY_RESUME],
);
expect(await expireLegacyDefaultTtlRows(raw, Date.now() + 60_000)).toEqual({
deleted: 0,
@@ -469,7 +469,7 @@ FROM generate_series(1, 2300) g`,
});
const untouched = await raw.query<{expires_at: Date | null}>(
`SELECT expires_at FROM ${KV_TABLE} WHERE table_name = $1 AND row_key = 'a'`,
[first],
[first.name],
);
expect(untouched.rows).toEqual([{expires_at: null}]);
expect(await resumePoint()).toBeNull();
@@ -7,7 +7,6 @@ import {
} from '@app/api/database/PostgresKvQueryExecutor';
import * as DonationTables from '@app/api/donation/DonationTables';
import * as Tables from '@app/api/Tables';
import {IPINFO_CACHE_TTL_SECONDS, IPINFO_REQUEST_AUDIT_TTL_SECONDS} from '@pkgs/geoip/src/PostgresIpInfoKv';
import {type IPostgresClient, quoteIdentifier} from '@pkgs/postgres/src/Client';
import {ms} from 'itty-time';
@@ -23,8 +22,6 @@ export const DEFAULT_TTL_TABLES: ReadonlyArray<{name: string; defaultTtlSeconds:
? []
: [{name: table.name, defaultTtlSeconds: table.defaultTtlSeconds}],
),
{name: 'ipinfo_cache', defaultTtlSeconds: IPINFO_CACHE_TTL_SECONDS},
{name: 'ipinfo_requests_by_hour', defaultTtlSeconds: IPINFO_REQUEST_AUDIT_TTL_SECONDS},
];
export interface LegacyDefaultTtlExpiryResult {
@@ -24,7 +24,6 @@ import type {JoinSourceType} from '@fluxer/constants/src/GuildConstants';
import {UnknownGuildMemberError} from '@fluxer/errors/src/domains/guild/UnknownGuildMemberError';
import type {GuildMemberResponse} from '@fluxer/schema/src/domains/guild/GuildMemberSchemas';
import type {GuildMemberUpdateRequest} from '@fluxer/schema/src/domains/guild/GuildRequestSchemas';
import type {IpInfoService} from '@pkgs/geoip/src/IpInfoService';
import type {IRateLimitService} from '@pkgs/rate_limit/src/IRateLimitService';
export class GuildMemberService {
@@ -47,11 +46,10 @@ export class GuildMemberService {
rateLimitService: IRateLimitService,
private readonly guildAuditLogService: GuildAuditLogService,
limitConfigService: LimitConfigService,
ipInfoService: IpInfoService,
) {
this.userRepository = userRepository;
this.authService = new GuildMemberAuthService(gatewayService, userRepository);
this.validationService = new GuildMemberValidationService(guildRepository, userRepository, ipInfoService);
this.validationService = new GuildMemberValidationService(guildRepository, userRepository);
this.auditService = new GuildMemberAuditService(guildAuditLogService);
this.eventService = new GuildMemberEventService(gatewayService, userCacheService);
this.searchIndexService = new GuildMemberSearchIndexService();
@@ -1,7 +1,6 @@
// SPDX-License-Identifier: AGPL-3.0-or-later
import type {GuildID, UserID} from '@app/api/BrandedTypes';
import {getIpBanBlastRadiusVerdict, isSingleIpBanCandidate} from '@app/api/ban/IpBanCgnatGuard';
import {isIpBanExempt} from '@app/api/ban/IpBanExemptions';
import type {GuildAuditLogService} from '@app/api/guild/GuildAuditLogService';
import type {GuildAuditLogChange} from '@app/api/guild/GuildAuditLogTypes';
@@ -27,7 +26,6 @@ import {UnknownGuildMemberError} from '@fluxer/errors/src/domains/guild/UnknownG
import {UnknownUserError} from '@fluxer/errors/src/domains/user/UnknownUserError';
import {isSameIpDecisionMatch} from '@fluxer/ip_utils/src/IpAddress';
import type {GuildBanResponse} from '@fluxer/schema/src/domains/guild/GuildMemberSchemas';
import type {IpInfoService} from '@pkgs/geoip/src/IpInfoService';
import type {IWorkerService} from '@pkgs/worker/src/contracts/IWorkerService';
const SECONDS_PER_DAY = 86_400;
@@ -42,7 +40,6 @@ export class GuildModerationService {
private readonly userCacheService: UserCacheService,
private readonly workerService: IWorkerService<WorkerTaskName>,
private readonly guildAuditLogService: GuildAuditLogService,
private readonly ipInfoService: IpInfoService,
) {
this.searchIndexService = new GuildMemberSearchIndexService();
}
@@ -218,7 +215,7 @@ export class GuildModerationService {
const userEmail = user?.email?.toLowerCase();
for (const ban of bans) {
if (ban.userId === userId) throw new BannedFromGuildError();
if (isSameIpDecisionMatch(userIp, ban.ipAddress) && (await this.shouldEnforceIpBan(userIp, ban.ipAddress))) {
if (isSameIpDecisionMatch(userIp, ban.ipAddress) && !isIpBanExempt(userIp)) {
throw new IpBannedFromGuildError();
}
}
@@ -228,35 +225,6 @@ export class GuildModerationService {
}
}
private async shouldEnforceIpBan(
userIp: string | null | undefined,
bannedIp: string | null | undefined,
): Promise<boolean> {
if (isIpBanExempt(userIp)) {
return false;
}
if (!userIp || !bannedIp || !isSingleIpBanCandidate(bannedIp)) {
return true;
}
try {
const {cgnat, sharedAccess} = await getIpBanBlastRadiusVerdict(userIp, this.ipInfoService, {
source: 'guild.ip_ban',
reason: 'join_cgnat_guard',
});
const highRisk = cgnat || sharedAccess;
if (highRisk) {
Logger.warn(
{userIp, bannedIp},
'Skipping guild IP ban match because IPInfo indicates high shared-network blast-radius risk',
);
}
return !highRisk;
} catch (error) {
Logger.warn({error, userIp, bannedIp}, 'IPInfo blast-radius guard failed while checking guild IP ban');
return true;
}
}
private serializeBanForAudit(ban: GuildBan): Record<string, unknown> {
return {
user_id: ban.userId.toString(),
@@ -58,7 +58,6 @@ import type {
import type {GuildUpdateRequest} from '@fluxer/schema/src/domains/guild/GuildRequestSchemas';
import type {GuildResponse} from '@fluxer/schema/src/domains/guild/GuildResponseSchemas';
import type {ICacheService} from '@pkgs/cache/src/ICacheService';
import type {IpInfoService} from '@pkgs/geoip/src/IpInfoService';
interface StoredAuditLogWebhookResponse extends Omit<AuditLogWebhookResponse, 'type'> {
type: number;
@@ -113,7 +112,6 @@ export class GuildService {
webhookRepository: IWebhookRepository,
guildAuditLogService: GuildAuditLogService,
limitConfigService: LimitConfigService,
ipInfoService: IpInfoService,
) {
const {
cache: cacheService,
@@ -153,7 +151,6 @@ export class GuildService {
rateLimitService,
guildAuditLogService,
limitConfigService,
ipInfoService,
);
this.roles = new GuildRoleService(
guildRepository,
@@ -171,7 +168,6 @@ export class GuildService {
userCacheService,
workerService,
guildAuditLogService,
ipInfoService,
);
this.content = new GuildContentService(
guildRepository,
@@ -2,10 +2,8 @@
import type {GuildID, RoleID, UserID} from '@app/api/BrandedTypes';
import {guildIdToRoleId} from '@app/api/BrandedTypes';
import {getIpBanBlastRadiusVerdict, isSingleIpBanCandidate} from '@app/api/ban/IpBanCgnatGuard';
import {isIpBanExempt} from '@app/api/ban/IpBanExemptions';
import type {IGuildRepositoryAggregate} from '@app/api/guild/repositories/IGuildRepositoryAggregate';
import {Logger} from '@app/api/Logger';
import type {GuildMember} from '@app/api/models/GuildMember';
import type {IUserRepository} from '@app/api/user/IUserRepository';
import {Permissions} from '@fluxer/constants/src/ChannelConstants';
@@ -17,7 +15,6 @@ import {IpBannedFromGuildError} from '@fluxer/errors/src/domains/guild/IpBannedF
import {UnknownGuildRoleError} from '@fluxer/errors/src/domains/guild/UnknownGuildRoleError';
import {isSameIpDecisionMatch} from '@fluxer/ip_utils/src/IpAddress';
import type {GuildResponse} from '@fluxer/schema/src/domains/guild/GuildResponseSchemas';
import type {IpInfoService} from '@pkgs/geoip/src/IpInfoService';
function ensureNotEveryoneRole(roleId: RoleID, guildId: GuildID, path: string): void {
if (roleId === guildIdToRoleId(guildId)) {
@@ -29,7 +26,6 @@ export class GuildMemberValidationService {
constructor(
private readonly guildRepository: IGuildRepositoryAggregate,
private readonly userRepository: IUserRepository,
private readonly ipInfoService: IpInfoService,
) {}
async validateAndGetRoleIds(params: {
@@ -102,38 +98,9 @@ export class GuildMemberValidationService {
if (ban.userId === userId) {
throw new BannedFromGuildError();
}
if (isSameIpDecisionMatch(userIp, ban.ipAddress) && (await this.shouldEnforceIpBan(userIp, ban.ipAddress))) {
if (isSameIpDecisionMatch(userIp, ban.ipAddress) && !isIpBanExempt(userIp)) {
throw new IpBannedFromGuildError();
}
}
}
private async shouldEnforceIpBan(
userIp: string | null | undefined,
bannedIp: string | null | undefined,
): Promise<boolean> {
if (isIpBanExempt(userIp)) {
return false;
}
if (!userIp || !bannedIp || !isSingleIpBanCandidate(bannedIp)) {
return true;
}
try {
const {cgnat, sharedAccess} = await getIpBanBlastRadiusVerdict(userIp, this.ipInfoService, {
source: 'guild.member_ip_ban',
reason: 'join_cgnat_guard',
});
const highRisk = cgnat || sharedAccess;
if (highRisk) {
Logger.warn(
{userIp, bannedIp},
'Skipping guild member IP ban match because IPInfo indicates high shared-network blast-radius risk',
);
}
return !highRisk;
} catch (error) {
Logger.warn({error, userIp, bannedIp}, 'IPInfo CGNAT guard failed while checking guild member IP ban');
return true;
}
}
}
@@ -2,6 +2,7 @@
export const GatewayRpcMethodErrorCodes = {
OVERLOADED: 'overloaded',
GUILD_OVERLOADED: 'guild_overloaded',
INTERNAL_ERROR: 'internal_error',
TIMEOUT: 'timeout',
NO_RESPONDERS: 'no_responders',
@@ -296,6 +296,9 @@ export class GatewayService {
if (error.code === GatewayRpcMethodErrorCodes.TIMEOUT) {
return new GatewayTimeoutError();
}
if (error.code === GatewayRpcMethodErrorCodes.GUILD_OVERLOADED) {
return new ServiceUnavailableError({headers: {'Retry-After': '1'}});
}
if (error.code === GatewayRpcMethodErrorCodes.OVERLOADED) {
return new ServiceUnavailableError();
}
@@ -8,6 +8,7 @@ import type {IGatewayRpcTransport} from '@app/api/infrastructure/IGatewayRpcTran
import {APIErrorCodes} from '@fluxer/constants/src/ApiErrorCodes';
import {BadGatewayError} from '@fluxer/errors/src/domains/core/BadGatewayError';
import {BadRequestError} from '@fluxer/errors/src/domains/core/BadRequestError';
import {ServiceUnavailableError} from '@fluxer/errors/src/domains/core/ServiceUnavailableError';
import {UnknownGuildError} from '@fluxer/errors/src/domains/guild/UnknownGuildError';
import {afterEach, describe, expect, it} from 'vitest';
@@ -70,4 +71,30 @@ describe('GatewayService gateway error mapping', () => {
expect((error as BadRequestError).status).toBe(400);
expect((error as BadRequestError).code).toBe(APIErrorCodes.INVALID_FORM_BODY);
});
it('returns 503 with Retry-After for an overloaded guild', async () => {
const service = serviceRaising(GatewayRpcMethodErrorCodes.GUILD_OVERLOADED);
const error = await service
.getUserPermissions({guildId: createGuildID(1n), userId: createUserID(2n)})
.catch((raised: unknown) => raised);
expect(error).toBeInstanceOf(ServiceUnavailableError);
const response = (error as ServiceUnavailableError).getResponse();
expect(response.status).toBe(503);
expect(response.headers.get('Retry-After')).toBe('1');
});
it('does not retry a guild overload response', async () => {
let calls = 0;
const client = GatewayRpcClient.createForTests({
async call(): Promise<unknown> {
calls += 1;
throw new GatewayRpcMethodError(GatewayRpcMethodErrorCodes.GUILD_OVERLOADED);
},
async destroy(): Promise<void> {},
});
await expect(client.call('guild.dispatch', {guild_id: '1'})).rejects.toMatchObject({
code: GatewayRpcMethodErrorCodes.GUILD_OVERLOADED,
});
expect(calls).toBe(1);
});
});
@@ -24,7 +24,6 @@ import type {ReadStateService} from '@app/api/read_state/ReadStateService';
import type {IUserRepository} from '@app/api/user/IUserRepository';
import type {VoiceAvailabilityService} from '@app/api/voice/VoiceAvailabilityService';
import type {IWebhookRepository} from '@app/api/webhook/IWebhookRepository';
import type {IpInfoService} from '@pkgs/geoip/src/IpInfoService';
import type {IVirusScanService} from '@pkgs/virus_scan/src/IVirusScanService';
interface GuildStackServiceFactoryDependencies {
@@ -50,7 +49,6 @@ interface GuildStackServiceFactoryDependencies {
voiceRoomStore: IVoiceRoomStore;
liveKitService: ILiveKitService;
voiceAvailabilityService: VoiceAvailabilityService | null;
ipInfoService: IpInfoService;
}
export interface GuildStackServices {
@@ -106,7 +104,6 @@ class LazyGuildStackServices implements GuildStackServices {
this.dependencies.webhookRepository,
this.dependencies.guildAuditLogService,
this.dependencies.limitConfigService,
this.dependencies.ipInfoService,
);
return this.cachedGuildService;
}
@@ -6,7 +6,6 @@ import {AdminService} from '@app/api/admin/AdminService';
import {AuthRequestService} from '@app/api/auth/AuthRequestService';
import {DesktopHandoffService} from '@app/api/auth/services/DesktopHandoffService';
import {SsoService} from '@app/api/auth/services/SsoService';
import {buildIpInfoCache, buildIpInfoRequestAuditLogger} from '@app/api/ban/IpInfoCacheFactory';
import type {IBlueskyOAuthService} from '@app/api/bluesky/IBlueskyOAuthService';
import {Config} from '@app/api/Config';
import {createApiContext} from '@app/api/CreateApiContext';
@@ -138,7 +137,6 @@ import {getRequestClientIp} from '@app/api/utils/RequestClientIp';
import {VoiceService} from '@app/api/voice/VoiceService';
import {WebhookRequestService} from '@app/api/webhook/WebhookRequestService';
import {WebhookService} from '@app/api/webhook/WebhookService';
import {createIpInfoService, createUnavailableIpInfoService, type IpInfoService} from '@pkgs/geoip/src/IpInfoService';
import {createMiddleware} from 'hono/factory';
export {initializeServiceSingletons} from '@app/api/middleware/ServiceSingletons';
@@ -172,33 +170,6 @@ export function shutdownReportService(): void {
}
}
let _ipInfoService: IpInfoService | null = null;
let _injectedIpInfoService: IpInfoService | undefined;
export function setInjectedIpInfoService(service: IpInfoService | undefined): void {
_injectedIpInfoService = service;
}
export function getIpInfoService(): IpInfoService {
if (_injectedIpInfoService) {
return _injectedIpInfoService;
}
if (_ipInfoService) return _ipInfoService;
if (!Config.ipinfo.apiKey) {
_ipInfoService = createUnavailableIpInfoService('IPInfo API key not configured');
return _ipInfoService;
}
const cache = buildIpInfoCache({
hot: getCacheService(),
});
_ipInfoService = createIpInfoService({
apiKey: Config.ipinfo.apiKey,
cache,
auditLogger: buildIpInfoRequestAuditLogger(),
});
return _ipInfoService;
}
let _liveKitWebhookService: LiveKitWebhookService | null = null;
function getLiveKitWebhookService(): LiveKitWebhookService | null {
@@ -349,7 +320,6 @@ class RequestServices implements RequestScopedServices {
voiceRoomStore: this.voiceRooms,
liveKitService: this.liveKit,
voiceAvailabilityService: getVoiceAvailabilityService(),
ipInfoService: getIpInfoService(),
});
return this.cachedGuildStack;
}
@@ -544,7 +514,6 @@ class RequestServices implements RequestScopedServices {
getApplicationRepository(),
this.stripeService.getStripe(),
new JobLedgerRepository(),
getIpInfoService(),
this.storeEntitlementService,
);
return this.cachedAdminService;
@@ -931,6 +900,5 @@ export const ServiceMiddleware = createMiddleware<HonoEnv>(async (ctx, next) =>
export function resetServiceMiddlewareForTesting(): void {
shutdownReportService();
_ipInfoService = null;
_liveKitWebhookService = null;
}
+1 -1
View File
@@ -22729,7 +22729,7 @@
"description": "The sequence number for lifetime premium subscribers"
},
"premium_grace_ends_at": {
"description": "ISO8601 timestamp at which the post-cancel grace period ends. Set when the subscription is fully canceled in Stripe; perks remain active and the original premium_since is restored on resubscribe until this timestamp passes. Null when not in grace.",
"description": "ISO8601 timestamp at which grace access ends after premium_until passes: after a failed renewal payment (7 days from the renewal for monthly plans, 14 for yearly), after a subscription ends (3 days), or during an App Store or Google Play grace period. Perks stay active and the original premium_since is kept on resubscribe until this timestamp passes. Null when no grace is recorded, in which case access lasts 3 days after premium_until.",
"type": ["string", "null"]
},
"premium_discriminator": {
@@ -30,7 +30,7 @@ import type {StripePremiumService} from '@app/api/stripe/services/StripePremiumS
import type {StripeSubscriptionReconciler} from '@app/api/stripe/services/StripeSubscriptionReconciler';
import type {IUserRepository} from '@app/api/user/IUserRepository';
import {PaymentRepository} from '@app/api/user/repositories/PaymentRepository';
import {PREMIUM_GRACE_PERIOD_MS} from '@app/api/user/UserHelpers';
import {getPremiumPaymentRecoveryGraceMs} from '@app/api/user/UserHelpers';
import {mapUserToPrivateResponse} from '@app/api/user/UserMappers';
import {UserPremiumTypes} from '@fluxer/constants/src/UserConstants';
import {StripeError} from '@fluxer/errors/src/domains/payment/StripeError';
@@ -369,7 +369,7 @@ export class StripeSubscriptionWebhookHandler {
);
return;
}
const updatedUser = await this.markSubscriptionAsGraceDisabled(targetUser, {
const updatedUser = await this.markSubscriptionPaymentIssue(targetUser, {
subscriptionId,
customerId: this.reconciler.getCustomerIdFromInvoice(invoice),
failedInvoiceServicePeriod: this.getInvoiceServicePeriod(invoice),
@@ -507,10 +507,10 @@ export class StripeSubscriptionWebhookHandler {
}
const willCancel = getPremiumWillCancelFromSubscription(canonicalSubscription);
if (!canProvisionPremiumFromSubscriptionStatus(canonicalSubscription.status)) {
const updatedUser = await this.markSubscriptionAsGraceDisabled(targetUser, {
const updatedUser = await this.markSubscriptionPaymentIssue(targetUser, {
subscriptionId: canonicalSubscription.id,
customerId: extractId(canonicalSubscription.customer),
failedInvoiceServicePeriod: null,
failedInvoiceServicePeriod: this.getUnpaidRenewalPeriod(targetUser, canonicalSubscription),
});
await this.enqueuePremiumStateReconciliation(updatedUser.id, {
reason: 'subscription_updated_non_provisionable',
@@ -523,7 +523,7 @@ export class StripeSubscriptionWebhookHandler {
status: canonicalSubscription.status,
willCancel,
},
'Subscription updated in non-provisionable state; preserved local expiry and disabled grace period',
'Subscription updated in non-provisionable state; preserved local expiry',
);
return;
}
@@ -663,11 +663,22 @@ export class StripeSubscriptionWebhookHandler {
if (!alreadyAppliedEarlyCancellation) {
const cancelledBeforePeriodEnd =
targetUser.premiumUntil != null && subscriptionEndedAt.getTime() < targetUser.premiumUntil.getTime();
if (cancelledBeforePeriodEnd) {
updates.premium_until = subscriptionEndedAt;
updates.premium_grace_ends_at = subscriptionEndedAt;
if (subscription.cancellation_details?.reason === 'payment_failed') {
const lapseStart =
targetUser.premiumUntil && targetUser.premiumUntil.getTime() < subscriptionEndedAt.getTime()
? targetUser.premiumUntil
: subscriptionEndedAt;
const billingCycle =
targetUser.premiumBillingCycle ?? this.reconciler.getBillingCycleFromSubscription(subscription);
updates.premium_until = lapseStart;
updates.premium_grace_ends_at = new Date(
lapseStart.getTime() + getPremiumPaymentRecoveryGraceMs(billingCycle),
);
} else {
updates.premium_grace_ends_at = new Date(subscriptionEndedAt.getTime() + PREMIUM_GRACE_PERIOD_MS);
if (cancelledBeforePeriodEnd) {
updates.premium_until = subscriptionEndedAt;
}
updates.premium_grace_ends_at = subscriptionEndedAt;
}
}
}
@@ -740,7 +751,7 @@ export class StripeSubscriptionWebhookHandler {
);
}
private async markSubscriptionAsGraceDisabled(
private async markSubscriptionPaymentIssue(
user: User,
context: {
subscriptionId: string | null;
@@ -770,6 +781,17 @@ export class StripeSubscriptionWebhookHandler {
) {
patch.premium_until = context.failedInvoiceServicePeriod.start;
}
const lapseStart = patch.premium_until ?? user.premiumUntil;
if (
user.premiumType === UserPremiumTypes.SUBSCRIPTION &&
context.failedInvoiceServicePeriod &&
lapseStart?.getTime() === context.failedInvoiceServicePeriod.start.getTime()
) {
const graceEndsAt = new Date(lapseStart.getTime() + getPremiumPaymentRecoveryGraceMs(user.premiumBillingCycle));
if (user.premiumGraceEndsAt?.getTime() !== graceEndsAt.getTime()) {
patch.premium_grace_ends_at = graceEndsAt;
}
}
if (Object.keys(patch).length === 0) {
return user;
}
@@ -778,6 +800,27 @@ export class StripeSubscriptionWebhookHandler {
return (await this.restoreStoreEntitlement(updatedUser.id)) ?? updatedUser;
}
private getUnpaidRenewalPeriod(
user: User,
subscription: Stripe.Subscription,
): {
start: Date;
end: Date;
} | null {
if (subscription.status !== 'past_due' && subscription.status !== 'unpaid') {
return null;
}
const item = getPrimarySubscriptionItem(subscription);
if (!item?.current_period_start || !item.current_period_end || !user.premiumUntil) {
return null;
}
const start = new Date(item.current_period_start * 1000);
if (user.premiumUntil.getTime() !== start.getTime()) {
return null;
}
return {start, end: new Date(item.current_period_end * 1000)};
}
private getInvoiceServicePeriod(invoice: Stripe.Invoice): {
start: Date;
end: Date;
@@ -43,6 +43,7 @@ const MOCK_PRICES = {
gift1YearEur: 'price_gift_1_year_eur',
};
const DAY_MS = 24 * 60 * 60 * 1000;
const LEGACY_MONTHLY_BRL_PRICE = 'price_legacy_monthly_brl';
const LEGACY_YEARLY_BRL_PRICE = 'price_legacy_yearly_brl';
const UNMAPPED_PRICE = 'price_retired_unmapped_brl';
@@ -147,6 +148,7 @@ describe('Stripe Webhook - Invoice Events', () => {
customerId: string;
premiumUntil: Date;
premiumWillCancel?: boolean;
billingCycle?: 'monthly' | 'yearly';
}): Promise<void> {
const {UserRepository} = await import('@app/api/user/repositories/UserRepository');
const userRepository = new UserRepository();
@@ -157,12 +159,44 @@ describe('Stripe Webhook - Invoice Events', () => {
premium_type: UserPremiumTypes.SUBSCRIPTION,
premium_until: params.premiumUntil,
premium_will_cancel: params.premiumWillCancel ?? false,
...(params.billingCycle ? {premium_billing_cycle: params.billingCycle} : {}),
stripe_subscription_id: params.subscriptionId,
stripe_customer_id: params.customerId,
},
(await userRepository.findUnique(userId))!.toRow(),
);
}
function createRenewalFailureEvent(params: {
invoiceId: string;
customerId: string;
subscriptionId: string;
periodStart: Date;
periodEnd: Date;
}): StripeWebhookEventData {
const eventData = createInvoicePaymentFailedEvent({
invoiceId: params.invoiceId,
customerId: params.customerId,
subscriptionId: params.subscriptionId,
amountDue: 2500,
});
eventData.data.object.billing_reason = 'subscription_cycle';
eventData.data.object.lines = {
data: [
{
period: {
start: Math.floor(params.periodStart.getTime() / 1000),
end: Math.floor(params.periodEnd.getTime() / 1000),
},
parent: {
subscription_item_details: {
subscription: params.subscriptionId,
},
},
},
],
};
return eventData;
}
describe('invoice.payment_succeeded', () => {
test('processes recurring subscription payment successfully', async () => {
const account = await createTestAccount(harness);
@@ -559,6 +593,7 @@ describe('Stripe Webhook - Invoice Events', () => {
premium_type: UserPremiumTypes.SUBSCRIPTION,
premium_until: existingPremiumUntil,
premium_will_cancel: false,
premium_billing_cycle: 'monthly',
stripe_subscription_id: subscriptionId,
stripe_customer_id: 'cus_test_failed_invoice',
},
@@ -592,12 +627,96 @@ describe('Stripe Webhook - Invoice Events', () => {
premium_type: number | null;
premium_until: string | null;
premium_will_cancel: boolean;
premium_grace_ends_at: string | null;
}>(harness, account.token)
.get('/users/@me')
.execute();
const failedPeriodStartMs = Math.floor(failedPeriodStart.getTime() / 1000) * 1000;
expect(me.premium_type).toBe(UserPremiumTypes.SUBSCRIPTION);
expect(me.premium_until).toBe(new Date(failedPeriodStartMs).toISOString());
expect(me.premium_will_cancel).toBe(true);
expect(me.premium_grace_ends_at).toBe(new Date(failedPeriodStartMs + 7 * DAY_MS).toISOString());
});
test('records a 14-day recovery deadline for a yearly subscription', async () => {
const account = await createTestAccount(harness);
const subscriptionId = `sub_failed_yearly_${Date.now()}`;
const failedPeriodStart = new Date(Math.floor((Date.now() - 60 * 60 * 1000) / 1000) * 1000);
const failedPeriodEnd = new Date(failedPeriodStart.getTime() + 365 * DAY_MS);
await createPaymentRecord({
userId: account.userId,
subscriptionId,
priceId: MOCK_PRICES.yearlyUsd,
productType: ProductType.YEARLY_SUBSCRIPTION,
});
await setSubscriptionUserState({
accountUserId: account.userId,
subscriptionId,
customerId: 'cus_test_failed_yearly',
premiumUntil: failedPeriodStart,
billingCycle: 'yearly',
});
const result = await sendWebhook(
createRenewalFailureEvent({
invoiceId: `in_failed_yearly_${Date.now()}`,
customerId: 'cus_test_failed_yearly',
subscriptionId,
periodStart: failedPeriodStart,
periodEnd: failedPeriodEnd,
}),
);
expect(result.received).toBe(true);
const me = await createBuilder<{
premium_type: number | null;
premium_until: string | null;
premium_grace_ends_at: string | null;
}>(harness, account.token)
.get('/users/@me')
.execute();
expect(me.premium_type).toBe(UserPremiumTypes.SUBSCRIPTION);
expect(me.premium_until).toBe(new Date(Math.floor(failedPeriodStart.getTime() / 1000) * 1000).toISOString());
expect(me.premium_will_cancel).toBe(true);
expect(me.premium_until).toBe(failedPeriodStart.toISOString());
expect(me.premium_grace_ends_at).toBe(new Date(failedPeriodStart.getTime() + 14 * DAY_MS).toISOString());
});
test('does not move the recovery deadline on a repeated failure for the same period', async () => {
const account = await createTestAccount(harness);
const subscriptionId = `sub_failed_repeat_${Date.now()}`;
const failedPeriodStart = new Date(Math.floor((Date.now() - 2 * DAY_MS) / 1000) * 1000);
const failedPeriodEnd = new Date(failedPeriodStart.getTime() + 30 * DAY_MS);
await createPaymentRecord({
userId: account.userId,
subscriptionId,
priceId: MOCK_PRICES.monthlyUsd,
productType: ProductType.MONTHLY_SUBSCRIPTION,
});
await setSubscriptionUserState({
accountUserId: account.userId,
subscriptionId,
customerId: 'cus_test_failed_repeat',
premiumUntil: failedPeriodStart,
billingCycle: 'monthly',
});
const invoiceId = `in_failed_repeat_${Date.now()}`;
const expectedDeadline = new Date(failedPeriodStart.getTime() + 7 * DAY_MS).toISOString();
for (const attempt of [1, 2]) {
const eventData = createRenewalFailureEvent({
invoiceId,
customerId: 'cus_test_failed_repeat',
subscriptionId,
periodStart: failedPeriodStart,
periodEnd: failedPeriodEnd,
});
eventData.id = `evt_failed_repeat_${attempt}_${Date.now()}`;
eventData.data.object.attempt_count = attempt;
const result = await sendWebhook(eventData);
expect(result.received).toBe(true);
const me = await createBuilder<{
premium_until: string | null;
premium_grace_ends_at: string | null;
}>(harness, account.token)
.get('/users/@me')
.execute();
expect(me.premium_until).toBe(failedPeriodStart.toISOString());
expect(me.premium_grace_ends_at).toBe(expectedDeadline);
}
});
test('ignores non-renewal invoice payment failures', async () => {
const account = await createTestAccount(harness);
@@ -688,11 +807,14 @@ describe('Stripe Webhook - Invoice Events', () => {
const me = await createBuilder<{
premium_until: string | null;
premium_will_cancel: boolean;
premium_grace_ends_at: string | null;
}>(harness, account.token)
.get('/users/@me')
.execute();
expect(me.premium_until).toBe(new Date(Math.floor(failedPeriodStart.getTime() / 1000) * 1000).toISOString());
const failedPeriodStartMs = Math.floor(failedPeriodStart.getTime() / 1000) * 1000;
expect(me.premium_until).toBe(new Date(failedPeriodStartMs).toISOString());
expect(me.premium_will_cancel).toBe(true);
expect(me.premium_grace_ends_at).toBe(new Date(failedPeriodStartMs + 7 * DAY_MS).toISOString());
});
test('handles invoice.finalization_failed like a recurring access issue', async () => {
const account = await createTestAccount(harness);
@@ -19,6 +19,7 @@ import {server} from '@app/api/test/msw/server';
import {createBuilder} from '@app/api/test/TestRequestBuilder';
import {PaymentRepository} from '@app/api/user/repositories/PaymentRepository';
import {UserRepository} from '@app/api/user/repositories/UserRepository';
import {getPremiumPaymentRecoveryGraceMs, PREMIUM_GRACE_PERIOD_MS} from '@app/api/user/UserHelpers';
import {APIErrorCodes} from '@fluxer/constants/src/ApiErrorCodes';
import {UserPremiumTypes} from '@fluxer/constants/src/UserConstants';
import {HttpResponse, http} from 'msw';
@@ -26,6 +27,7 @@ import {afterAll, afterEach, beforeAll, beforeEach, describe, expect, test} from
const MOCK_PRICES = {
monthlyUsd: 'price_monthly_usd',
yearlyUsd: 'price_yearly_usd',
};
describe('Stripe Webhook Subscription Lifecycle', () => {
@@ -259,6 +261,80 @@ describe('Stripe Webhook Subscription Lifecycle', () => {
expect(updatedUser?.stripeSubscriptionId).toBe(subscriptionId);
expect(updatedUser?.stripeCustomerId).toBe('cus_test_past_due');
});
async function seedPastDueUser(subscriptionId: string, premiumUntil: Date) {
const account = await createTestAccount(harness);
const userId = createUserID(BigInt(account.userId));
const sessionId = `cs_${subscriptionId}_${Date.now()}`;
await paymentRepository.createPayment({
checkout_session_id: sessionId,
user_id: userId,
price_id: MOCK_PRICES.monthlyUsd,
product_type: ProductType.MONTHLY_SUBSCRIPTION,
status: 'completed',
is_gift: false,
created_at: new Date(),
});
await paymentRepository.updatePayment({
checkout_session_id: sessionId,
subscription_id: subscriptionId,
stripe_customer_id: 'cus_test_past_due',
status: 'completed',
});
await userRepository.patchUpsert(
userId,
{
premium_type: UserPremiumTypes.SUBSCRIPTION,
premium_until: premiumUntil,
premium_will_cancel: false,
premium_billing_cycle: 'monthly',
stripe_subscription_id: subscriptionId,
stripe_customer_id: 'cus_test_past_due',
premium_since: new Date(),
},
(await userRepository.findUnique(userId))!.toRow(),
);
return userId;
}
function pastDueEvent(subscriptionId: string, periodStartSeconds: number, periodEndSeconds: number) {
const eventData = createSubscriptionUpdatedEvent({
subscriptionId,
customerId: 'cus_test_past_due',
status: 'past_due',
cancelAtPeriodEnd: false,
});
eventData.data.object.cancel_at = null;
eventData.data.object.items = {
data: [{current_period_start: periodStartSeconds, current_period_end: periodEndSeconds}],
};
return eventData;
}
test('records the payment recovery deadline when past_due arrives before the failed invoice', async () => {
const subscriptionId = 'sub_test_past_due_first';
const renewalSeconds = Math.floor(Date.now() / 1000) - 60 * 60;
const renewalAt = new Date(renewalSeconds * 1000);
const userId = await seedPastDueUser(subscriptionId, renewalAt);
const result = await sendWebhook(
pastDueEvent(subscriptionId, renewalSeconds, renewalSeconds + 30 * 24 * 60 * 60),
);
expect(result.received).toBe(true);
const updatedUser = await userRepository.findUnique(userId);
expect(updatedUser?.premiumUntil?.getTime()).toBe(renewalAt.getTime());
expect(updatedUser?.premiumGraceEndsAt?.getTime()).toBe(
renewalAt.getTime() + getPremiumPaymentRecoveryGraceMs('monthly'),
);
});
test('does not move premium back to the period start for a mid-period past_due', async () => {
const subscriptionId = 'sub_test_past_due_mid_period';
const periodStartSeconds = Math.floor(Date.now() / 1000) - 20 * 24 * 60 * 60;
const periodEndSeconds = periodStartSeconds + 30 * 24 * 60 * 60;
const paidThrough = new Date(periodEndSeconds * 1000);
const userId = await seedPastDueUser(subscriptionId, paidThrough);
const result = await sendWebhook(pastDueEvent(subscriptionId, periodStartSeconds, periodEndSeconds));
expect(result.received).toBe(true);
const updatedUser = await userRepository.findUnique(userId);
expect(updatedUser?.premiumUntil?.getTime()).toBe(paidThrough.getTime());
expect(updatedUser?.premiumGraceEndsAt).toBeNull();
});
test('does not clear premium when period end is missing', async () => {
const account = await createTestAccount(harness);
const userId = createUserID(BigInt(account.userId));
@@ -501,7 +577,7 @@ describe('Stripe Webhook Subscription Lifecycle', () => {
const {checkHasActivePaidPremium} = await import('@app/api/user/UserHelpers');
expect(checkHasActivePaidPremium(afterUser!)).toBe(false);
});
test('grants standard grace when the subscription is cancelled at the end of its paid period', async () => {
test('ends premium without grace when the subscription is cancelled at the end of its paid period', async () => {
const account = await createTestAccount(harness);
const userId = createUserID(BigInt(account.userId));
const subscriptionId = 'sub_test_cancel_natural';
@@ -523,8 +599,113 @@ describe('Stripe Webhook Subscription Lifecycle', () => {
expect(result.received).toBe(true);
const afterUser = await userRepository.findUnique(userId);
expect(afterUser?.premiumUntil?.getTime()).toBe(premiumUntil.getTime());
expect(afterUser?.premiumGraceEndsAt).not.toBeNull();
expect(afterUser!.premiumGraceEndsAt!.getTime()).toBe(endedAt * 1000 + 3 * 24 * 60 * 60 * 1000);
expect(afterUser?.premiumGraceEndsAt?.getTime()).toBe(endedAt * 1000);
const {checkHasActivePaidPremium} = await import('@app/api/user/UserHelpers');
expect(checkHasActivePaidPremium(afterUser!)).toBe(false);
});
test('keeps the payment recovery deadline when Stripe cancels for non-payment', async () => {
const account = await createTestAccount(harness);
const userId = createUserID(BigInt(account.userId));
const subscriptionId = 'sub_test_cancel_non_payment';
const sessionId = `cs_test_non_payment_${Date.now()}`;
await paymentRepository.createPayment({
checkout_session_id: sessionId,
user_id: userId,
price_id: MOCK_PRICES.monthlyUsd,
product_type: ProductType.MONTHLY_SUBSCRIPTION,
status: 'completed',
is_gift: false,
created_at: new Date(),
});
await paymentRepository.updatePayment({
checkout_session_id: sessionId,
subscription_id: subscriptionId,
stripe_customer_id: 'cus_test_1',
status: 'completed',
});
const lapseStart = new Date(Math.floor((Date.now() - 5 * 24 * 60 * 60 * 1000) / 1000) * 1000);
const recoveryDeadline = new Date(lapseStart.getTime() + 7 * 24 * 60 * 60 * 1000);
await userRepository.patchUpsert(
userId,
{
premium_type: UserPremiumTypes.SUBSCRIPTION,
stripe_subscription_id: subscriptionId,
stripe_customer_id: 'cus_test_1',
premium_since: new Date(),
premium_until: lapseStart,
premium_billing_cycle: 'monthly',
premium_will_cancel: true,
premium_grace_ends_at: recoveryDeadline,
},
(await userRepository.findUnique(userId))!.toRow(),
);
const endedAt = Math.floor(Date.now() / 1000);
const eventData = createSubscriptionDeletedEvent({
subscriptionId,
endedAt,
cancellationReason: 'payment_failed',
interval: 'month',
});
const result = await sendWebhook(eventData);
expect(result.received).toBe(true);
const afterUser = await userRepository.findUnique(userId);
expect(afterUser?.premiumType).toBe(UserPremiumTypes.SUBSCRIPTION);
expect(afterUser?.premiumUntil?.getTime()).toBe(lapseStart.getTime());
expect(afterUser?.premiumGraceEndsAt?.getTime()).toBe(recoveryDeadline.getTime());
expect(afterUser?.premiumGraceEndsAt?.getTime()).not.toBe(endedAt * 1000 + PREMIUM_GRACE_PERIOD_MS);
expect(afterUser?.stripeSubscriptionId).toBeNull();
const {checkHasActivePaidPremium} = await import('@app/api/user/UserHelpers');
expect(checkHasActivePaidPremium(afterUser!)).toBe(true);
});
test('records the recovery deadline from the payload cycle when none was recorded', async () => {
const account = await createTestAccount(harness);
const userId = createUserID(BigInt(account.userId));
const subscriptionId = 'sub_test_cancel_non_payment_yearly';
const sessionId = `cs_test_non_payment_yearly_${Date.now()}`;
await paymentRepository.createPayment({
checkout_session_id: sessionId,
user_id: userId,
price_id: MOCK_PRICES.yearlyUsd,
product_type: ProductType.YEARLY_SUBSCRIPTION,
status: 'completed',
is_gift: false,
created_at: new Date(),
});
await paymentRepository.updatePayment({
checkout_session_id: sessionId,
subscription_id: subscriptionId,
stripe_customer_id: 'cus_test_1',
status: 'completed',
});
const lapseStart = new Date(Math.floor((Date.now() - 10 * 24 * 60 * 60 * 1000) / 1000) * 1000);
await userRepository.patchUpsert(
userId,
{
premium_type: UserPremiumTypes.SUBSCRIPTION,
stripe_subscription_id: subscriptionId,
stripe_customer_id: 'cus_test_1',
premium_since: new Date(),
premium_until: lapseStart,
premium_billing_cycle: null,
premium_grace_ends_at: null,
},
(await userRepository.findUnique(userId))!.toRow(),
);
const endedAt = Math.floor(Date.now() / 1000);
const eventData = createSubscriptionDeletedEvent({
subscriptionId,
endedAt,
cancellationReason: 'payment_failed',
interval: 'year',
});
const result = await sendWebhook(eventData);
expect(result.received).toBe(true);
const afterUser = await userRepository.findUnique(userId);
expect(afterUser?.premiumUntil?.getTime()).toBe(lapseStart.getTime());
expect(afterUser?.premiumGraceEndsAt?.getTime()).toBe(
lapseStart.getTime() + getPremiumPaymentRecoveryGraceMs('yearly'),
);
expect(afterUser?.premiumGraceEndsAt?.getTime()).toBe(lapseStart.getTime() + 14 * 24 * 60 * 60 * 1000);
const {checkHasActivePaidPremium} = await import('@app/api/user/UserHelpers');
expect(checkHasActivePaidPremium(afterUser!)).toBe(true);
});
@@ -10,7 +10,6 @@ import {
import {resetSharedListsForTests} from '@app/api/infrastructure/activity/SharedLists';
import {NullSearchProvider} from '@app/api/infrastructure/NullSearchProvider';
import {ipBanCache} from '@app/api/middleware/IpBanMiddleware';
import {setInjectedIpInfoService} from '@app/api/middleware/ServiceMiddleware';
import {
setInjectedBlueskyOAuthService,
setInjectedGatewayService,
@@ -106,7 +105,6 @@ export async function createApiTestHarness(options: CreateApiTestHarnessOptions
getInstanceConfigRepository().clearCacheForTesting();
kvProvider.reset();
mockBlueskyOAuthService.reset();
setInjectedIpInfoService(undefined);
setInjectedUnfurlerService(undefined);
resetSharedListsForTests();
}
@@ -134,7 +132,6 @@ export async function createApiTestHarness(options: CreateApiTestHarnessOptions
setInjectedWorkerService(new NoopWorkerService());
setInjectedGatewayService(new NoopGatewayService());
setInjectedKVProvider(new MockKVProvider());
setInjectedIpInfoService(undefined);
setInjectedUnfurlerService(undefined);
resetSharedListsForTests();
const fallbackStorageService = new MockStorageService();
@@ -1,28 +0,0 @@
// SPDX-License-Identifier: AGPL-3.0-or-later
import {HttpResponse, http} from 'msw';
export function createIpInfoLookupHandler() {
return http.get('https://api.ipinfo.io/lookup/:ip', ({params}) => {
const ip = typeof params.ip === 'string' ? params.ip : '198.51.100.1';
return HttpResponse.json({
ip,
geo: {
city: 'Ashburn',
region: 'Virginia',
region_code: 'VA',
country: 'United States',
country_code: 'US',
continent: 'North America',
continent_code: 'NA',
},
as: {
asn: 'AS64500',
name: 'Test ISP',
domain: 'example.com',
type: 'isp',
},
anonymous: {},
});
});
}
@@ -1857,6 +1857,8 @@ export function createSubscriptionDeletedEvent(options: {
subscriptionId?: string;
customerId?: string;
endedAt?: number;
cancellationReason?: 'cancellation_requested' | 'payment_disputed' | 'payment_failed';
interval?: 'month' | 'year';
}): StripeWebhookEventData {
const nowSeconds = Math.floor(Date.now() / 1000);
return {
@@ -1869,6 +1871,15 @@ export function createSubscriptionDeletedEvent(options: {
status: 'canceled',
canceled_at: nowSeconds,
ended_at: options.endedAt ?? nowSeconds,
...(options.cancellationReason ? {cancellation_details: {reason: options.cancellationReason}} : {}),
...(options.interval
? {
items: {
object: 'list',
data: [{object: 'subscription_item', price: {recurring: {interval: options.interval}}}],
},
}
: {}),
},
},
};
-2
View File
@@ -1,6 +1,5 @@
// SPDX-License-Identifier: AGPL-3.0-or-later
import {createIpInfoLookupHandler} from '@app/api/test/msw/handlers/IpInfoHandlers';
import {createNcmecHandlers} from '@app/api/test/msw/handlers/NcmecHandlers';
import {createOnionooDetailsHandler} from '@app/api/test/msw/handlers/OnionooHandlers';
import {createOpenNsfwHandlers} from '@app/api/test/msw/handlers/OpenNsfwHandlers';
@@ -10,7 +9,6 @@ import {setupServer} from 'msw/node';
export const server = setupServer(
...createNcmecHandlers(),
...createOpenNsfwHandlers(),
createIpInfoLookupHandler(),
createOnionooDetailsHandler(),
createPwnedPasswordsRangeHandler(),
);
@@ -7,9 +7,11 @@ import {
checkIsPremium,
getEffectivePremiumUntil,
getEffectiveSuspiciousFlags,
getPremiumPaymentRecoveryGraceMs,
getRequiredActions,
isSignInRefused,
isTemporarilyBanned,
PREMIUM_GRACE_PERIOD_MS,
} from '@app/api/user/UserHelpers';
import {
DEFERRED_PHONE_ON_COMMUNITY_JOIN,
@@ -289,3 +291,17 @@ describe('account standing', () => {
expect(canOwnerRunBots(standing(0n))).toBe(true);
});
});
describe('premium grace lengths', () => {
it('maps billing cycles to payment recovery grace', () => {
const day = 24 * 60 * 60 * 1000;
expect(getPremiumPaymentRecoveryGraceMs('monthly')).toBe(7 * day);
expect(getPremiumPaymentRecoveryGraceMs('yearly')).toBe(14 * day);
expect(getPremiumPaymentRecoveryGraceMs(null)).toBe(7 * day);
expect(getPremiumPaymentRecoveryGraceMs(undefined)).toBe(7 * day);
});
it('keeps the fallback grace at 3 days', () => {
expect(PREMIUM_GRACE_PERIOD_MS).toBe(3 * 24 * 60 * 60 * 1000);
});
});
+12 -2
View File
@@ -9,12 +9,14 @@ import {extractEmailDomain} from '@app/api/utils/EmailDomainUtils';
import {
DEFERRABLE_PHONE_FLAGS,
DEFERRED_PHONE_ON_COMMUNITY_JOIN,
PREMIUM_GRACE_PERIOD_DAYS,
PREMIUM_PAYMENT_RECOVERY_GRACE_DAYS,
PremiumFlags,
SuspiciousActivityFlags,
UserFlags,
} from '@fluxer/constants/src/UserConstants';
import {MS_PER_DAY} from '@fluxer/date_utils/src/DateConstants';
import type {RequiredAction} from '@fluxer/schema/src/domains/user/UserResponseSchemas';
import {ms} from 'itty-time';
type ClauseAction = Exclude<RequiredAction, 'REQUIRE_INBOUND_PHONE_VERIFICATION'>;
type VerificationChannel = 'email' | 'phone';
@@ -214,7 +216,15 @@ interface PremiumCheckable {
premiumFlags: number;
}
export const PREMIUM_GRACE_PERIOD_MS = ms('3 days');
export const PREMIUM_GRACE_PERIOD_MS = PREMIUM_GRACE_PERIOD_DAYS * MS_PER_DAY;
export function getPremiumPaymentRecoveryGraceMs(billingCycle: string | null | undefined): number {
const days =
billingCycle === 'yearly'
? PREMIUM_PAYMENT_RECOVERY_GRACE_DAYS.yearly
: PREMIUM_PAYMENT_RECOVERY_GRACE_DAYS.monthly;
return days * MS_PER_DAY;
}
export function getEffectivePremiumUntil(
user: Pick<PremiumCheckable, 'premiumUntil' | 'premiumGiftExtensionEndsAt'>,
@@ -38,7 +38,6 @@ import type {InviteService} from '@app/api/invite/InviteService';
import {Logger} from '@app/api/Logger';
import type {LimitConfigService} from '@app/api/limits/LimitConfigService';
import {createGuildStackServices} from '@app/api/middleware/GuildStackServiceFactory';
import {getIpInfoService} from '@app/api/middleware/ServiceMiddleware';
import {
ensureVoiceResourcesInitialized,
getGatewayService,
@@ -237,7 +236,6 @@ export async function initializeWorkerDependencies(snowflakeService: ISnowflakeS
}
const inviteRepository = getInviteRepository();
const webhookRepository = getWebhookRepository();
const ipInfoService = getIpInfoService();
const contactChangeLogService = getContactChangeLogService();
const apiContext = createApiContext();
const {channelService, guildService, inviteService} = createGuildStackServices({
@@ -263,7 +261,6 @@ export async function initializeWorkerDependencies(snowflakeService: ISnowflakeS
voiceRoomStore,
liveKitService,
voiceAvailabilityService,
ipInfoService,
});
const billingRepository = new BillingRepository(snowflakeService, kvClient);
const storeEntitlementService = createStoreEntitlementService({
@@ -75,6 +75,9 @@ function buildStripePremiumRepairPatch(user: User, subscription: Stripe.Subscrip
if (user.premiumWillCancel !== premiumWillCancel) {
patch.premium_will_cancel = premiumWillCancel;
}
if (user.premiumGraceEndsAt != null) {
patch.premium_grace_ends_at = null;
}
if (premiumBillingCycle && user.premiumBillingCycle !== premiumBillingCycle) {
patch.premium_billing_cycle = premiumBillingCycle;
}
@@ -293,7 +296,9 @@ async function reconcileUserPremiumStateFromStripe(params: {userId: UserID; stri
const patch: Partial<UserRow> = {};
let effectivePremiumUntil = getEffectivePremiumUntil(user);
const paidThrough = await getPaidThroughFromSubscriptionInvoices(stripe, mostRecentTerminalSubscription);
if (mostRecentTerminalSubscription?.ended_at && user.premiumUntil) {
const terminalSubscriptionIsCurrent =
user.stripeSubscriptionId == null || mostRecentTerminalSubscription?.id === user.stripeSubscriptionId;
if (mostRecentTerminalSubscription?.ended_at && user.premiumUntil && terminalSubscriptionIsCurrent) {
const subscriptionEndedAt = new Date(mostRecentTerminalSubscription.ended_at * 1000);
const entitlementEnd =
paidThrough && paidThrough.getTime() > subscriptionEndedAt.getTime() ? paidThrough : subscriptionEndedAt;
@@ -314,7 +319,10 @@ async function reconcileUserPremiumStateFromStripe(params: {userId: UserID; stri
premiumGiftExtensionEndsAt: user.premiumGiftExtensionEndsAt,
});
}
const hasFutureLocalEntitlement = effectivePremiumUntil != null && Date.now() <= effectivePremiumUntil.getTime();
const graceEndsAt = patch.premium_grace_ends_at ?? user.premiumGraceEndsAt;
const hasFutureLocalEntitlement =
(effectivePremiumUntil != null && Date.now() <= effectivePremiumUntil.getTime()) ||
(graceEndsAt != null && Date.now() <= graceEndsAt.getTime());
if (hasFutureLocalEntitlement) {
if (user.premiumWillCancel !== true) {
patch.premium_will_cancel = true;
+59 -13
View File
@@ -2,19 +2,65 @@
import {createUserID, type UserID} from '@app/api/BrandedTypes';
import {createRequestCache} from '@app/api/middleware/RequestCacheMiddleware';
import type {User} from '@app/api/models/User';
import {UserChannelService} from '@app/api/user/services/UserChannelService';
import {getWorkerDependencies} from '@app/api/worker/WorkerContext';
import {UserFlags} from '@fluxer/constants/src/UserConstants';
import {JobCancelledError, type WorkerTaskHelpers} from '@pkgs/worker/src/contracts/WorkerTask';
import {z} from 'zod';
const SYSTEM_USER_ID: UserID = createUserID(0n);
const PayloadSchema = z.object({
content: z.string().min(1).max(4000),
user_ids: z.array(z.string().regex(/^\d+$/)).min(1),
});
const ALL_USERS_PAGE_SIZE = 100;
const CURSOR_TTL_SECONDS = 7 * 24 * 60 * 60;
const INELIGIBLE_FLAGS = UserFlags.DELETED | UserFlags.SELF_DELETED | UserFlags.DISABLED;
const PayloadSchema = z.union([
z.object({
content: z.string().min(1).max(4000),
user_ids: z.array(z.string().regex(/^\d+$/)).min(1),
}),
z.object({
content: z.string().min(1).max(4000),
all_users: z.literal(true),
}),
]);
function isEligibleRecipient(user: User): boolean {
return user.id !== SYSTEM_USER_ID && !user.isBot && !user.isSystem && (user.flags & INELIGIBLE_FLAGS) === 0n;
}
async function* allUserRecipients(helpers: WorkerTaskHelpers): AsyncGenerator<UserID> {
const {userRepository, kvClient} = getWorkerDependencies();
const cursorKey = `system_dm:all_users_cursor:${helpers.jobId}`;
let pageState = await kvClient.get(cursorKey);
if (pageState !== null) {
helpers.logger.info('Resuming system DM broadcast from saved cursor');
}
do {
const page = await userRepository.scanAllUsersPage(ALL_USERS_PAGE_SIZE, pageState);
for (const user of page.users) {
if (isEligibleRecipient(user)) {
yield user.id;
}
}
pageState = page.pageState;
if (pageState !== null) {
await kvClient.setex(cursorKey, CURSOR_TTL_SECONDS, pageState);
}
} while (pageState !== null);
await kvClient.del(cursorKey);
}
async function* listedRecipients(userIds: Array<string>): AsyncGenerator<UserID> {
for (const raw of userIds) {
yield createUserID(BigInt(raw));
}
}
export async function sendSystemDm(payload: unknown, helpers: WorkerTaskHelpers): Promise<void> {
const {content, user_ids} = PayloadSchema.parse(payload);
const parsed = PayloadSchema.parse(payload);
const {content} = parsed;
const total = 'user_ids' in parsed ? parsed.user_ids.length : null;
const recipients = 'user_ids' in parsed ? listedRecipients(parsed.user_ids) : allUserRecipients(helpers);
const deps = getWorkerDependencies();
const systemUser = await deps.userRepository.findUniqueAssert(SYSTEM_USER_ID);
const userChannelService = new UserChannelService(
@@ -29,16 +75,12 @@ export async function sendSystemDm(payload: unknown, helpers: WorkerTaskHelpers)
const requestCache = createRequestCache();
let sent = 0;
let failed = 0;
for (const raw of user_ids) {
for await (const recipientId of recipients) {
if (await helpers.shouldCancel()) {
helpers.logger.info(
{sent, failed, remaining: user_ids.length - sent - failed},
'System DM job cancelled mid-flight',
);
helpers.logger.info({sent, failed, total}, 'System DM job cancelled mid-flight');
requestCache.clear();
throw new JobCancelledError();
}
const recipientId = createUserID(BigInt(raw));
try {
const channel = await userChannelService.ensureDmOpenForBothUsers({
userId: SYSTEM_USER_ID,
@@ -55,9 +97,13 @@ export async function sendSystemDm(payload: unknown, helpers: WorkerTaskHelpers)
sent += 1;
} catch (error) {
failed += 1;
helpers.logger.warn({recipientId: raw, error}, 'System DM send failed for recipient');
helpers.logger.warn({recipientId: recipientId.toString(), error}, 'System DM send failed for recipient');
}
if ((sent + failed) % ALL_USERS_PAGE_SIZE === 0) {
requestCache.clear();
await helpers.reportProgress(sent + failed, total, `${sent} sent, ${failed} failed`);
}
}
requestCache.clear();
helpers.logger.info({sent, failed, total: user_ids.length}, 'System DM job complete');
helpers.logger.info({sent, failed, total: sent + failed}, 'System DM job complete');
}
@@ -5,7 +5,7 @@ import {AdminBanManagementService} from '@app/api/admin/services/AdminBanManagem
import {AdminGuildService} from '@app/api/admin/services/AdminGuildService';
import {AdminUserService} from '@app/api/admin/services/AdminUserService';
import {createApiContext} from '@app/api/CreateApiContext';
import {getIpInfoService, getReportServiceInstance} from '@app/api/middleware/ServiceMiddleware';
import {getReportServiceInstance} from '@app/api/middleware/ServiceMiddleware';
import {
getDiscriminatorService,
getEntityAssetService,
@@ -28,7 +28,6 @@ export function createAdminBulkServices(deps: WorkerDependencies): AdminBulkServ
apiContext,
adminRepository: deps.adminRepository,
auditService,
ipInfoService: getIpInfoService(),
});
const userService = new AdminUserService({
apiContext,
@@ -10,7 +10,6 @@ import {DisabledLiveKitService} from '@app/api/infrastructure/DisabledLiveKitSer
import {InMemoryVoiceRoomStore} from '@app/api/infrastructure/InMemoryVoiceRoomStore';
import {getMessages} from '@app/api/message/tests/MessageTestUtils';
import {createGuildStackServices} from '@app/api/middleware/GuildStackServiceFactory';
import {getIpInfoService} from '@app/api/middleware/ServiceMiddleware';
import {getGatewayService, getSnowflakeService, getVoiceAvailabilityService} from '@app/api/middleware/ServiceRegistry';
import {
getAdminRepository,
@@ -97,7 +96,6 @@ function installWorkerDependencies(): void {
voiceRoomStore: new InMemoryVoiceRoomStore(),
liveKitService: new DisabledLiveKitService(),
voiceAvailabilityService: getVoiceAvailabilityService(),
ipInfoService: getIpInfoService(),
});
setWorkerDependenciesForTest({
adminRepository: getAdminRepository(),
@@ -71,6 +71,28 @@ function createActiveSubscription(periodEndMs: number): Stripe.Subscription {
} as unknown as Stripe.Subscription;
}
function createPastDueSubscription(): Stripe.Subscription {
return {
id: 'sub_test',
status: 'past_due',
customer: 'cus_test',
ended_at: null,
canceled_at: null,
cancel_at: null,
cancel_at_period_end: false,
trial_end: null,
start_date: Math.floor((Date.now() - 200 * ONE_DAY_MS) / 1000),
items: {
data: [
{
current_period_end: Math.floor((Date.now() + 29 * ONE_DAY_MS) / 1000),
price: {recurring: {interval: 'month'}},
},
],
},
} as unknown as Stripe.Subscription;
}
function createPaidInvoice(periodEndMs: number): Stripe.Invoice {
return {
id: 'in_test',
@@ -344,6 +366,153 @@ describe('processPremiumStateReconciliationQueue', () => {
expect(patches[0].premium_until).toBeNull();
expect(patches[0].premium_since).toBeNull();
});
test('keeps premium for a past_due subscription until the recorded payment recovery deadline', async () => {
const queueService = createQueueService();
await queueService.enqueueUser(USER_ID, new Date(Date.now() - 1000));
const lapseStartMs = Math.floor((Date.now() - ONE_HOUR_MS) / 1000) * 1000;
const user = createPremiumUser({
premium_until: new Date(lapseStartMs),
premium_will_cancel: true,
premium_billing_cycle: 'monthly',
premium_grace_ends_at: new Date(lapseStartMs + 7 * ONE_DAY_MS),
});
const {userRepository, patches, extras} = createCapturingDeps(user);
setWorkerDependenciesForTest({
premiumStateReconciliationQueueService: queueService,
stripe: createStripeStub(createPastDueSubscription(), [createPaidInvoice(lapseStartMs)]),
userRepository,
...extras,
});
await processPremiumStateReconciliationQueue({}, createHelpers());
expect(patches).toHaveLength(0);
expect(await queueService.getQueueSize()).toBe(0);
});
test('keeps the recovery deadline when an older cancelled subscription shares the customer', async () => {
const queueService = createQueueService();
await queueService.enqueueUser(USER_ID, new Date(Date.now() - 1000));
const lapseStartMs = Math.floor((Date.now() - ONE_HOUR_MS) / 1000) * 1000;
const recoveryDeadline = new Date(lapseStartMs + 7 * ONE_DAY_MS);
const user = createPremiumUser({
premium_until: new Date(lapseStartMs),
premium_will_cancel: true,
premium_billing_cycle: 'monthly',
premium_grace_ends_at: recoveryDeadline,
stripe_subscription_id: 'sub_current',
});
const {userRepository, patches, extras} = createCapturingDeps(user);
const currentSubscription = {...createPastDueSubscription(), id: 'sub_current'} as Stripe.Subscription;
const olderSubscription = {
...createCancelledSubscription(Date.now() - 90 * ONE_DAY_MS),
id: 'sub_older',
} as Stripe.Subscription;
setWorkerDependenciesForTest({
premiumStateReconciliationQueueService: queueService,
stripe: {
subscriptions: {
retrieve: async () => currentSubscription,
list: async () => ({data: [olderSubscription, currentSubscription]}),
},
invoices: {
list: async () => ({data: [createPaidInvoice(Date.now() - 90 * ONE_DAY_MS)]}),
},
} as unknown as Stripe,
userRepository,
...extras,
});
await processPremiumStateReconciliationQueue({}, createHelpers());
expect(patches).toHaveLength(0);
});
test('clears a leftover recovery deadline once the subscription is active again', async () => {
const queueService = createQueueService();
await queueService.enqueueUser(USER_ID, new Date(Date.now() - 1000));
const periodEndMs = Math.floor((Date.now() + 29 * ONE_DAY_MS) / 1000) * 1000;
const user = createPremiumUser({
premium_until: new Date(periodEndMs),
premium_billing_cycle: 'monthly',
premium_grace_ends_at: new Date(Date.now() + 6 * ONE_DAY_MS),
});
const {userRepository, patches, extras} = createCapturingDeps(user);
setWorkerDependenciesForTest({
premiumStateReconciliationQueueService: queueService,
stripe: createStripeStub(createActiveSubscription(periodEndMs), []),
userRepository,
...extras,
});
await processPremiumStateReconciliationQueue({}, createHelpers());
expect(patches).toHaveLength(1);
expect(patches[0].premium_grace_ends_at).toBeNull();
expect(patches[0].premium_until).toBeUndefined();
});
test('strips a past_due subscription once the recovery deadline has passed', async () => {
const queueService = createQueueService();
await queueService.enqueueUser(USER_ID, new Date(Date.now() - 1000));
const lapseStartMs = Math.floor((Date.now() - 7 * ONE_DAY_MS - 60_000) / 1000) * 1000;
const user = createPremiumUser({
premium_until: new Date(lapseStartMs),
premium_will_cancel: true,
premium_billing_cycle: 'monthly',
premium_grace_ends_at: new Date(lapseStartMs + 7 * ONE_DAY_MS),
});
const {userRepository, patches, extras} = createCapturingDeps(user);
setWorkerDependenciesForTest({
premiumStateReconciliationQueueService: queueService,
stripe: createStripeStub(createPastDueSubscription(), [createPaidInvoice(lapseStartMs)]),
userRepository,
...extras,
});
await processPremiumStateReconciliationQueue({}, createHelpers());
expect(patches).toHaveLength(1);
expect(patches[0].premium_type).toBeNull();
expect(patches[0].premium_grace_ends_at).toBeNull();
});
test('honours the voluntary-cancel grace written by the delete webhook', async () => {
const queueService = createQueueService();
await queueService.enqueueUser(USER_ID, new Date(Date.now() - 1000));
const endedAtMs = Math.floor((Date.now() - 60_000) / 1000) * 1000;
const user = createPremiumUser({
premium_until: new Date(endedAtMs),
premium_will_cancel: false,
premium_billing_cycle: null,
stripe_subscription_id: null,
premium_grace_ends_at: new Date(endedAtMs + 3 * ONE_DAY_MS),
});
const {userRepository, patches, extras} = createCapturingDeps(user);
setWorkerDependenciesForTest({
premiumStateReconciliationQueueService: queueService,
stripe: createStripeStub(createCancelledSubscription(endedAtMs), [createPaidInvoice(endedAtMs)]),
userRepository,
...extras,
});
await processPremiumStateReconciliationQueue({}, createHelpers());
expect(patches.every((patch) => patch.premium_type === undefined)).toBe(true);
expect(patches.every((patch) => patch.premium_until === undefined)).toBe(true);
expect(patches.every((patch) => patch.premium_grace_ends_at === undefined)).toBe(true);
});
test('hands a user with an active App Store subscription and a stale Stripe customer to the store', async () => {
const queueService = createQueueService();
await queueService.enqueueUser(USER_ID, new Date(Date.now() - 1000));
@@ -8,6 +8,7 @@ import type {UserRepository} from '@app/api/user/repositories/UserRepository';
import {sendSystemDm} from '@app/api/worker/tasks/SendSystemDm';
import {clearWorkerDependencies, setWorkerDependenciesForTest} from '@app/api/worker/WorkerContext';
import {WorkerRunner} from '@app/api/worker/WorkerRunner';
import {UserFlags} from '@fluxer/constants/src/UserConstants';
import type {JsMsg} from '@nats-io/jetstream';
import {afterEach, beforeAll, describe, expect, it, vi} from 'vitest';
@@ -71,11 +72,11 @@ function createWorkerDependencies() {
return {sentChannelIds, sentUserIds};
}
function createJobMessage() {
function createJobMessage(recipients: Record<string, unknown> = {user_ids: ['11', '12', '13']}) {
const envelope = {
payload: {
content: 'scheduled maintenance tonight',
user_ids: ['11', '12', '13'],
...recipients,
__jobId: LEDGER_JOB_ID.toString(),
},
max_attempts: 5,
@@ -164,4 +165,61 @@ describe('System DM cancellation', () => {
expect(deps.sentUserIds).toEqual([0n, 0n, 0n]);
});
it('broadcasts to every eligible user when all_users is set', async () => {
const user = (id: bigint, extra: Record<string, unknown> = {}) => ({
id,
isBot: false,
isSystem: false,
flags: 0n,
...extra,
});
const pages = [
{users: [user(0n, {isSystem: true}), user(21n), user(22n, {isBot: true})], pageState: 'page-2'},
{
users: [user(23n, {flags: UserFlags.DELETED}), user(24n), user(25n, {flags: UserFlags.DISABLED})],
pageState: null,
},
];
const kv = new Map<string, string>();
const kvClient = {
get: async (key: string) => kv.get(key) ?? null,
setex: async (key: string, _ttl: number, value: string) => {
kv.set(key, value);
},
del: async (key: string) => (kv.delete(key) ? 1 : 0),
};
const recipientIds: Array<bigint> = [];
const systemUser = {id: 0n, username: 'Fluxer', bot: true, system: true};
const userRepository = {
findUnique: async () => systemUser,
findUniqueAssert: async () => systemUser,
findExistingDmState: async (_userId: bigint, recipientId: bigint) => {
recipientIds.push(recipientId);
return {id: 500n};
},
isDmChannelOpen: async () => true,
scanAllUsersPage: async (_limit: number, pageState: string | null) =>
pageState === 'page-2' ? pages[1] : pages[0],
} as unknown as UserRepository;
const channelService = {
messages: {send: {sendMessage: async () => {}}},
} as unknown as ChannelService;
setWorkerDependenciesForTest({userRepository, channelService, kvClient} as never);
const {ledger, markSucceeded} = createLedgerStub(Number.POSITIVE_INFINITY);
const runner = new TestWorkerRunner({
tasks: {[TASK_TYPE]: sendSystemDm},
queue: queueStub,
consumerName: 'workers_batch',
laneName: 'batch',
ledger,
concurrency: 1,
});
await expect(runner.runJob(TASK_TYPE, createJobMessage({all_users: true}) as unknown as JsMsg)).resolves.toBe(true);
expect(recipientIds).toEqual([21n, 24n]);
expect(markSucceeded).toHaveBeenCalledTimes(1);
expect(kv.size).toBe(0);
});
});
@@ -8,6 +8,7 @@ import type {TrackBitrateInfo} from './PCTransport.ts';
import {
applyVideoStartBitrate,
collectStereoMids,
conformBundledCodecFmtp,
ensureAudioNackAndStereo,
ensureOpusFmtp,
ensureVideoDDExtension,
@@ -282,15 +283,63 @@ describe('placeholderMidsFromTransceivers', () => {
return {mid, currentDirection, sender: {track}} as unknown as RTCRtpTransceiver;
}
it('keeps the trackless recvonly sections that still hold an m-line', () => {
it('keeps unused trackless sections that still hold an m-line', () => {
const mids = placeholderMidsFromTransceivers([
transceiver('3', null, 'recvonly'),
transceiver('3', null, 'inactive'),
transceiver('4', null, null),
transceiver('7', {} as MediaStreamTrack, 'sendonly'),
]);
expect(mids).toEqual(new Set(['3']));
expect(mids).toEqual(new Set(['3', '4']));
});
it('drops a transceiver that unpublish stopped so its recycled m-section is not fmtp-conformed', () => {
expect(placeholderMidsFromTransceivers([transceiver('7', null, 'stopped')])).toEqual(new Set());
});
it.each(['recvonly', 'sendrecv'] as const)(
'preserves a negotiated %s receiver without a local sender',
(direction) => {
expect(placeholderMidsFromTransceivers([transceiver('0', null, direction)])).toEqual(new Set());
},
);
it.each(['sendonly', 'sendrecv', undefined] as const)(
'preserves a receiver activated by a remote %s answer before currentDirection updates',
(direction) => {
const incoming = opusMedia('useinbandfec=1');
incoming.direction = direction;
expect(placeholderMidsFromTransceivers([transceiver('0', null, null)], [incoming])).toEqual(new Set());
},
);
it('keeps inactive and rejected remote sections eligible for placeholder conformance', () => {
const inactive = opusMedia('useinbandfec=1', '0');
inactive.direction = 'inactive';
const rejected = opusMedia('useinbandfec=1', '1');
rejected.direction = 'sendonly';
rejected.port = 0;
expect(
placeholderMidsFromTransceivers(
[transceiver('0', null, 'inactive'), transceiver('1', null, null)],
[inactive, rejected],
),
).toEqual(new Set(['0', '1']));
});
it('starting a stereo share preserves incoming microphone fmtp while conforming unused placeholders', () => {
const microphone = opusMedia('useinbandfec=1;maxaveragebitrate=64000', '0');
const placeholder = opusMedia('useinbandfec=1;usedtx=1', '1');
const screenShare = opusMedia('useinbandfec=1', '2');
ensureOpusFmtp(screenShare, 128000, true);
const microphoneConfig = opusConfig(microphone);
const mids = placeholderMidsFromTransceivers([
transceiver('0', null, 'recvonly'),
transceiver('1', null, 'inactive'),
transceiver('2', {} as MediaStreamTrack, 'sendonly'),
]);
conformBundledCodecFmtp([microphone, placeholder, screenShare], (media) => mids.has(String(media.mid)));
expect(opusConfig(microphone)).toBe(microphoneConfig);
expect(opusConfig(screenShare)).toContain('stereo=1');
expect(opusConfig(placeholder)).toBe(opusConfig(screenShare));
});
});
@@ -257,7 +257,7 @@ export default class PCTransport extends (EventEmitter as new () => TypedEmitter
}
}
});
const placeholderMids = this.getPlaceholderMids();
const placeholderMids = this.getPlaceholderMids(sdpParsed.media);
if (placeholderMids.size > 0) {
conformBundledCodecFmtp(sdpParsed.media, (media) => placeholderMids.has(getMidString(media.mid!)));
}
@@ -461,8 +461,11 @@ export default class PCTransport extends (EventEmitter as new () => TypedEmitter
}
}
private getPlaceholderMids(): Set<string> {
return placeholderMidsFromTransceivers(this._pc?.getTransceivers() ?? []);
private getPlaceholderMids(remoteMedia?: ReadonlyArray<MediaDescription>): Set<string> {
return placeholderMidsFromTransceivers(
this._pc?.getTransceivers() ?? [],
remoteMedia ?? parse(this._pc?.remoteDescription?.sdp ?? '').media,
);
}
createDataChannel(label: string, dataChannelDict: RTCDataChannelInit) {
@@ -853,10 +856,28 @@ export function collectStereoMids(
return stereoMids;
}
export function placeholderMidsFromTransceivers(transceivers: ReadonlyArray<RTCRtpTransceiver>): Set<string> {
export function placeholderMidsFromTransceivers(
transceivers: ReadonlyArray<RTCRtpTransceiver>,
remoteMedia: ReadonlyArray<MediaDescription> = [],
): Set<string> {
const receivingMids = new Set(
remoteMedia
.filter(
(media) =>
media.mid !== undefined &&
media.port !== 0 &&
(media.direction === 'sendonly' || media.direction === 'sendrecv' || media.direction === undefined),
)
.map((media) => getMidString(media.mid!)),
);
const mids = new Set<string>();
for (const transceiver of transceivers) {
if (transceiver.currentDirection === 'stopped') {
if (
transceiver.currentDirection === 'stopped' ||
transceiver.currentDirection === 'recvonly' ||
transceiver.currentDirection === 'sendrecv' ||
(transceiver.mid !== null && receivingMids.has(transceiver.mid))
) {
continue;
}
if (transceiver.mid && !transceiver.sender.track) {
@@ -0,0 +1,127 @@
import {type AddTrackRequest, AudioTrackFeature, ParticipantPermission, TrackInfo} from '@livekit/protocol';
import {EventEmitter} from 'events';
import {afterEach, beforeEach, describe, expect, it, vi} from 'vitest';
import {SignalConnectionState} from '../../api/SignalClient.ts';
import {publishDefaults, roomOptionDefaults} from '../defaults.ts';
import {TrackEvent} from '../events.ts';
import type RTCEngine from '../RTCEngine.ts';
import LocalAudioTrack from '../track/LocalAudioTrack.ts';
import {Track} from '../track/Track.ts';
import LocalParticipant from './LocalParticipant.ts';
class TestMediaStreamTrack extends EventTarget {
readonly id = 'microphone-input';
readonly kind = 'audio';
enabled = true;
readyState: MediaStreamTrackState = 'live';
constructor(private readonly channelCount: number) {
super();
}
getSettings(): MediaTrackSettings {
return {channelCount: this.channelCount, echoCancellation: true};
}
getConstraints(): MediaTrackConstraints {
return {};
}
stop() {
this.readyState = 'ended';
}
}
class TestMediaStream {
constructor(private readonly tracks: Array<MediaStreamTrack>) {}
getTracks() {
return this.tracks;
}
}
function createPublisher() {
const setTrackCodecBitrate = vi.fn();
const sendUpdateLocalAudioTrack = vi.fn();
const sender = {replaceTrack: vi.fn(async () => undefined)} as unknown as RTCRtpSender;
const transceiver = {sender} as RTCRtpTransceiver;
const addTrack = vi.fn(
async (request: AddTrackRequest) =>
new TrackInfo({
sid: 'TR_microphone',
name: request.name,
type: request.type,
source: request.source,
audioFeatures: request.audioFeatures,
}),
);
const engine = Object.assign(new EventEmitter(), {
isClosed: false,
logContext: {},
client: {currentState: SignalConnectionState.CONNECTED, sendUpdateLocalAudioTrack},
pcManager: {publisher: {getTransceivers: () => [transceiver], setTrackCodecBitrate}},
createSender: vi.fn(async () => sender),
negotiate: vi.fn(async () => undefined),
addTrack,
});
type ParticipantArgs = ConstructorParameters<typeof LocalParticipant>;
const participant = new LocalParticipant(
'PA_publisher',
'publisher',
engine as unknown as RTCEngine,
{...roomOptionDefaults, publishDefaults},
{} as ParticipantArgs[4],
{} as ParticipantArgs[5],
{} as ParticipantArgs[6],
{} as ParticipantArgs[7],
);
participant.permissions = new ParticipantPermission({canPublish: true});
return {participant, addTrack, setTrackCodecBitrate, sendUpdateLocalAudioTrack};
}
describe('microphone publication stereo metadata', () => {
beforeEach(() => {
vi.stubGlobal('MediaStreamTrack', TestMediaStreamTrack);
vi.stubGlobal('MediaStream', TestMediaStream);
});
afterEach(() => {
vi.unstubAllGlobals();
});
it.each([
{name: 'mono policy on a two-channel device', channelCount: 2, forceStereo: false, stereo: false},
{name: 'automatic stereo on a two-channel device', channelCount: 2, forceStereo: undefined, stereo: true},
{name: 'forced stereo on a one-channel device', channelCount: 1, forceStereo: true, stereo: true},
{name: 'automatic mono on a one-channel device', channelCount: 1, forceStereo: undefined, stereo: false},
])(
'keeps the request, SDP policy, and feature updates consistent for $name',
async ({channelCount, forceStereo, stereo}) => {
const {participant, addTrack, setTrackCodecBitrate, sendUpdateLocalAudioTrack} = createPublisher();
const source = new TestMediaStreamTrack(channelCount);
const track = new LocalAudioTrack(source as unknown as MediaStreamTrack);
track.source = Track.Source.Microphone;
await track.runWithTrackChangeLock(async () => undefined);
const publication = await participant.publishTrack(track, {
audioPreset: {maxBitrate: 64000},
forceStereo,
});
expect(addTrack).toHaveBeenCalledTimes(1);
const request = addTrack.mock.calls[0]![0];
expect(request.stereo).toBe(stereo);
expect(request.audioFeatures.includes(AudioTrackFeature.TF_STEREO)).toBe(stereo);
expect(request.audioFeatures).toContain(AudioTrackFeature.TF_ECHO_CANCELLATION);
expect(setTrackCodecBitrate).toHaveBeenCalledWith(expect.objectContaining({codec: 'opus', maxbr: 64, stereo}));
expect(publication.getTrackFeatures().includes(AudioTrackFeature.TF_STEREO)).toBe(stereo);
track.emit(TrackEvent.AudioTrackFeatureUpdate, track, AudioTrackFeature.TF_ECHO_CANCELLATION, true);
expect(sendUpdateLocalAudioTrack).toHaveBeenCalledTimes(1);
const [sid, features] = sendUpdateLocalAudioTrack.mock.calls[0]!;
expect(sid).toBe('TR_microphone');
expect(features.includes(AudioTrackFeature.TF_STEREO)).toBe(stereo);
expect(features).toContain(AudioTrackFeature.TF_ECHO_CANCELLATION);
track.stop();
},
);
});
@@ -966,7 +966,7 @@ export default class LocalParticipant extends Participant {
if (settings.noiseSuppression) {
audioFeatures.push(AudioTrackFeature.TF_NOISE_SUPPRESSION);
}
if (settings.channelCount && settings.channelCount > 1) {
if (isStereo) {
audioFeatures.push(AudioTrackFeature.TF_STEREO);
}
if (disableDtx) {
@@ -90,7 +90,7 @@ export default class LocalTrackPublication extends TrackPublication {
if (settings.noiseSuppression) {
features.add(AudioTrackFeature.TF_NOISE_SUPPRESSION);
}
if (settings.channelCount && settings.channelCount > 1) {
if (this.options?.forceStereo ?? (settings.channelCount !== undefined && settings.channelCount > 1)) {
features.add(AudioTrackFeature.TF_STEREO);
}
if (!this.options?.dtx) {
@@ -135,8 +135,7 @@ export const PlutoniumContent = observer(({defaultGiftMode = false}: PlutoniumCo
title={<Trans>Cancel subscription?</Trans>}
description={
<Trans>
You keep your perks until your next renewal date, then have a 3-day grace period to resubscribe and keep
your subscriber history.
You keep your perks until your next renewal date. Reactivate before then to keep your subscriber history.
</Trans>
}
primaryText={<Trans>Cancel subscription</Trans>}
@@ -463,6 +463,22 @@ export const SubscriptionCard: React.FC<SubscriptionCardProps> = observer(
</Trans>
);
})()
) : gracePeriodInfo.isPaymentRecovery ? (
(() => {
const graceDate = graceEndDate ? getFormattedLongDate(graceEndDate, locale) : undefined;
return (
<Trans comment="Plutonium subscription card text shown while a failed renewal payment is being retried. {graceDate} is a date already formatted and localized by code; never write a date into the translation.">
Your renewal payment failed but{' '}
<PerksButton
onClick={scrollToPerks}
data-flx="app.plutonium.subscription-card.perks-button.scroll-to-perks--9"
/>{' '}
stay active until{' '}
<strong data-flx="app.plutonium.subscription-card.strong--16">{graceDate}</strong>. Update your
payment method before then to keep your subscription.
</Trans>
);
})()
) : isInGracePeriod ? (
(() => {
const graceDate = graceEndDate ? getFormattedLongDate(graceEndDate, locale) : undefined;
@@ -844,7 +860,7 @@ export const SubscriptionCard: React.FC<SubscriptionCardProps> = observer(
<Trans comment="Billing button that starts subscription cancellation.">Cancel subscription</Trans>
</Button>
)}
{isInGracePeriod && (
{isInGracePeriod && !gracePeriodInfo.isPaymentRecovery && (
<Button
variant="danger"
onClick={handleEndPremiumGracePeriod}
@@ -1,6 +1,7 @@
// SPDX-License-Identifier: AGPL-3.0-or-later
import DeveloperOptions from '@app/features/devtools/state/DeveloperOptions';
import {getPremiumGraceEndDate} from '@app/features/premium/utils/PremiumGrace';
import type {User} from '@app/features/user/models/User';
import {UserPremiumTypes} from '@fluxer/constants/src/UserConstants';
import {MS_PER_DAY} from '@fluxer/date_utils/src/DateConstants';
@@ -12,6 +13,7 @@ export interface GracePeriodInfo {
isExpired: boolean;
graceEndDate: Date | null;
showExpiredState: boolean;
isPaymentRecovery: boolean;
}
export interface SubscriptionStatusInfo {
@@ -82,13 +84,25 @@ export const useSubscriptionStatus = (
const isGiftSubscription = Boolean(!billingCycle && hasPaidPremium && !isVisionary && premiumUntil);
const gracePeriodInfo = useMemo((): GracePeriodInfo => {
if (isVisionary) {
return {isInGracePeriod: false, isExpired: false, graceEndDate: null, showExpiredState: false};
return {
isInGracePeriod: false,
isExpired: false,
graceEndDate: null,
showExpiredState: false,
isPaymentRecovery: false,
};
}
const explicitGraceEnd = premiumGraceEndsAt ?? null;
const expiryDate = premiumUntil ? new Date(premiumUntil) : null;
const graceEndDate = explicitGraceEnd ?? (expiryDate ? new Date(expiryDate.getTime() + 3 * MS_PER_DAY) : null);
const graceEndDate = expiryDate ? getPremiumGraceEndDate(expiryDate, explicitGraceEnd) : explicitGraceEnd;
if (!graceEndDate) {
return {isInGracePeriod: false, isExpired: false, graceEndDate: null, showExpiredState: false};
return {
isInGracePeriod: false,
isExpired: false,
graceEndDate: null,
showExpiredState: false,
isPaymentRecovery: false,
};
}
const now = new Date();
const anchorDate = expiryDate ?? graceEndDate;
@@ -96,8 +110,9 @@ export const useSubscriptionStatus = (
const isInGracePeriod = (!expiryDate || now > expiryDate) && now <= graceEndDate;
const isExpired = now > graceEndDate;
const showExpiredState = isExpired && now <= expiredStateEndDate;
return {isInGracePeriod, isExpired, graceEndDate, showExpiredState};
}, [premiumUntil, premiumGraceEndsAt, isVisionary]);
const isPaymentRecovery = isInGracePeriod && explicitGraceEnd != null && billingCycle != null;
return {isInGracePeriod, isExpired, graceEndDate, showExpiredState, isPaymentRecovery};
}, [premiumUntil, premiumGraceEndsAt, isVisionary, billingCycle]);
const {isInGracePeriod, isExpired: isFullyExpired, showExpiredState} = gracePeriodInfo;
const isPremium = useDeveloperOverride
? hasPaidPremium && !isFullyExpired && !perksDisabled
@@ -21,6 +21,7 @@ import * as NotificationUtils from '@app/features/notification/utils/Notificatio
import NativePermission from '@app/features/permissions/system/state/NativePermission';
import {resolvePriceAnnouncementCampaign} from '@app/features/premium/config/PriceAnnouncementCampaign';
import PremiumState from '@app/features/premium/state/PremiumState';
import {getPremiumGraceEndDate} from '@app/features/premium/utils/PremiumGrace';
import {canServiceStripeSubscriptions, shouldShowPremiumFeatures} from '@app/features/premium/utils/PremiumUtils';
import StreamerMode from '@app/features/streamer_mode/state/StreamerMode';
import Nagbar from '@app/features/ui/state/Nagbar';
@@ -117,14 +118,11 @@ export const useNagbarConditions = (): NagbarConditions => {
if (!showPremium || !canServiceSubscription) return false;
if (nagbarState.forceHidePremiumGracePeriod) return false;
if (nagbarState.forcePremiumGracePeriod) return true;
if (!user?.premiumUntil || user.premiumType === 2 || premiumWillCancel) return false;
if (!user?.premiumUntil || !user.premiumGraceEndsAt || !user.premiumBillingCycle || user.premiumType === 2) {
return false;
}
const now = new Date();
const expiryDate = new Date(user.premiumUntil);
const gracePeriodMs = 3 * MS_PER_DAY;
const graceEndDate = user.premiumGraceEndsAt
? new Date(user.premiumGraceEndsAt)
: new Date(expiryDate.getTime() + gracePeriodMs);
const isInGracePeriod = now > expiryDate && now <= graceEndDate;
const isInGracePeriod = now > new Date(user.premiumUntil) && now <= new Date(user.premiumGraceEndsAt);
return isInGracePeriod && !nagbarState.premiumGracePeriodDismissed;
})();
const canShowPremiumExpired = (() => {
@@ -134,11 +132,8 @@ export const useNagbarConditions = (): NagbarConditions => {
if (!user?.premiumUntil || user.premiumType === 2 || premiumWillCancel) return false;
const now = new Date();
const expiryDate = new Date(user.premiumUntil);
const gracePeriodMs = 3 * MS_PER_DAY;
const expiredStateDurationMs = 30 * MS_PER_DAY;
const graceEndDate = user.premiumGraceEndsAt
? new Date(user.premiumGraceEndsAt)
: new Date(expiryDate.getTime() + gracePeriodMs);
const graceEndDate = getPremiumGraceEndDate(expiryDate, user.premiumGraceEndsAt);
const expiredStateEndDate = new Date(graceEndDate.getTime() + expiredStateDurationMs);
const isExpired = now > graceEndDate;
const showExpiredState = isExpired && now <= expiredStateEndDate;
@@ -8,12 +8,12 @@ import {NAGBAR_TONES, NagbarToneKind} from '@app/features/app/components/layout/
import {PREMIUM_PRODUCT_NAME} from '@app/features/app/config/I18nDisplayConstants';
import {Logger} from '@app/features/platform/utils/AppLogger';
import * as PremiumCommands from '@app/features/premium/commands/PremiumCommands';
import {getPremiumGraceEndDate} from '@app/features/premium/utils/PremiumGrace';
import {MANAGE_SUBSCRIPTION_DESCRIPTOR} from '@app/features/premium/utils/PremiumMessageDescriptors';
import * as NagbarCommands from '@app/features/ui/commands/NagbarCommands';
import {openExternalUrl} from '@app/features/ui/utils/NativeUtils';
import Users from '@app/features/user/state/Users';
import * as LocaleUtils from '@app/features/user/utils/LocaleUtils';
import {MS_PER_DAY} from '@fluxer/date_utils/src/DateConstants';
import {getFormattedLongDate} from '@fluxer/date_utils/src/DateFormatting';
import {msg} from '@lingui/core/macro';
import {useLingui} from '@lingui/react/macro';
@@ -62,10 +62,8 @@ export const PremiumGracePeriodNagbar = observer(({isMobile}: {isMobile: boolean
const handleDismiss = () => {
NagbarCommands.dismissNagbar('premiumGracePeriodDismissed');
};
if (!user?.premiumUntil || user?.premiumWillCancel) return null;
const expiryDate = new Date(user.premiumUntil);
const gracePeriodMs = 3 * MS_PER_DAY;
const graceEndDate = new Date(expiryDate.getTime() + gracePeriodMs);
if (!user?.premiumUntil) return null;
const graceEndDate = getPremiumGraceEndDate(new Date(user.premiumUntil), user.premiumGraceEndsAt);
const locale = LocaleUtils.getCurrentLocale();
const formattedGraceDate = getFormattedLongDate(graceEndDate, locale);
return (
@@ -20,6 +20,7 @@ import {handleGuildCountsUpdate} from '@app/features/guild/events/GuildCountsUpd
import {handleGuildCreate} from '@app/features/guild/events/GuildCreate';
import {handleGuildDelete} from '@app/features/guild/events/GuildDelete';
import {handleGuildEmojisUpdate} from '@app/features/guild/events/GuildEmojisUpdate';
import {handleGuildHealthUpdate} from '@app/features/guild/events/GuildHealthUpdate';
import {handleGuildMemberAdd} from '@app/features/guild/events/GuildMemberAdd';
import {handleGuildMemberListUpdate} from '@app/features/guild/events/GuildMemberListUpdate';
import {handleGuildMemberRemove} from '@app/features/guild/events/GuildMemberRemove';
@@ -112,6 +113,7 @@ export function createHandlerRegistry(): GatewayHandlerRegistry {
registry.set('GUILD_MEMBERS_CHUNK', handleGuildMembersChunk as GatewayEventHandler);
registry.set('GUILD_MEMBER_LIST_UPDATE', handleGuildMemberListUpdate as GatewayEventHandler);
registry.set('GUILD_COUNTS_UPDATE', handleGuildCountsUpdate as GatewayEventHandler);
registry.set('GUILD_HEALTH_UPDATE', handleGuildHealthUpdate as GatewayEventHandler);
registry.set('CHANNEL_MEMBER_COUNTS_UPDATE', handleChannelMemberCountsUpdate as GatewayEventHandler);
registry.set('GUILD_ROLE_CREATE', handleGuildRoleCreate as GatewayEventHandler);
registry.set('GUILD_ROLE_UPDATE', handleGuildRoleUpdate as GatewayEventHandler);
@@ -23,4 +23,5 @@ export type GuildReadyData = Readonly<{
joined_at: string;
unavailable?: boolean;
unavailable_hidden?: boolean;
degraded?: boolean;
}>;
@@ -48,6 +48,9 @@ export function handleGuildCreate(data: GuildReadyData, _context: GatewayHandler
return;
}
GuildAvailability.setGuildAvailable(data.id);
if (!isSync || data.degraded !== undefined) {
GuildAvailability.setGuildDegraded(data.id, data.degraded === true);
}
Guilds.handleGuildCreate(data);
GuildCount.handleGuildCreate(data);
if (!isSync) {
@@ -32,6 +32,7 @@ interface GuildDeletePayload {
}
export function handleGuildDelete(data: GuildDeletePayload, _context: GatewayHandlerContext): void {
GuildAvailability.setGuildDegraded(data.id, false);
GuildAvailability.handleGuildAvailability(data.id, data.unavailable, data.unavailable_hidden);
Guilds.handleGuildDelete({guildId: data.id, unavailable: data.unavailable});
GuildList.handleGuildDelete(data.id, data.unavailable);
@@ -0,0 +1,10 @@
// SPDX-License-Identifier: AGPL-3.0-or-later
import GuildAvailability from '@app/features/guild/state/GuildAvailability';
import Guilds from '@app/features/guild/state/Guilds';
export function handleGuildHealthUpdate(data: {guild_id: string; degraded: boolean}): void {
if (Guilds.getGuild(data.guild_id)) {
GuildAvailability.setGuildDegraded(data.guild_id, data.degraded);
}
}
@@ -5,12 +5,14 @@ import {makeAutoObservable, observable} from 'mobx';
class GuildAvailability {
unavailableGuilds: Set<string> = observable.set();
degradedGuilds: Set<string> = observable.set();
constructor() {
makeAutoObservable(
this,
{
unavailableGuilds: false,
degradedGuilds: false,
},
{autoBind: true},
);
@@ -23,11 +25,20 @@ class GuildAvailability {
}
setGuildUnavailable(guildId: string): void {
this.degradedGuilds.delete(guildId);
if (!this.unavailableGuilds.has(guildId)) {
this.unavailableGuilds.add(guildId);
}
}
setGuildDegraded(guildId: string, degraded: boolean): void {
if (degraded) {
this.degradedGuilds.add(guildId);
} else {
this.degradedGuilds.delete(guildId);
}
}
handleGuildAvailability(guildId: string, unavailable = false, unavailableHidden = false): void {
if (unavailable && !unavailableHidden) {
this.setGuildUnavailable(guildId);
@@ -38,7 +49,11 @@ class GuildAvailability {
loadUnavailableGuilds(guilds: ReadonlyArray<GuildReadyData>): void {
this.unavailableGuilds.clear();
this.degradedGuilds.clear();
for (const guild of guilds) {
if (guild.degraded && !guild.unavailable) {
this.degradedGuilds.add(guild.id);
}
if (guild.unavailable && !guild.unavailable_hidden) {
this.unavailableGuilds.add(guild.id);
}
@@ -2471,7 +2471,7 @@ msgid "A Linux desktop update is available. Choose the package format for this s
msgstr "يتوفر تحديث لتطبيق سطح المكتب على Linux. اختر تنسيق الحزمة لهذا النظام وسيحفظه {productName} محليًا."
#. Plutonium subscription card line offering a move to a lower price. {listPriceEffectiveDate} is a date already formatted and localized by code; never write a date into the translation.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:684
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:700
msgid "A lower price is available. Switching takes effect on <0>{listPriceEffectiveDate}</0> and changes nothing else."
msgstr "يتوفر سعر أقل. يسري التبديل اعتبارًا من <0>{listPriceEffectiveDate}</0> ولا يغيّر أي شيء آخر."
@@ -3487,19 +3487,19 @@ msgstr "عناصر التحكم في المحاذاة متاحة فقط على
msgid "All"
msgstr "الكل"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:524
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:540
msgid "All <0/> for <1>{effectiveMonthlyPrice}/month</1>."
msgstr "جميع <0/> مقابل <1>{effectiveMonthlyPrice} شهريًا</1>."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:546
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:562
msgid "All <0/> for <1>{effectiveYearlyPrice}/year</1>."
msgstr "جميع <0/> مقابل <1>{effectiveYearlyPrice} سنويًا</1>."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:567
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:583
msgid "All <0/> included with your subscription."
msgstr "جميع <0/> مشمولة في اشتراكك."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:514
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:530
msgid "All <0/>, forever. No billing, no renewals."
msgstr "جميع <0/> للأبد. بلا فواتير ولا تجديدات."
@@ -6469,7 +6469,7 @@ msgid "Cancel import"
msgstr "إلغاء الاستيراد"
#. Billing button that cancels a scheduled move to a lower subscription price.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:821
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:837
msgid "Cancel price change"
msgstr "إلغاء تغيير السعر"
@@ -6484,14 +6484,14 @@ msgid "Cancel request"
msgstr "إلغاء الطلب"
#. Billing button that cancels a scheduled billing-cycle change.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:829
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:845
msgid "Cancel scheduled switch"
msgstr "إلغاء التبديل المجدول"
#. Billing button that starts subscription cancellation.
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:844
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:142
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:860
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:141
#: src/features/user/components/settings_utils/search_index/PlutoniumIndex.ts:31
msgid "Cancel subscription"
msgstr "إلغاء الاشتراك"
@@ -6501,7 +6501,7 @@ msgid "Cancel subscription?"
msgstr "هل تريد إلغاء الاشتراك؟"
#. Plutonium subscription card hint shown to a subscriber who could move to a lower price but has another billing change already scheduled.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:647
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:663
msgid "Cancel the scheduled change to move to the current price instead."
msgstr "ألغِ التغيير المجدول للانتقال إلى السعر الحالي بدلاً من ذلك."
@@ -6511,7 +6511,7 @@ msgid "Cancel upload"
msgstr "إلغاء التحميل"
#. Billing button that cancels a scheduled yearly upgrade.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:825
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:841
msgid "Cancel yearly upgrade"
msgstr "إلغاء الترقية السنوية"
@@ -6530,7 +6530,7 @@ msgstr "سيتم الإلغاء"
msgid "Cancellation"
msgstr "إلغاء الصدى"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:501
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:517
msgid "Cancels on <0>{cancelDate}</0>. <1/> remain active until then."
msgstr "سيتم الإلغاء في <0>{cancelDate}</0>. تظل <1/> سارية حتى ذلك الحين."
@@ -10872,7 +10872,7 @@ msgstr "مخصص…"
#. Billing button that opens the external customer portal.
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:750
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:766
#: src/features/user/components/settings_utils/search_index/PlutoniumIndex.ts:39
msgid "Customer portal"
msgstr "بوابة العملاء"
@@ -13877,15 +13877,15 @@ msgid "End date"
msgstr "تاريخ الانتهاء"
#. Billing button that ends premium grace period immediately.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:856
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:872
msgid "End grace now"
msgstr "إنهاء فترة السماح الآن"
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:164
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:163
msgid "End grace period"
msgstr "إنهاء فترة السماح"
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:157
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:156
msgid "End grace period now?"
msgstr "إنهاء فترة السماح الآن؟"
@@ -16347,7 +16347,7 @@ msgstr "هدية: تنتهي صلاحيتها قريبًا"
msgid "Gift: grace period (still have access)"
msgstr "هدية: فترة سماح (لا يزال لديك حق الوصول)"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:486
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:502
msgid "Gifted <0/> until <1>{giftEndDate}</1>. Does not renew automatically. Redeem more gift codes to extend."
msgstr "<0/> مُهدى حتى <1>{giftEndDate}</1>. لا يتجدد تلقائيًا. استرد المزيد من رموز الهدايا لتمديده."
@@ -16826,7 +16826,7 @@ msgid "Hate speech"
msgstr "خطاب الكراهية"
#. Premium page text shown on an instance where the premium tier cannot be bought, only redeemed. {PREMIUM_PRODUCT_NAME} is the premium tier name.
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:297
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:296
msgid "Have a gift code? Redeem it to unlock {PREMIUM_PRODUCT_NAME}."
msgstr "هل لديك رمز هدية؟ استبدله لفتح {PREMIUM_PRODUCT_NAME}."
@@ -18926,7 +18926,7 @@ msgstr "الاحتفاظ بالمرفقات عند إفراغ نص الرسال
msgid "Keep free and premium tiers. You can customize the tiers, sell premium through Stripe, or hand out gift codes later from the admin panel."
msgstr "حافظ على المستويات المجانية والمدفوعة. يمكنك تخصيص المستويات، أو البيع عبر Stripe، أو توزيع رموز هدايا لاحقًا من لوحة التحكم."
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:166
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:165
msgid "Keep grace period"
msgstr "الاحتفاظ بفترة السماح"
@@ -18940,7 +18940,7 @@ msgstr "إبقاء Neko ثابتًا"
msgid "Keep running"
msgstr "مواصلة التشغيل"
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:144
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:143
msgid "Keep subscription"
msgstr "الاحتفاظ بالاشتراك"
@@ -19297,8 +19297,8 @@ msgstr "زر الفأرة الأيسر"
msgid "Left tooltip"
msgstr "تلميح لليسار"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:539
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:561
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:555
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:577
msgid "Legacy rate"
msgstr "السعر القديم"
@@ -21339,11 +21339,11 @@ msgstr "شهريًا"
msgid "Monthly {monthlyPrice}"
msgstr "شهريًا {monthlyPrice}"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:631
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:647
msgid "Monthly billing starts on <0>{pendingChangeDate}</0>."
msgstr "تبدأ الفوترة الشهرية في <0>{pendingChangeDate}</0>."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:624
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:640
msgid "Monthly billing starts on <0>{pendingChangeDate}</0>. First monthly charge: {pendingInitialPriceLabel}. Future monthly renewals: {pendingRecurringPriceLabel}/month."
msgstr "تبدأ الفوترة الشهرية في <0>{pendingChangeDate}</0>. أول رسوم شهرية: {pendingInitialPriceLabel}. التجديدات الشهرية اللاحقة: {pendingRecurringPriceLabel}/شهر."
@@ -22269,12 +22269,12 @@ msgid "New password"
msgstr "كلمة مرور جديدة"
#. Plutonium subscription card line shown when a move to a lower price is scheduled but the new amount is unknown. {pendingChangeDate} is a date already formatted and localized by code; never write a date into the translation.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:595
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:611
msgid "New price scheduled for <0>{pendingChangeDate}</0>."
msgstr "من المقرر تطبيق سعر جديد في <0>{pendingChangeDate}</0>."
#. Plutonium subscription card line shown when a move to a lower price is scheduled. {pendingChangeDate} is a date and {pendingTargetPriceLabel} is a currency amount, both already formatted and localized by code; never write a date or an amount into the translation.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:589
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:605
msgid "New price scheduled for <0>{pendingChangeDate}</0>. Renewals will be {pendingTargetPriceLabel} from then on."
msgstr "من المقرر تطبيق سعر جديد في <0>{pendingChangeDate}</0>. سيكون التجديد بسعر {pendingTargetPriceLabel} من ذلك الحين فصاعدًا."
@@ -26152,7 +26152,7 @@ msgstr "التفاعلات"
#. Billing button that cancels a scheduled subscription cancellation.
#. Button label on the premium-expired nagbar. Opens billing so the user can reactivate their subscription.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:746
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:762
#: src/features/app/components/layout/app_layout/nagbars/PremiumExpiredNagbar.tsx:25
msgid "Reactivate"
msgstr "إعادة التفعيل"
@@ -26375,8 +26375,8 @@ msgstr "استرداد لنفسك"
#. Billing button for entering a premium gift code.
#. Billing button for entering a premium gift code.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:719
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:307
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:735
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:306
msgid "Redeem gift code"
msgstr "استرداد رمز الهدية"
@@ -27147,7 +27147,7 @@ msgstr "عتبة التجديد (بالأيام)"
msgid "Renew window (days)"
msgstr "فترة التجديد (بالأيام)"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:701
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:717
msgid "Renews on <0>{renewalDate}.</0>"
msgstr "يتجدد في <0>{renewalDate}.</0>"
@@ -27896,8 +27896,8 @@ msgstr "استعادة النافذة"
#. Billing button for restarting a subscription during the grace period.
#. Billing button for starting a new subscription after premium expired.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:738
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:742
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:754
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:758
msgid "Resubscribe"
msgstr "إعادة الاشتراك"
@@ -32521,7 +32521,7 @@ msgid "Switch price"
msgstr "تبديل السعر"
#. Billing button that opens confirmation to move the subscription down to the current price. {listPriceNewLabel} is the localized new price.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:806
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:822
msgid "Switch to {listPriceNewLabel}"
msgstr "التبديل إلى {listPriceNewLabel}"
@@ -32546,7 +32546,7 @@ msgstr "التبديل إلى الإدخال المباشر"
#. Billing button that opens confirmation to switch to monthly billing.
#. Button confirming a change to monthly subscription billing.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:57
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:789
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:805
msgid "Switch to monthly"
msgstr "التبديل إلى الفوترة الشهرية"
@@ -32615,7 +32615,7 @@ msgstr "التبديل إلى عمودين"
#. Billing button that opens confirmation to switch to yearly billing.
#. Button confirming a change to yearly subscription billing.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:53
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:785
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:801
msgid "Switch to yearly"
msgstr "التبديل إلى الفوترة السنوية"
@@ -35865,7 +35865,7 @@ msgstr "افتح الرموز التعبيرية المخصصة في الرسا
msgid "Unlock HD screen share with {premiumProductName}"
msgstr "افتح مشاركة الشاشة عالية الدقة باستخدام {premiumProductName}"
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:217
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:216
msgid "Unlock higher limits and exclusive features while supporting an independent communication platform."
msgstr "احصل على حدود أعلى وميزات حصرية مع دعم منصة تواصل مستقلة."
@@ -39015,15 +39015,15 @@ msgstr "سنويًا {yearlyPrice}"
msgid "Yearly gift"
msgstr "هدية سنوية"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:618
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:634
msgid "Yearly upgrade scheduled for <0>{pendingChangeDate}</0>."
msgstr "الترقية السنوية مجدولة بتاريخ <0>{pendingChangeDate}</0>."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:603
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:619
msgid "Yearly upgrade scheduled for <0>{pendingChangeDate}</0>. First yearly charge: {pendingInitialPriceLabel} after a {pendingCreditPriceLabel} credit. Future yearly renewals: {pendingRecurringPriceLabel}/year."
msgstr "الترقية السنوية مجدولة بتاريخ <0>{pendingChangeDate}</0>. أول رسوم سنوية: {pendingInitialPriceLabel} بعد خصم رصيد بقيمة {pendingCreditPriceLabel}. التجديدات السنوية المستقبلية: {pendingRecurringPriceLabel} سنويًا."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:610
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:626
msgid "Yearly upgrade scheduled for <0>{pendingChangeDate}</0>. First yearly charge: {pendingInitialPriceLabel}. Future yearly renewals: {pendingRecurringPriceLabel}/year."
msgstr "الترقية السنوية مجدولة بتاريخ <0>{pendingChangeDate}</0>. أول رسوم سنوية: {pendingInitialPriceLabel}. التجديدات السنوية المستقبلية: {pendingRecurringPriceLabel} سنويًا."
@@ -39493,10 +39493,10 @@ msgid "You just pressed Tab. Keyboard mode is now on so you can navigate {produc
msgstr "لقد ضغطت على Tab للتو. وضع لوحة المفاتيح قيد التشغيل الآن حتى تتمكن من التنقل في {productName} دون استخدام الماوس."
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:137
msgid "You keep your perks until your next renewal date, then have a 3-day grace period to resubscribe and keep your subscriber history."
msgstr "ستحتفظ بمزاياك حتى تاريخ التجديد التالي، ثم تحصل على فترة سماح مدتها 3 أيام لإعادة الاشتراك والاحتفاظ بسجل اشتراكك."
msgid "You keep your perks until your next renewal date. Reactivate before then to keep your subscriber history."
msgstr "ستحتفظ بمزاياك حتى تاريخ التجديد التالي. أعد تفعيل اشتراكك قبل ذلك للاحتفاظ بسجل اشتراكك."
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:159
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:158
msgid "You lose all {PREMIUM_PRODUCT_NAME} perks immediately and your subscriber history resets. This cannot be undone."
msgstr "ستفقد جميع مزايا {PREMIUM_PRODUCT_NAME} على الفور وستتم إعادة تعيين سجل اشتراكك. لا يمكن التراجع عن هذا الإجراء."
@@ -40231,6 +40231,11 @@ msgstr "منطقتك"
msgid "Your registration needs an extra anti-spam check before you can continue."
msgstr "يتطلب تسجيلك فحصًا إضافيًا لمكافحة الرسائل المزعجة قبل أن تتمكن من المتابعة."
#. Plutonium subscription card text shown while a failed renewal payment is being retried. {graceDate} is a date already formatted and localized by code; never write a date into the translation.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:470
msgid "Your renewal payment failed but <0/> stay active until <1>{graceDate}</1>. Update your payment method before then to keep your subscription."
msgstr "فشل دفع تجديد اشتراكك، لكن <0/> ستظل نشطة حتى <1>{graceDate}</1>. حدّث طريقة الدفع قبل ذلك التاريخ للاحتفاظ باشتراكك."
#. Video settings note shown when the saved screen share quality is above what this account can send. Resolutions are short labels such as 1440p or Source and rates are whole numbers. FPS is a technical token.
#: src/features/user/components/modals/tabs/UserVideoTab.tsx:92
msgid "Your saved {savedResolution} at {savedFrameRate} FPS needs {premiumProductName}, so shares use {resolution} at {frameRate} FPS."
@@ -40252,7 +40257,7 @@ msgstr "البث المباشر الخاص بك لا يزال نشطًا"
msgid "Your subscription can't move to the new price right now."
msgstr "لا يمكن نقل اشتراكك إلى السعر الجديد في الوقت الحالي."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:470
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:486
msgid "Your subscription ended but <0/> stay active until <1>{graceDate}</1>. Resubscribe before then to keep your subscriber history."
msgstr "انتهى اشتراكك، لكن <0/> ستظل نشطة حتى <1>{graceDate}</1>. أعد الاشتراك قبل ذلك التاريخ للاحتفاظ بسجل اشتراكك."
@@ -40281,7 +40286,7 @@ msgstr "تم تحويل اشتراكك إلى الفوترة الشهرية."
msgid "Your subscription has been switched to yearly billing."
msgstr "تم تحويل اشتراكك إلى الفوترة السنوية."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:512
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:528
msgid "Your subscription is active but perks are temporarily paused."
msgstr "اشتراكك نشط، ولكن المزايا متوقفة مؤقتًا."
@@ -40301,7 +40306,7 @@ msgid "Your subscription moves to the new price on {effectiveDate}."
msgstr "سينتقل اشتراكك إلى السعر الجديد في {effectiveDate}."
#. Plutonium subscription card line shown to a subscriber on a legacy price whose subscription is already set to cancel. {cancelDate} is a date and {listPriceNewLabel} is a currency amount, both already formatted and localized by code; never write a date or an amount into the translation.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:666
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:682
msgid "Your subscription still ends on <0>{cancelDate}</0>. The current price is now {listPriceNewLabel}. If you reactivate, you can switch to it from here."
msgstr "سينتهي اشتراكك في <0>{cancelDate}</0> كما هو مقرر. السعر الحالي الآن {listPriceNewLabel}. إذا أعدت التفعيل، يمكنك التبديل إليه من هنا."
@@ -2471,7 +2471,7 @@ msgid "A Linux desktop update is available. Choose the package format for this s
msgstr "Налична е актуализация за настолното приложение на Linux. Избери формата на пакета за тази система и {productName} ще я запази локално."
#. Plutonium subscription card line offering a move to a lower price. {listPriceEffectiveDate} is a date already formatted and localized by code; never write a date into the translation.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:684
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:700
msgid "A lower price is available. Switching takes effect on <0>{listPriceEffectiveDate}</0> and changes nothing else."
msgstr "Предлага се по-ниска цена. Преминаването влиза в сила на <0>{listPriceEffectiveDate}</0> и не променя нищо друго."
@@ -3487,19 +3487,19 @@ msgstr "Контролите за подравняване са налични
msgid "All"
msgstr "Всички"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:524
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:540
msgid "All <0/> for <1>{effectiveMonthlyPrice}/month</1>."
msgstr "Всички <0/> за <1>{effectiveMonthlyPrice}/месец</1>."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:546
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:562
msgid "All <0/> for <1>{effectiveYearlyPrice}/year</1>."
msgstr "Всички <0/> за <1>{effectiveYearlyPrice}/година</1>."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:567
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:583
msgid "All <0/> included with your subscription."
msgstr "Всички <0/> са включени в абонамента ти."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:514
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:530
msgid "All <0/>, forever. No billing, no renewals."
msgstr "Всички <0/>, завинаги. Без таксуване и подновявания."
@@ -6469,7 +6469,7 @@ msgid "Cancel import"
msgstr "Отказ на импортирането"
#. Billing button that cancels a scheduled move to a lower subscription price.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:821
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:837
msgid "Cancel price change"
msgstr "Отказ на промяната на цената"
@@ -6484,14 +6484,14 @@ msgid "Cancel request"
msgstr "Отмяна на поканата"
#. Billing button that cancels a scheduled billing-cycle change.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:829
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:845
msgid "Cancel scheduled switch"
msgstr "Отказ на планираната промяна"
#. Billing button that starts subscription cancellation.
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:844
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:142
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:860
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:141
#: src/features/user/components/settings_utils/search_index/PlutoniumIndex.ts:31
msgid "Cancel subscription"
msgstr "Отказ от абонамент"
@@ -6501,7 +6501,7 @@ msgid "Cancel subscription?"
msgstr "Да откажеш ли абонамента?"
#. Plutonium subscription card hint shown to a subscriber who could move to a lower price but has another billing change already scheduled.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:647
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:663
msgid "Cancel the scheduled change to move to the current price instead."
msgstr "Отмени планираната промяна, за да преминеш към текущата цена вместо това."
@@ -6511,7 +6511,7 @@ msgid "Cancel upload"
msgstr "Отказ на качването"
#. Billing button that cancels a scheduled yearly upgrade.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:825
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:841
msgid "Cancel yearly upgrade"
msgstr "Отказ на годишното надграждане"
@@ -6530,7 +6530,7 @@ msgstr "Анулиране"
msgid "Cancellation"
msgstr "Потискане на ехото"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:501
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:517
msgid "Cancels on <0>{cancelDate}</0>. <1/> remain active until then."
msgstr "Анулира се на <0>{cancelDate}</0>. <1/> остават активни дотогава."
@@ -10872,7 +10872,7 @@ msgstr "По избор…"
#. Billing button that opens the external customer portal.
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:750
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:766
#: src/features/user/components/settings_utils/search_index/PlutoniumIndex.ts:39
msgid "Customer portal"
msgstr "Клиентски портал"
@@ -13877,15 +13877,15 @@ msgid "End date"
msgstr "Крайна дата"
#. Billing button that ends premium grace period immediately.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:856
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:872
msgid "End grace now"
msgstr "Прекратяване сега"
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:164
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:163
msgid "End grace period"
msgstr "Край на гратисния период"
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:157
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:156
msgid "End grace period now?"
msgstr "Да се прекрати ли гратисният период сега?"
@@ -16347,7 +16347,7 @@ msgstr "Подарък: изтича скоро"
msgid "Gift: grace period (still have access)"
msgstr "Подарък: гратисен период (все още имаш достъп)"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:486
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:502
msgid "Gifted <0/> until <1>{giftEndDate}</1>. Does not renew automatically. Redeem more gift codes to extend."
msgstr "Подарено <0/> до <1>{giftEndDate}</1>. Не се подновява автоматично. Осребри още кодове за подарък, за да удължиш."
@@ -16826,7 +16826,7 @@ msgid "Hate speech"
msgstr "Език на омразата"
#. Premium page text shown on an instance where the premium tier cannot be bought, only redeemed. {PREMIUM_PRODUCT_NAME} is the premium tier name.
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:297
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:296
msgid "Have a gift code? Redeem it to unlock {PREMIUM_PRODUCT_NAME}."
msgstr "Имате код за подарък? Осребрете го, за да отключите {PREMIUM_PRODUCT_NAME}."
@@ -18926,7 +18926,7 @@ msgstr "Запазване на прикачени файлове при изч
msgid "Keep free and premium tiers. You can customize the tiers, sell premium through Stripe, or hand out gift codes later from the admin panel."
msgstr "Запазете безплатни и премиум нива. Можете да персонализирате нивата, да продавате премиум чрез Stripe или по-късно да раздавате кодове за подаръци от административния панел."
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:166
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:165
msgid "Keep grace period"
msgstr "Запазване на гратисния период"
@@ -18940,7 +18940,7 @@ msgstr "Спиране на движението на Неко"
msgid "Keep running"
msgstr "Работа във фонов режим"
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:144
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:143
msgid "Keep subscription"
msgstr "Запазване на абонамента"
@@ -19297,8 +19297,8 @@ msgstr "Ляв бутон на мишката"
msgid "Left tooltip"
msgstr "Подсказка отляво"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:539
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:561
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:555
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:577
msgid "Legacy rate"
msgstr "Стара цена"
@@ -21339,11 +21339,11 @@ msgstr "Месечно"
msgid "Monthly {monthlyPrice}"
msgstr "Месечно {monthlyPrice}"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:631
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:647
msgid "Monthly billing starts on <0>{pendingChangeDate}</0>."
msgstr "Месечното таксуване започва на <0>{pendingChangeDate}</0>."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:624
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:640
msgid "Monthly billing starts on <0>{pendingChangeDate}</0>. First monthly charge: {pendingInitialPriceLabel}. Future monthly renewals: {pendingRecurringPriceLabel}/month."
msgstr "Месечното таксуване започва на <0>{pendingChangeDate}</0>. Първа месечна такса: {pendingInitialPriceLabel}. Бъдещи месечни подновявания: {pendingRecurringPriceLabel}/месец."
@@ -22269,12 +22269,12 @@ msgid "New password"
msgstr "Нова парола"
#. Plutonium subscription card line shown when a move to a lower price is scheduled but the new amount is unknown. {pendingChangeDate} is a date already formatted and localized by code; never write a date into the translation.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:595
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:611
msgid "New price scheduled for <0>{pendingChangeDate}</0>."
msgstr "Нова цена е насрочена за <0>{pendingChangeDate}</0>."
#. Plutonium subscription card line shown when a move to a lower price is scheduled. {pendingChangeDate} is a date and {pendingTargetPriceLabel} is a currency amount, both already formatted and localized by code; never write a date or an amount into the translation.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:589
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:605
msgid "New price scheduled for <0>{pendingChangeDate}</0>. Renewals will be {pendingTargetPriceLabel} from then on."
msgstr "Нова цена е насрочена за <0>{pendingChangeDate}</0>. След това подновяванията ще бъдат {pendingTargetPriceLabel}."
@@ -26152,7 +26152,7 @@ msgstr "Реакции"
#. Billing button that cancels a scheduled subscription cancellation.
#. Button label on the premium-expired nagbar. Opens billing so the user can reactivate their subscription.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:746
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:762
#: src/features/app/components/layout/app_layout/nagbars/PremiumExpiredNagbar.tsx:25
msgid "Reactivate"
msgstr "Активиране отново"
@@ -26375,8 +26375,8 @@ msgstr "Осребри за себе си"
#. Billing button for entering a premium gift code.
#. Billing button for entering a premium gift code.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:719
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:307
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:735
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:306
msgid "Redeem gift code"
msgstr "Осребряване на код за подарък"
@@ -27147,7 +27147,7 @@ msgstr "Праг на подновяване (дни)"
msgid "Renew window (days)"
msgstr "Период за подновяване (дни)"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:701
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:717
msgid "Renews on <0>{renewalDate}.</0>"
msgstr "Подновява се на <0>{renewalDate}.</0>"
@@ -27896,8 +27896,8 @@ msgstr "Възстановяване на прозореца"
#. Billing button for restarting a subscription during the grace period.
#. Billing button for starting a new subscription after premium expired.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:738
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:742
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:754
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:758
msgid "Resubscribe"
msgstr "Абониране отново"
@@ -32521,7 +32521,7 @@ msgid "Switch price"
msgstr "Смяна на цена"
#. Billing button that opens confirmation to move the subscription down to the current price. {listPriceNewLabel} is the localized new price.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:806
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:822
msgid "Switch to {listPriceNewLabel}"
msgstr "Премини към {listPriceNewLabel}"
@@ -32546,7 +32546,7 @@ msgstr "Превключване към директен вход"
#. Billing button that opens confirmation to switch to monthly billing.
#. Button confirming a change to monthly subscription billing.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:57
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:789
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:805
msgid "Switch to monthly"
msgstr "Премини към месечно таксуване"
@@ -32615,7 +32615,7 @@ msgstr "Превключване към две колони"
#. Billing button that opens confirmation to switch to yearly billing.
#. Button confirming a change to yearly subscription billing.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:53
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:785
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:801
msgid "Switch to yearly"
msgstr "Премини към годишно таксуване"
@@ -35865,7 +35865,7 @@ msgstr "Отключи персонализирани емоджита в DM с
msgid "Unlock HD screen share with {premiumProductName}"
msgstr "Отключи споделяне на екран в HD с {premiumProductName}"
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:217
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:216
msgid "Unlock higher limits and exclusive features while supporting an independent communication platform."
msgstr "Отключи по-високи лимити и ексклузивни функции, докато подкрепяш независима комуникационна платформа."
@@ -39015,15 +39015,15 @@ msgstr "Годишно {yearlyPrice}"
msgid "Yearly gift"
msgstr "Годишен подарък"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:618
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:634
msgid "Yearly upgrade scheduled for <0>{pendingChangeDate}</0>."
msgstr "Годишно надграждане, насрочено за <0>{pendingChangeDate}</0>."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:603
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:619
msgid "Yearly upgrade scheduled for <0>{pendingChangeDate}</0>. First yearly charge: {pendingInitialPriceLabel} after a {pendingCreditPriceLabel} credit. Future yearly renewals: {pendingRecurringPriceLabel}/year."
msgstr "Годишно надграждане, насрочено за <0>{pendingChangeDate}</0>. Първо годишно таксуване: {pendingInitialPriceLabel} след кредит от {pendingCreditPriceLabel}. Бъдещи годишни подновявания: {pendingRecurringPriceLabel}/година."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:610
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:626
msgid "Yearly upgrade scheduled for <0>{pendingChangeDate}</0>. First yearly charge: {pendingInitialPriceLabel}. Future yearly renewals: {pendingRecurringPriceLabel}/year."
msgstr "Годишно надграждане, насрочено за <0>{pendingChangeDate}</0>. Първо годишно таксуване: {pendingInitialPriceLabel}. Бъдещи годишни подновявания: {pendingRecurringPriceLabel}/година."
@@ -39493,10 +39493,10 @@ msgid "You just pressed Tab. Keyboard mode is now on so you can navigate {produc
msgstr "Току-що натисна Tab. Режимът за навигация с клавиатура вече е включен, за да можеш да използваш {productName} без мишка."
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:137
msgid "You keep your perks until your next renewal date, then have a 3-day grace period to resubscribe and keep your subscriber history."
msgstr "Запазваш предимствата си до следващата дата на подновяване, след което имаш 3-дневен гратисен период, за да се абонираш отново и да запазиш историята си като абонат."
msgid "You keep your perks until your next renewal date. Reactivate before then to keep your subscriber history."
msgstr "Запазваш предимствата си до следващата дата на подновяване. Активирай абонамента отново преди това, за да запазиш историята си като абонат."
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:159
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:158
msgid "You lose all {PREMIUM_PRODUCT_NAME} perks immediately and your subscriber history resets. This cannot be undone."
msgstr "Веднага губиш всички предимства на {PREMIUM_PRODUCT_NAME} и историята ти като абонат се нулира. Това не може да бъде отменено."
@@ -40231,6 +40231,11 @@ msgstr "твоя регион"
msgid "Your registration needs an extra anti-spam check before you can continue."
msgstr "Регистрацията ти изисква допълнителна проверка срещу спам, преди да продължиш."
#. Plutonium subscription card text shown while a failed renewal payment is being retried. {graceDate} is a date already formatted and localized by code; never write a date into the translation.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:470
msgid "Your renewal payment failed but <0/> stay active until <1>{graceDate}</1>. Update your payment method before then to keep your subscription."
msgstr "Плащането за подновяване не успя, но <0/> остават активни до <1>{graceDate}</1>. Обнови начина си на плащане преди тази дата, за да запазиш абонамента си."
#. Video settings note shown when the saved screen share quality is above what this account can send. Resolutions are short labels such as 1440p or Source and rates are whole numbers. FPS is a technical token.
#: src/features/user/components/modals/tabs/UserVideoTab.tsx:92
msgid "Your saved {savedResolution} at {savedFrameRate} FPS needs {premiumProductName}, so shares use {resolution} at {frameRate} FPS."
@@ -40252,7 +40257,7 @@ msgstr "Потокът ти все още е на живо"
msgid "Your subscription can't move to the new price right now."
msgstr "Абонаментът ти не може да премине към новата цена в момента."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:470
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:486
msgid "Your subscription ended but <0/> stay active until <1>{graceDate}</1>. Resubscribe before then to keep your subscriber history."
msgstr "Абонаментът ти приключи, но <0/> остават активни до <1>{graceDate}</1>. Абонирай се отново преди тази дата, за да запазиш историята си като абонат."
@@ -40281,7 +40286,7 @@ msgstr "Абонаментът ти е превключен към месечн
msgid "Your subscription has been switched to yearly billing."
msgstr "Абонаментът ти е превключен към годишно таксуване."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:512
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:528
msgid "Your subscription is active but perks are temporarily paused."
msgstr "Абонаментът ти е активен, но предимствата са временно на пауза."
@@ -40301,7 +40306,7 @@ msgid "Your subscription moves to the new price on {effectiveDate}."
msgstr "Абонаментът ти преминава към новата цена на {effectiveDate}."
#. Plutonium subscription card line shown to a subscriber on a legacy price whose subscription is already set to cancel. {cancelDate} is a date and {listPriceNewLabel} is a currency amount, both already formatted and localized by code; never write a date or an amount into the translation.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:666
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:682
msgid "Your subscription still ends on <0>{cancelDate}</0>. The current price is now {listPriceNewLabel}. If you reactivate, you can switch to it from here."
msgstr "Абонаментът ти все още приключва на <0>{cancelDate}</0>. Текущата цена вече е {listPriceNewLabel}. Ако го активираш отново, можеш да преминеш към нея оттук."
@@ -2471,7 +2471,7 @@ msgid "A Linux desktop update is available. Choose the package format for this s
msgstr "Je k dispozici aktualizace desktopové aplikace pro Linux. Vyberte formát balíčku pro tento systém a aplikace {productName} jej uloží do počítače."
#. Plutonium subscription card line offering a move to a lower price. {listPriceEffectiveDate} is a date already formatted and localized by code; never write a date into the translation.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:684
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:700
msgid "A lower price is available. Switching takes effect on <0>{listPriceEffectiveDate}</0> and changes nothing else."
msgstr "Je k dispozici nižší cena. Přechod začne platit <0>{listPriceEffectiveDate}</0> a nic jiného se nezmění."
@@ -3487,19 +3487,19 @@ msgstr "Ovládací prvky zarovnání jsou dostupné pouze na širších obrazovk
msgid "All"
msgstr "Vše"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:524
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:540
msgid "All <0/> for <1>{effectiveMonthlyPrice}/month</1>."
msgstr "Všechny <0/> za <1>{effectiveMonthlyPrice}/měsíc</1>."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:546
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:562
msgid "All <0/> for <1>{effectiveYearlyPrice}/year</1>."
msgstr "Všechny <0/> za <1>{effectiveYearlyPrice}/rok</1>."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:567
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:583
msgid "All <0/> included with your subscription."
msgstr "Všechny <0/> jsou součástí vašeho předplatného."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:514
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:530
msgid "All <0/>, forever. No billing, no renewals."
msgstr "Všechny <0/> napořád. Žádné platby ani obnovování."
@@ -6469,7 +6469,7 @@ msgid "Cancel import"
msgstr "Zrušit import"
#. Billing button that cancels a scheduled move to a lower subscription price.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:821
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:837
msgid "Cancel price change"
msgstr "Zrušit změnu ceny"
@@ -6484,14 +6484,14 @@ msgid "Cancel request"
msgstr "Zrušit žádost"
#. Billing button that cancels a scheduled billing-cycle change.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:829
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:845
msgid "Cancel scheduled switch"
msgstr "Zrušit plánovanou změnu"
#. Billing button that starts subscription cancellation.
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:844
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:142
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:860
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:141
#: src/features/user/components/settings_utils/search_index/PlutoniumIndex.ts:31
msgid "Cancel subscription"
msgstr "Zrušit předplatné"
@@ -6501,7 +6501,7 @@ msgid "Cancel subscription?"
msgstr "Zrušit předplatné?"
#. Plutonium subscription card hint shown to a subscriber who could move to a lower price but has another billing change already scheduled.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:647
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:663
msgid "Cancel the scheduled change to move to the current price instead."
msgstr "Zrušit naplánovanou změnu a místo toho přejít na aktuální cenu."
@@ -6511,7 +6511,7 @@ msgid "Cancel upload"
msgstr "Zrušit nahrávání"
#. Billing button that cancels a scheduled yearly upgrade.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:825
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:841
msgid "Cancel yearly upgrade"
msgstr "Zrušit přechod na roční předplatné"
@@ -6530,7 +6530,7 @@ msgstr "Ruší se"
msgid "Cancellation"
msgstr "Potlačení ozvěny"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:501
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:517
msgid "Cancels on <0>{cancelDate}</0>. <1/> remain active until then."
msgstr "Předplatné bude zrušeno dne <0>{cancelDate}</0>. <1/> zůstanou aktivní až do té doby."
@@ -10872,7 +10872,7 @@ msgstr "Vlastní…"
#. Billing button that opens the external customer portal.
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:750
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:766
#: src/features/user/components/settings_utils/search_index/PlutoniumIndex.ts:39
msgid "Customer portal"
msgstr "Zákaznický portál"
@@ -13877,15 +13877,15 @@ msgid "End date"
msgstr "Datum konce"
#. Billing button that ends premium grace period immediately.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:856
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:872
msgid "End grace now"
msgstr "Ukončit dodatečnou lhůtu hned"
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:164
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:163
msgid "End grace period"
msgstr "Ukončit dodatečnou lhůtu"
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:157
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:156
msgid "End grace period now?"
msgstr "Ukončit dodatečnou lhůtu hned?"
@@ -16347,7 +16347,7 @@ msgstr "Dárek: brzy vyprší"
msgid "Gift: grace period (still have access)"
msgstr "Dárek: dodatečná lhůta (stále máte přístup)"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:486
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:502
msgid "Gifted <0/> until <1>{giftEndDate}</1>. Does not renew automatically. Redeem more gift codes to extend."
msgstr "Darované <0/> platí do <1>{giftEndDate}</1>. Předplatné se automaticky neobnovuje. Pro prodloužení uplatněte další dárkové kódy."
@@ -16826,7 +16826,7 @@ msgid "Hate speech"
msgstr "Nenávistné projevy"
#. Premium page text shown on an instance where the premium tier cannot be bought, only redeemed. {PREMIUM_PRODUCT_NAME} is the premium tier name.
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:297
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:296
msgid "Have a gift code? Redeem it to unlock {PREMIUM_PRODUCT_NAME}."
msgstr "Máte dárkový kód? Uplatněte ho a odemkněte {PREMIUM_PRODUCT_NAME}."
@@ -18926,7 +18926,7 @@ msgstr "Ponechat přílohy při vymazání textu během úprav"
msgid "Keep free and premium tiers. You can customize the tiers, sell premium through Stripe, or hand out gift codes later from the admin panel."
msgstr "Ponechte bezplatnou i prémiovou úroveň. Úrovně můžete přizpůsobit, prodávat prémiové členství přes Stripe nebo později rozdávat dárkové kódy z administračního panelu."
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:166
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:165
msgid "Keep grace period"
msgstr "Ponechat dodatečnou lhůtu"
@@ -18940,7 +18940,7 @@ msgstr "Ponechat Neko na místě"
msgid "Keep running"
msgstr "Pokračovat v běhu"
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:144
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:143
msgid "Keep subscription"
msgstr "Ponechat předplatné"
@@ -19297,8 +19297,8 @@ msgstr "Levé tlačítko myši"
msgid "Left tooltip"
msgstr "Bublina vlevo"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:539
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:561
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:555
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:577
msgid "Legacy rate"
msgstr "Původní cena"
@@ -21339,11 +21339,11 @@ msgstr "Měsíčně"
msgid "Monthly {monthlyPrice}"
msgstr "Měsíčně {monthlyPrice}"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:631
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:647
msgid "Monthly billing starts on <0>{pendingChangeDate}</0>."
msgstr "Měsíční fakturace začíná dne <0>{pendingChangeDate}</0>."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:624
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:640
msgid "Monthly billing starts on <0>{pendingChangeDate}</0>. First monthly charge: {pendingInitialPriceLabel}. Future monthly renewals: {pendingRecurringPriceLabel}/month."
msgstr "Měsíční fakturace začíná <0>{pendingChangeDate}</0>. První měsíční poplatek: {pendingInitialPriceLabel}. Budoucí měsíční obnovení: {pendingRecurringPriceLabel}/měsíc."
@@ -22269,12 +22269,12 @@ msgid "New password"
msgstr "Nové heslo"
#. Plutonium subscription card line shown when a move to a lower price is scheduled but the new amount is unknown. {pendingChangeDate} is a date already formatted and localized by code; never write a date into the translation.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:595
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:611
msgid "New price scheduled for <0>{pendingChangeDate}</0>."
msgstr "Nová cena naplánována na <0>{pendingChangeDate}</0>."
#. Plutonium subscription card line shown when a move to a lower price is scheduled. {pendingChangeDate} is a date and {pendingTargetPriceLabel} is a currency amount, both already formatted and localized by code; never write a date or an amount into the translation.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:589
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:605
msgid "New price scheduled for <0>{pendingChangeDate}</0>. Renewals will be {pendingTargetPriceLabel} from then on."
msgstr "Nová cena naplánovaná na <0>{pendingChangeDate}</0>. Obnovení budou od té doby stát {pendingTargetPriceLabel}."
@@ -26152,7 +26152,7 @@ msgstr "Reakce"
#. Billing button that cancels a scheduled subscription cancellation.
#. Button label on the premium-expired nagbar. Opens billing so the user can reactivate their subscription.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:746
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:762
#: src/features/app/components/layout/app_layout/nagbars/PremiumExpiredNagbar.tsx:25
msgid "Reactivate"
msgstr "Znovu aktivovat"
@@ -26375,8 +26375,8 @@ msgstr "Uplatnit pro sebe"
#. Billing button for entering a premium gift code.
#. Billing button for entering a premium gift code.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:719
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:307
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:735
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:306
msgid "Redeem gift code"
msgstr "Uplatnit dárkový kód"
@@ -27147,7 +27147,7 @@ msgstr "Prahová hodnota obnovení (dny)"
msgid "Renew window (days)"
msgstr "Období obnovení (dny)"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:701
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:717
msgid "Renews on <0>{renewalDate}.</0>"
msgstr "Obnoví se dne <0>{renewalDate}.</0>"
@@ -27896,8 +27896,8 @@ msgstr "Obnovit okno"
#. Billing button for restarting a subscription during the grace period.
#. Billing button for starting a new subscription after premium expired.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:738
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:742
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:754
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:758
msgid "Resubscribe"
msgstr "Obnovit předplatné"
@@ -32521,7 +32521,7 @@ msgid "Switch price"
msgstr "Změnit cenu"
#. Billing button that opens confirmation to move the subscription down to the current price. {listPriceNewLabel} is the localized new price.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:806
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:822
msgid "Switch to {listPriceNewLabel}"
msgstr "Přejít na {listPriceNewLabel}"
@@ -32546,7 +32546,7 @@ msgstr "Přepnout na přímý vstup"
#. Billing button that opens confirmation to switch to monthly billing.
#. Button confirming a change to monthly subscription billing.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:57
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:789
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:805
msgid "Switch to monthly"
msgstr "Přepnout na měsíční platbu"
@@ -32615,7 +32615,7 @@ msgstr "Přepnout na dva sloupce"
#. Billing button that opens confirmation to switch to yearly billing.
#. Button confirming a change to yearly subscription billing.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:53
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:785
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:801
msgid "Switch to yearly"
msgstr "Přepnout na roční platbu"
@@ -35865,7 +35865,7 @@ msgstr "Odemkněte vlastní emoji v soukromých konverzacích s {premiumProductN
msgid "Unlock HD screen share with {premiumProductName}"
msgstr "Odemkněte sdílení obrazovky v HD rozlišení s {premiumProductName}"
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:217
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:216
msgid "Unlock higher limits and exclusive features while supporting an independent communication platform."
msgstr "Odemkněte vyšší limity a exkluzivní funkce a zároveň podpořte nezávislou komunikační platformu."
@@ -39015,15 +39015,15 @@ msgstr "Ročně {yearlyPrice}"
msgid "Yearly gift"
msgstr "Roční dárek"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:618
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:634
msgid "Yearly upgrade scheduled for <0>{pendingChangeDate}</0>."
msgstr "Přechod na roční předplatné je naplánovaný na <0>{pendingChangeDate}</0>."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:603
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:619
msgid "Yearly upgrade scheduled for <0>{pendingChangeDate}</0>. First yearly charge: {pendingInitialPriceLabel} after a {pendingCreditPriceLabel} credit. Future yearly renewals: {pendingRecurringPriceLabel}/year."
msgstr "Přechod na roční předplatné je naplánovaný na <0>{pendingChangeDate}</0>. První roční platba: {pendingInitialPriceLabel} po započtení kreditu {pendingCreditPriceLabel}. Další roční obnovení: {pendingRecurringPriceLabel}/rok."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:610
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:626
msgid "Yearly upgrade scheduled for <0>{pendingChangeDate}</0>. First yearly charge: {pendingInitialPriceLabel}. Future yearly renewals: {pendingRecurringPriceLabel}/year."
msgstr "Přechod na roční předplatné je naplánovaný na <0>{pendingChangeDate}</0>. První roční platba: {pendingInitialPriceLabel}. Další roční obnovení: {pendingRecurringPriceLabel}/rok."
@@ -39493,10 +39493,10 @@ msgid "You just pressed Tab. Keyboard mode is now on so you can navigate {produc
msgstr "Právě jste stiskli klávesu Tab. Režim klávesnice je nyní zapnutý, takže můžete procházet aplikaci {productName} bez myši."
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:137
msgid "You keep your perks until your next renewal date, then have a 3-day grace period to resubscribe and keep your subscriber history."
msgstr "Výhody si ponecháte do data příštího obnovení. Poté máte dodatečnou lhůtu 3 dnů na obnovení předplatného a zachování jeho historie."
msgid "You keep your perks until your next renewal date. Reactivate before then to keep your subscriber history."
msgstr "Výhody si ponecháte do data příštího obnovení. Pokud předplatné do té doby znovu aktivujete, zachováte si jeho historii."
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:159
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:158
msgid "You lose all {PREMIUM_PRODUCT_NAME} perks immediately and your subscriber history resets. This cannot be undone."
msgstr "Okamžitě ztratíte všechny výhody {PREMIUM_PRODUCT_NAME} a historie vašeho předplatného se resetuje. Tuto akci nelze vrátit zpět."
@@ -40231,6 +40231,11 @@ msgstr "váš region"
msgid "Your registration needs an extra anti-spam check before you can continue."
msgstr "Než budete moct pokračovat, je potřeba provést dodatečnou kontrolu proti spamu."
#. Plutonium subscription card text shown while a failed renewal payment is being retried. {graceDate} is a date already formatted and localized by code; never write a date into the translation.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:470
msgid "Your renewal payment failed but <0/> stay active until <1>{graceDate}</1>. Update your payment method before then to keep your subscription."
msgstr "Platba za obnovení předplatného se nezdařila, ale <0/> zůstávají aktivní do <1>{graceDate}</1>. Do té doby aktualizujte způsob platby, abyste si předplatné zachovali."
#. Video settings note shown when the saved screen share quality is above what this account can send. Resolutions are short labels such as 1440p or Source and rates are whole numbers. FPS is a technical token.
#: src/features/user/components/modals/tabs/UserVideoTab.tsx:92
msgid "Your saved {savedResolution} at {savedFrameRate} FPS needs {premiumProductName}, so shares use {resolution} at {frameRate} FPS."
@@ -40252,7 +40257,7 @@ msgstr "Váš stream je stále aktivní"
msgid "Your subscription can't move to the new price right now."
msgstr "Vaše předplatné se momentálně nemůže přesunout na novou cenu."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:470
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:486
msgid "Your subscription ended but <0/> stay active until <1>{graceDate}</1>. Resubscribe before then to keep your subscriber history."
msgstr "Vaše předplatné skončilo, ale <0/> zůstávají aktivní do <1>{graceDate}</1>. Do té doby si předplatné obnovte, abyste zachovali jeho historii."
@@ -40281,7 +40286,7 @@ msgstr "Vaše předplatné bylo změněno na měsíční fakturaci."
msgid "Your subscription has been switched to yearly billing."
msgstr "Vaše předplatné bylo změněno na roční fakturaci."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:512
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:528
msgid "Your subscription is active but perks are temporarily paused."
msgstr "Vaše předplatné je aktivní, ale výhody jsou dočasně pozastaveny."
@@ -40301,7 +40306,7 @@ msgid "Your subscription moves to the new price on {effectiveDate}."
msgstr "Vaše předplatné přechází na novou cenu {effectiveDate}."
#. Plutonium subscription card line shown to a subscriber on a legacy price whose subscription is already set to cancel. {cancelDate} is a date and {listPriceNewLabel} is a currency amount, both already formatted and localized by code; never write a date or an amount into the translation.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:666
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:682
msgid "Your subscription still ends on <0>{cancelDate}</0>. The current price is now {listPriceNewLabel}. If you reactivate, you can switch to it from here."
msgstr "Vaše předplatné stále končí <0>{cancelDate}</0>. Aktuální cena je {listPriceNewLabel}. Pokud předplatné znovu aktivujete, můžete zde na tuto cenu přejít."
@@ -2471,7 +2471,7 @@ msgid "A Linux desktop update is available. Choose the package format for this s
msgstr "En opdatering til Linux-appen er tilgængelig. Vælg pakkeformatet for dette system, så gemmer {productName} det lokalt."
#. Plutonium subscription card line offering a move to a lower price. {listPriceEffectiveDate} is a date already formatted and localized by code; never write a date into the translation.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:684
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:700
msgid "A lower price is available. Switching takes effect on <0>{listPriceEffectiveDate}</0> and changes nothing else."
msgstr "En lavere pris er tilgængelig. Skiftet træder i kraft den <0>{listPriceEffectiveDate}</0> og ændrer intet andet."
@@ -3487,19 +3487,19 @@ msgstr "Kontroller til placering er kun tilgængelige på bredere skærme"
msgid "All"
msgstr "Alle"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:524
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:540
msgid "All <0/> for <1>{effectiveMonthlyPrice}/month</1>."
msgstr "Alle <0/> for <1>{effectiveMonthlyPrice}/måned</1>."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:546
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:562
msgid "All <0/> for <1>{effectiveYearlyPrice}/year</1>."
msgstr "Alle <0/> for <1>{effectiveYearlyPrice}/år</1>."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:567
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:583
msgid "All <0/> included with your subscription."
msgstr "Alle <0/> er inkluderet i dit abonnement."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:514
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:530
msgid "All <0/>, forever. No billing, no renewals."
msgstr "Alle <0/>, for evigt. Ingen fakturering, ingen fornyelser."
@@ -6469,7 +6469,7 @@ msgid "Cancel import"
msgstr "Annuller import"
#. Billing button that cancels a scheduled move to a lower subscription price.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:821
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:837
msgid "Cancel price change"
msgstr "Annuller prisændring"
@@ -6484,14 +6484,14 @@ msgid "Cancel request"
msgstr "Annuller anmodning"
#. Billing button that cancels a scheduled billing-cycle change.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:829
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:845
msgid "Cancel scheduled switch"
msgstr "Annuller planlagt skift"
#. Billing button that starts subscription cancellation.
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:844
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:142
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:860
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:141
#: src/features/user/components/settings_utils/search_index/PlutoniumIndex.ts:31
msgid "Cancel subscription"
msgstr "Opsig abonnement"
@@ -6501,7 +6501,7 @@ msgid "Cancel subscription?"
msgstr "Opsig abonnement?"
#. Plutonium subscription card hint shown to a subscriber who could move to a lower price but has another billing change already scheduled.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:647
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:663
msgid "Cancel the scheduled change to move to the current price instead."
msgstr "Annuller den planlagte ændring for at skifte til den aktuelle pris i stedet."
@@ -6511,7 +6511,7 @@ msgid "Cancel upload"
msgstr "Annuller upload"
#. Billing button that cancels a scheduled yearly upgrade.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:825
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:841
msgid "Cancel yearly upgrade"
msgstr "Annuller årlig opgradering"
@@ -6530,7 +6530,7 @@ msgstr "Opsigelse planlagt"
msgid "Cancellation"
msgstr "Ekkoannullering"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:501
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:517
msgid "Cancels on <0>{cancelDate}</0>. <1/> remain active until then."
msgstr "Udløber efter opsigelse den <0>{cancelDate}</0>. <1/> forbliver aktive indtil da."
@@ -10872,7 +10872,7 @@ msgstr "Tilpasset…"
#. Billing button that opens the external customer portal.
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:750
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:766
#: src/features/user/components/settings_utils/search_index/PlutoniumIndex.ts:39
msgid "Customer portal"
msgstr "Kundeportal"
@@ -13877,15 +13877,15 @@ msgid "End date"
msgstr "Slutdato"
#. Billing button that ends premium grace period immediately.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:856
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:872
msgid "End grace now"
msgstr "Afslut overgangsperiode nu"
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:164
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:163
msgid "End grace period"
msgstr "Afslut overgangsperiode"
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:157
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:156
msgid "End grace period now?"
msgstr "Afslut overgangsperiode nu?"
@@ -16347,7 +16347,7 @@ msgstr "Gave: udløber snart"
msgid "Gift: grace period (still have access)"
msgstr "Gave: overgangsperiode (har stadig adgang)"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:486
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:502
msgid "Gifted <0/> until <1>{giftEndDate}</1>. Does not renew automatically. Redeem more gift codes to extend."
msgstr "Du har fået <0/> i gave indtil <1>{giftEndDate}</1>. Fornyes ikke automatisk. Indløs flere gavekoder for at forlænge perioden."
@@ -16826,7 +16826,7 @@ msgid "Hate speech"
msgstr "Hadefuld tale"
#. Premium page text shown on an instance where the premium tier cannot be bought, only redeemed. {PREMIUM_PRODUCT_NAME} is the premium tier name.
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:297
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:296
msgid "Have a gift code? Redeem it to unlock {PREMIUM_PRODUCT_NAME}."
msgstr "Har du en gavekode? Indløs den for at låse op for {PREMIUM_PRODUCT_NAME}."
@@ -18926,7 +18926,7 @@ msgstr "Behold vedhæftede filer, når du rydder en redigering"
msgid "Keep free and premium tiers. You can customize the tiers, sell premium through Stripe, or hand out gift codes later from the admin panel."
msgstr "Behold gratis og premium-niveauer. Du kan tilpasse niveauerne, sælge premium via Stripe eller uddele gavekoder senere fra adminpanelet."
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:166
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:165
msgid "Keep grace period"
msgstr "Behold overgangsperioden"
@@ -18940,7 +18940,7 @@ msgstr "Hold Neko stille"
msgid "Keep running"
msgstr "Fortsæt med at køre"
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:144
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:143
msgid "Keep subscription"
msgstr "Behold abonnement"
@@ -19297,8 +19297,8 @@ msgstr "Venstre museknap"
msgid "Left tooltip"
msgstr "Værktøjstip til venstre"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:539
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:561
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:555
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:577
msgid "Legacy rate"
msgstr "Gammel pris"
@@ -21339,11 +21339,11 @@ msgstr "Månedligt"
msgid "Monthly {monthlyPrice}"
msgstr "Månedligt {monthlyPrice}"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:631
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:647
msgid "Monthly billing starts on <0>{pendingChangeDate}</0>."
msgstr "Månedlig fakturering starter den <0>{pendingChangeDate}</0>."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:624
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:640
msgid "Monthly billing starts on <0>{pendingChangeDate}</0>. First monthly charge: {pendingInitialPriceLabel}. Future monthly renewals: {pendingRecurringPriceLabel}/month."
msgstr "Månedlig fakturering starter den <0>{pendingChangeDate}</0>. Første månedlige betaling: {pendingInitialPriceLabel}. Fremtidige månedlige fornyelser: {pendingRecurringPriceLabel}/måned."
@@ -22269,12 +22269,12 @@ msgid "New password"
msgstr "Ny adgangskode"
#. Plutonium subscription card line shown when a move to a lower price is scheduled but the new amount is unknown. {pendingChangeDate} is a date already formatted and localized by code; never write a date into the translation.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:595
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:611
msgid "New price scheduled for <0>{pendingChangeDate}</0>."
msgstr "Ny pris planlagt til <0>{pendingChangeDate}</0>."
#. Plutonium subscription card line shown when a move to a lower price is scheduled. {pendingChangeDate} is a date and {pendingTargetPriceLabel} is a currency amount, both already formatted and localized by code; never write a date or an amount into the translation.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:589
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:605
msgid "New price scheduled for <0>{pendingChangeDate}</0>. Renewals will be {pendingTargetPriceLabel} from then on."
msgstr "Ny pris planlagt til <0>{pendingChangeDate}</0>. Fornyelser vil koste {pendingTargetPriceLabel} derefter."
@@ -26152,7 +26152,7 @@ msgstr "Reaktioner"
#. Billing button that cancels a scheduled subscription cancellation.
#. Button label on the premium-expired nagbar. Opens billing so the user can reactivate their subscription.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:746
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:762
#: src/features/app/components/layout/app_layout/nagbars/PremiumExpiredNagbar.tsx:25
msgid "Reactivate"
msgstr "Genaktiver"
@@ -26375,8 +26375,8 @@ msgstr "Indløs til dig selv"
#. Billing button for entering a premium gift code.
#. Billing button for entering a premium gift code.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:719
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:307
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:735
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:306
msgid "Redeem gift code"
msgstr "Indløs gavekode"
@@ -27147,7 +27147,7 @@ msgstr "Fornyelsestærskel (dage)"
msgid "Renew window (days)"
msgstr "Fornyelsesvindue (dage)"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:701
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:717
msgid "Renews on <0>{renewalDate}.</0>"
msgstr "Fornyes den <0>{renewalDate}.</0>"
@@ -27896,8 +27896,8 @@ msgstr "Gendan vindue"
#. Billing button for restarting a subscription during the grace period.
#. Billing button for starting a new subscription after premium expired.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:738
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:742
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:754
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:758
msgid "Resubscribe"
msgstr "Forny abonnement"
@@ -32521,7 +32521,7 @@ msgid "Switch price"
msgstr "Skift pris"
#. Billing button that opens confirmation to move the subscription down to the current price. {listPriceNewLabel} is the localized new price.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:806
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:822
msgid "Switch to {listPriceNewLabel}"
msgstr "Skift til {listPriceNewLabel}"
@@ -32546,7 +32546,7 @@ msgstr "Skift til direkte input"
#. Billing button that opens confirmation to switch to monthly billing.
#. Button confirming a change to monthly subscription billing.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:57
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:789
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:805
msgid "Switch to monthly"
msgstr "Skift til månedligt abonnement"
@@ -32615,7 +32615,7 @@ msgstr "Skift til to kolonner"
#. Billing button that opens confirmation to switch to yearly billing.
#. Button confirming a change to yearly subscription billing.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:53
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:785
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:801
msgid "Switch to yearly"
msgstr "Skift til årligt abonnement"
@@ -35865,7 +35865,7 @@ msgstr "Lås op for tilpassede emojis i direkte beskeder med {premiumProductName
msgid "Unlock HD screen share with {premiumProductName}"
msgstr "Lås op for HD-skærmdeling med {premiumProductName}"
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:217
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:216
msgid "Unlock higher limits and exclusive features while supporting an independent communication platform."
msgstr "Lås op for højere grænser og eksklusive funktioner, og støt samtidig en uafhængig kommunikationsplatform."
@@ -39015,15 +39015,15 @@ msgstr "Årligt {yearlyPrice}"
msgid "Yearly gift"
msgstr "Gave på et år"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:618
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:634
msgid "Yearly upgrade scheduled for <0>{pendingChangeDate}</0>."
msgstr "Årlig opgradering planlagt til <0>{pendingChangeDate}</0>."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:603
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:619
msgid "Yearly upgrade scheduled for <0>{pendingChangeDate}</0>. First yearly charge: {pendingInitialPriceLabel} after a {pendingCreditPriceLabel} credit. Future yearly renewals: {pendingRecurringPriceLabel}/year."
msgstr "Årlig opgradering planlagt til <0>{pendingChangeDate}</0>. Første årlige betaling: {pendingInitialPriceLabel} efter modregning af {pendingCreditPriceLabel}. Fremtidige årlige fornyelser: {pendingRecurringPriceLabel}/år."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:610
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:626
msgid "Yearly upgrade scheduled for <0>{pendingChangeDate}</0>. First yearly charge: {pendingInitialPriceLabel}. Future yearly renewals: {pendingRecurringPriceLabel}/year."
msgstr "Årlig opgradering planlagt til <0>{pendingChangeDate}</0>. Første årlige betaling: {pendingInitialPriceLabel}. Fremtidige årlige fornyelser: {pendingRecurringPriceLabel}/år."
@@ -39493,10 +39493,10 @@ msgid "You just pressed Tab. Keyboard mode is now on so you can navigate {produc
msgstr "Du har lige trykket på Tab. Tastaturtilstand er nu slået til, så du kan navigere i {productName} uden en mus."
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:137
msgid "You keep your perks until your next renewal date, then have a 3-day grace period to resubscribe and keep your subscriber history."
msgstr "Du beholder dine fordele indtil din næste fornyelsesdato og har derefter en overgangsperiode på 3 dage til at tegne abonnement igen og bevare din abonnementshistorik."
msgid "You keep your perks until your next renewal date. Reactivate before then to keep your subscriber history."
msgstr "Du beholder dine fordele indtil din næste fornyelsesdato. Genaktiver inden da for at bevare din abonnementshistorik."
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:159
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:158
msgid "You lose all {PREMIUM_PRODUCT_NAME} perks immediately and your subscriber history resets. This cannot be undone."
msgstr "Du mister alle dine {PREMIUM_PRODUCT_NAME}-fordele med det samme, og din abonnementshistorik nulstilles. Dette kan ikke fortrydes."
@@ -40231,6 +40231,11 @@ msgstr "din region"
msgid "Your registration needs an extra anti-spam check before you can continue."
msgstr "Din registrering kræver et ekstra anti-spam-tjek, før du kan fortsætte."
#. Plutonium subscription card text shown while a failed renewal payment is being retried. {graceDate} is a date already formatted and localized by code; never write a date into the translation.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:470
msgid "Your renewal payment failed but <0/> stay active until <1>{graceDate}</1>. Update your payment method before then to keep your subscription."
msgstr "Din fornyelsesbetaling mislykkedes, men <0/> forbliver aktive indtil <1>{graceDate}</1>. Opdater din betalingsmetode inden da for at beholde dit abonnement."
#. Video settings note shown when the saved screen share quality is above what this account can send. Resolutions are short labels such as 1440p or Source and rates are whole numbers. FPS is a technical token.
#: src/features/user/components/modals/tabs/UserVideoTab.tsx:92
msgid "Your saved {savedResolution} at {savedFrameRate} FPS needs {premiumProductName}, so shares use {resolution} at {frameRate} FPS."
@@ -40252,7 +40257,7 @@ msgstr "Din stream er stadig live"
msgid "Your subscription can't move to the new price right now."
msgstr "Dit abonnement kan ikke flyttes til den nye pris lige nu."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:470
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:486
msgid "Your subscription ended but <0/> stay active until <1>{graceDate}</1>. Resubscribe before then to keep your subscriber history."
msgstr "Dit abonnement er udløbet, men <0/> forbliver aktive indtil <1>{graceDate}</1>. Tegn abonnement igen inden da for at bevare din abonnementshistorik."
@@ -40281,7 +40286,7 @@ msgstr "Dit abonnement er nu skiftet til månedlig fakturering."
msgid "Your subscription has been switched to yearly billing."
msgstr "Dit abonnement er blevet skiftet til årlig fakturering."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:512
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:528
msgid "Your subscription is active but perks are temporarily paused."
msgstr "Dit abonnement er aktivt, men fordelene er midlertidigt sat på pause."
@@ -40301,7 +40306,7 @@ msgid "Your subscription moves to the new price on {effectiveDate}."
msgstr "Dit abonnement skifter til den nye pris den {effectiveDate}."
#. Plutonium subscription card line shown to a subscriber on a legacy price whose subscription is already set to cancel. {cancelDate} is a date and {listPriceNewLabel} is a currency amount, both already formatted and localized by code; never write a date or an amount into the translation.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:666
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:682
msgid "Your subscription still ends on <0>{cancelDate}</0>. The current price is now {listPriceNewLabel}. If you reactivate, you can switch to it from here."
msgstr "Dit abonnement udløber stadig den <0>{cancelDate}</0>. Den aktuelle pris er nu {listPriceNewLabel}. Hvis du genaktiverer, kan du skifte til den herfra."
@@ -2471,7 +2471,7 @@ msgid "A Linux desktop update is available. Choose the package format for this s
msgstr "Ein Desktop-Update für Linux ist verfügbar. Wähle das Paketformat für dieses System und {productName} speichert es lokal."
#. Plutonium subscription card line offering a move to a lower price. {listPriceEffectiveDate} is a date already formatted and localized by code; never write a date into the translation.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:684
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:700
msgid "A lower price is available. Switching takes effect on <0>{listPriceEffectiveDate}</0> and changes nothing else."
msgstr "Ein niedrigerer Preis ist verfügbar. Der Wechsel wird am <0>{listPriceEffectiveDate}</0> wirksam und ändert nichts weiter."
@@ -3487,19 +3487,19 @@ msgstr "Ausrichtungsoptionen sind nur auf breiteren Bildschirmen verfügbar"
msgid "All"
msgstr "Alle"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:524
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:540
msgid "All <0/> for <1>{effectiveMonthlyPrice}/month</1>."
msgstr "Alle <0/> für <1>{effectiveMonthlyPrice}/Monat</1>."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:546
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:562
msgid "All <0/> for <1>{effectiveYearlyPrice}/year</1>."
msgstr "Alle <0/> für <1>{effectiveYearlyPrice}/Jahr</1>."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:567
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:583
msgid "All <0/> included with your subscription."
msgstr "Alle <0/> sind in deinem Abonnement enthalten."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:514
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:530
msgid "All <0/>, forever. No billing, no renewals."
msgstr "Alle <0/>, für immer. Keine Abrechnung, keine Verlängerungen."
@@ -6469,7 +6469,7 @@ msgid "Cancel import"
msgstr "Import abbrechen"
#. Billing button that cancels a scheduled move to a lower subscription price.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:821
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:837
msgid "Cancel price change"
msgstr "Preisänderung abbrechen"
@@ -6484,14 +6484,14 @@ msgid "Cancel request"
msgstr "Anfrage zurückziehen"
#. Billing button that cancels a scheduled billing-cycle change.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:829
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:845
msgid "Cancel scheduled switch"
msgstr "Geplante Umstellung abbrechen"
#. Billing button that starts subscription cancellation.
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:844
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:142
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:860
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:141
#: src/features/user/components/settings_utils/search_index/PlutoniumIndex.ts:31
msgid "Cancel subscription"
msgstr "Abo kündigen"
@@ -6501,7 +6501,7 @@ msgid "Cancel subscription?"
msgstr "Abo kündigen?"
#. Plutonium subscription card hint shown to a subscriber who could move to a lower price but has another billing change already scheduled.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:647
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:663
msgid "Cancel the scheduled change to move to the current price instead."
msgstr "Brich die geplante Änderung ab, um stattdessen zum aktuellen Preis zu wechseln."
@@ -6511,7 +6511,7 @@ msgid "Cancel upload"
msgstr "Upload abbrechen"
#. Billing button that cancels a scheduled yearly upgrade.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:825
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:841
msgid "Cancel yearly upgrade"
msgstr "Wechsel zum Jahresabonnement abbrechen"
@@ -6530,7 +6530,7 @@ msgstr "Wird gekündigt"
msgid "Cancellation"
msgstr "Echo-Unterdrückung"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:501
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:517
msgid "Cancels on <0>{cancelDate}</0>. <1/> remain active until then."
msgstr "Kündigung am <0>{cancelDate}</0>. <1/> bleiben bis dahin aktiv."
@@ -10872,7 +10872,7 @@ msgstr "Benutzerdefiniert …"
#. Billing button that opens the external customer portal.
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:750
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:766
#: src/features/user/components/settings_utils/search_index/PlutoniumIndex.ts:39
msgid "Customer portal"
msgstr "Kundenportal"
@@ -13877,15 +13877,15 @@ msgid "End date"
msgstr "Enddatum"
#. Billing button that ends premium grace period immediately.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:856
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:872
msgid "End grace now"
msgstr "Übergangsfrist jetzt beenden"
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:164
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:163
msgid "End grace period"
msgstr "Übergangsfrist beenden"
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:157
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:156
msgid "End grace period now?"
msgstr "Übergangsfrist jetzt beenden?"
@@ -16347,7 +16347,7 @@ msgstr "Geschenk: läuft bald ab"
msgid "Gift: grace period (still have access)"
msgstr "Geschenk: Übergangsfrist (Zugriff weiterhin möglich)"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:486
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:502
msgid "Gifted <0/> until <1>{giftEndDate}</1>. Does not renew automatically. Redeem more gift codes to extend."
msgstr "<0/> als Geschenk bis <1>{giftEndDate}</1> erhalten. Wird nicht automatisch verlängert. Löse weitere Geschenkcodes ein, um die Laufzeit zu verlängern."
@@ -16826,7 +16826,7 @@ msgid "Hate speech"
msgstr "Hassrede"
#. Premium page text shown on an instance where the premium tier cannot be bought, only redeemed. {PREMIUM_PRODUCT_NAME} is the premium tier name.
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:297
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:296
msgid "Have a gift code? Redeem it to unlock {PREMIUM_PRODUCT_NAME}."
msgstr "Hast du einen Geschenke-Code? Löse ihn ein, um {PREMIUM_PRODUCT_NAME} freizuschalten."
@@ -18926,7 +18926,7 @@ msgstr "Anhänge beim Löschen einer Bearbeitung beibehalten"
msgid "Keep free and premium tiers. You can customize the tiers, sell premium through Stripe, or hand out gift codes later from the admin panel."
msgstr "Behalte kostenlose und Premium-Stufen bei. Du kannst die Stufen anpassen, Premium über Stripe verkaufen oder später Geschenke-Codes im Admin-Panel verteilen."
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:166
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:165
msgid "Keep grace period"
msgstr "Übergangsfrist beibehalten"
@@ -18940,7 +18940,7 @@ msgstr "Neko festhalten"
msgid "Keep running"
msgstr "Weiter ausführen"
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:144
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:143
msgid "Keep subscription"
msgstr "Abo behalten"
@@ -19297,8 +19297,8 @@ msgstr "Linke Maustaste"
msgid "Left tooltip"
msgstr "Linker Tooltip"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:539
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:561
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:555
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:577
msgid "Legacy rate"
msgstr "Alter Tarif"
@@ -21339,11 +21339,11 @@ msgstr "Monatlich"
msgid "Monthly {monthlyPrice}"
msgstr "Monatlich {monthlyPrice}"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:631
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:647
msgid "Monthly billing starts on <0>{pendingChangeDate}</0>."
msgstr "Die monatliche Abrechnung beginnt am <0>{pendingChangeDate}</0>."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:624
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:640
msgid "Monthly billing starts on <0>{pendingChangeDate}</0>. First monthly charge: {pendingInitialPriceLabel}. Future monthly renewals: {pendingRecurringPriceLabel}/month."
msgstr "Die monatliche Abrechnung beginnt am <0>{pendingChangeDate}</0>. Erste monatliche Gebühr: {pendingInitialPriceLabel}. Zukünftige monatliche Verlängerungen: {pendingRecurringPriceLabel}/Monat."
@@ -22269,12 +22269,12 @@ msgid "New password"
msgstr "Neues Passwort"
#. Plutonium subscription card line shown when a move to a lower price is scheduled but the new amount is unknown. {pendingChangeDate} is a date already formatted and localized by code; never write a date into the translation.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:595
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:611
msgid "New price scheduled for <0>{pendingChangeDate}</0>."
msgstr "Neuer Preis geplant für den <0>{pendingChangeDate}</0>."
#. Plutonium subscription card line shown when a move to a lower price is scheduled. {pendingChangeDate} is a date and {pendingTargetPriceLabel} is a currency amount, both already formatted and localized by code; never write a date or an amount into the translation.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:589
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:605
msgid "New price scheduled for <0>{pendingChangeDate}</0>. Renewals will be {pendingTargetPriceLabel} from then on."
msgstr "Neuer Preis geplant für den <0>{pendingChangeDate}</0>. Verlängerungen kosten dann {pendingTargetPriceLabel}."
@@ -26152,7 +26152,7 @@ msgstr "Reaktionen"
#. Billing button that cancels a scheduled subscription cancellation.
#. Button label on the premium-expired nagbar. Opens billing so the user can reactivate their subscription.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:746
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:762
#: src/features/app/components/layout/app_layout/nagbars/PremiumExpiredNagbar.tsx:25
msgid "Reactivate"
msgstr "Reaktivieren"
@@ -26375,8 +26375,8 @@ msgstr "Für dich einlösen"
#. Billing button for entering a premium gift code.
#. Billing button for entering a premium gift code.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:719
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:307
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:735
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:306
msgid "Redeem gift code"
msgstr "Geschenkcode einlösen"
@@ -27147,7 +27147,7 @@ msgstr "Erneuerungsschwelle (Tage)"
msgid "Renew window (days)"
msgstr "Erneuerungszeitraum (Tage)"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:701
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:717
msgid "Renews on <0>{renewalDate}.</0>"
msgstr "Verlängert sich am <0>{renewalDate}.</0>"
@@ -27896,8 +27896,8 @@ msgstr "Fenster wiederherstellen"
#. Billing button for restarting a subscription during the grace period.
#. Billing button for starting a new subscription after premium expired.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:738
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:742
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:754
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:758
msgid "Resubscribe"
msgstr "Erneut abonnieren"
@@ -32521,7 +32521,7 @@ msgid "Switch price"
msgstr "Preis wechseln"
#. Billing button that opens confirmation to move the subscription down to the current price. {listPriceNewLabel} is the localized new price.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:806
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:822
msgid "Switch to {listPriceNewLabel}"
msgstr "Wechseln zu {listPriceNewLabel}"
@@ -32546,7 +32546,7 @@ msgstr "Direkte Eingabe nutzen"
#. Billing button that opens confirmation to switch to monthly billing.
#. Button confirming a change to monthly subscription billing.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:57
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:789
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:805
msgid "Switch to monthly"
msgstr "Zum Monatsabo wechseln"
@@ -32615,7 +32615,7 @@ msgstr "Zu zwei Spalten wechseln"
#. Billing button that opens confirmation to switch to yearly billing.
#. Button confirming a change to yearly subscription billing.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:53
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:785
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:801
msgid "Switch to yearly"
msgstr "Zum Jahresabo wechseln"
@@ -35865,7 +35865,7 @@ msgstr "Schalte benutzerdefinierte Emojis in DMs mit {premiumProductName} frei"
msgid "Unlock HD screen share with {premiumProductName}"
msgstr "HD-Bildschirmfreigabe mit {premiumProductName} freischalten"
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:217
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:216
msgid "Unlock higher limits and exclusive features while supporting an independent communication platform."
msgstr "Schalte höhere Limits und exklusive Funktionen frei und unterstütze gleichzeitig eine unabhängige Kommunikationsplattform."
@@ -39015,15 +39015,15 @@ msgstr "Jährlich {yearlyPrice}"
msgid "Yearly gift"
msgstr "Jährliches Geschenk"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:618
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:634
msgid "Yearly upgrade scheduled for <0>{pendingChangeDate}</0>."
msgstr "Wechsel zum Jahresabo für <0>{pendingChangeDate}</0> geplant."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:603
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:619
msgid "Yearly upgrade scheduled for <0>{pendingChangeDate}</0>. First yearly charge: {pendingInitialPriceLabel} after a {pendingCreditPriceLabel} credit. Future yearly renewals: {pendingRecurringPriceLabel}/year."
msgstr "Wechsel zum Jahresabo für <0>{pendingChangeDate}</0> geplant. Erste jährliche Abbuchung: {pendingInitialPriceLabel} nach Anrechnung einer Gutschrift von {pendingCreditPriceLabel}. Künftige jährliche Verlängerungen: {pendingRecurringPriceLabel}/Jahr."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:610
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:626
msgid "Yearly upgrade scheduled for <0>{pendingChangeDate}</0>. First yearly charge: {pendingInitialPriceLabel}. Future yearly renewals: {pendingRecurringPriceLabel}/year."
msgstr "Wechsel zum Jahresabo für <0>{pendingChangeDate}</0> geplant. Erste jährliche Abbuchung: {pendingInitialPriceLabel}. Künftige jährliche Verlängerungen: {pendingRecurringPriceLabel}/Jahr."
@@ -39493,10 +39493,10 @@ msgid "You just pressed Tab. Keyboard mode is now on so you can navigate {produc
msgstr "Du hast gerade die Tab-Taste gedrückt. Der Tastaturmodus ist jetzt aktiviert, damit du {productName} ohne Maus navigieren kannst."
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:137
msgid "You keep your perks until your next renewal date, then have a 3-day grace period to resubscribe and keep your subscriber history."
msgstr "Du behältst deine Vorteile bis zum nächsten Verlängerungsdatum. Danach hast du eine Übergangsfrist von 3 Tagen, um erneut zu abonnieren und deinen Abo-Verlauf zu behalten."
msgid "You keep your perks until your next renewal date. Reactivate before then to keep your subscriber history."
msgstr "Du behältst deine Vorteile bis zum nächsten Verlängerungsdatum. Reaktiviere dein Abo vorher, um deinen Abo-Verlauf zu behalten."
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:159
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:158
msgid "You lose all {PREMIUM_PRODUCT_NAME} perks immediately and your subscriber history resets. This cannot be undone."
msgstr "Du verlierst sofort alle {PREMIUM_PRODUCT_NAME}-Vorteile und dein Abonnentenverlauf wird zurückgesetzt. Dies kann nicht rückgängig gemacht werden."
@@ -40231,6 +40231,11 @@ msgstr "deine Region"
msgid "Your registration needs an extra anti-spam check before you can continue."
msgstr "Deine Registrierung erfordert eine zusätzliche Anti-Spam-Prüfung, bevor du fortfahren kannst."
#. Plutonium subscription card text shown while a failed renewal payment is being retried. {graceDate} is a date already formatted and localized by code; never write a date into the translation.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:470
msgid "Your renewal payment failed but <0/> stay active until <1>{graceDate}</1>. Update your payment method before then to keep your subscription."
msgstr "Deine Verlängerungszahlung ist fehlgeschlagen, aber <0/> bleiben bis zum <1>{graceDate}</1> aktiv. Aktualisiere vorher deine Zahlungsmethode, um dein Abo zu behalten."
#. Video settings note shown when the saved screen share quality is above what this account can send. Resolutions are short labels such as 1440p or Source and rates are whole numbers. FPS is a technical token.
#: src/features/user/components/modals/tabs/UserVideoTab.tsx:92
msgid "Your saved {savedResolution} at {savedFrameRate} FPS needs {premiumProductName}, so shares use {resolution} at {frameRate} FPS."
@@ -40252,7 +40257,7 @@ msgstr "Dein Stream ist weiterhin live"
msgid "Your subscription can't move to the new price right now."
msgstr "Dein Abonnement kann im Moment nicht zum neuen Preis übernommen werden."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:470
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:486
msgid "Your subscription ended but <0/> stay active until <1>{graceDate}</1>. Resubscribe before then to keep your subscriber history."
msgstr "Dein Abo ist abgelaufen, aber <0/> bleiben bis zum <1>{graceDate}</1> aktiv. Abonniere vorher erneut, um deinen Abo-Verlauf zu behalten."
@@ -40281,7 +40286,7 @@ msgstr "Dein Abo wurde auf monatliche Abrechnung umgestellt."
msgid "Your subscription has been switched to yearly billing."
msgstr "Dein Abo wurde auf jährliche Abrechnung umgestellt."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:512
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:528
msgid "Your subscription is active but perks are temporarily paused."
msgstr "Dein Abo ist aktiv, aber die Vorteile sind vorübergehend pausiert."
@@ -40301,7 +40306,7 @@ msgid "Your subscription moves to the new price on {effectiveDate}."
msgstr "Dein Abonnement wird am {effectiveDate} auf den neuen Preis umgestellt."
#. Plutonium subscription card line shown to a subscriber on a legacy price whose subscription is already set to cancel. {cancelDate} is a date and {listPriceNewLabel} is a currency amount, both already formatted and localized by code; never write a date or an amount into the translation.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:666
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:682
msgid "Your subscription still ends on <0>{cancelDate}</0>. The current price is now {listPriceNewLabel}. If you reactivate, you can switch to it from here."
msgstr "Dein Abo endet weiterhin am <0>{cancelDate}</0>. Der aktuelle Preis beträgt jetzt {listPriceNewLabel}. Wenn du dein Abo reaktivierst, kannst du hier zu diesem Preis wechseln."
@@ -2471,7 +2471,7 @@ msgid "A Linux desktop update is available. Choose the package format for this s
msgstr "Υπάρχει διαθέσιμη ενημέρωση της εφαρμογής για Linux. Επιλέξτε τη μορφή πακέτου για αυτό το σύστημα και το {productName} θα την αποθηκεύσει τοπικά."
#. Plutonium subscription card line offering a move to a lower price. {listPriceEffectiveDate} is a date already formatted and localized by code; never write a date into the translation.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:684
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:700
msgid "A lower price is available. Switching takes effect on <0>{listPriceEffectiveDate}</0> and changes nothing else."
msgstr "Υπάρχει διαθέσιμη χαμηλότερη τιμή. Η αλλαγή τίθεται σε ισχύ στις <0>{listPriceEffectiveDate}</0> και δεν αλλάζει τίποτα άλλο."
@@ -3487,19 +3487,19 @@ msgstr "Οι ρυθμίσεις στοίχισης είναι διαθέσιμε
msgid "All"
msgstr "Όλα"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:524
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:540
msgid "All <0/> for <1>{effectiveMonthlyPrice}/month</1>."
msgstr "Όλα τα <0/> με <1>{effectiveMonthlyPrice}/μήνα</1>."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:546
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:562
msgid "All <0/> for <1>{effectiveYearlyPrice}/year</1>."
msgstr "Όλα τα <0/> με <1>{effectiveYearlyPrice}/έτος</1>."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:567
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:583
msgid "All <0/> included with your subscription."
msgstr "Όλα τα <0/> περιλαμβάνονται στη συνδρομή σας."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:514
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:530
msgid "All <0/>, forever. No billing, no renewals."
msgstr "Όλα τα <0/>, για πάντα. Χωρίς χρέωση, χωρίς ανανεώσεις."
@@ -6469,7 +6469,7 @@ msgid "Cancel import"
msgstr "Ακύρωση εισαγωγής"
#. Billing button that cancels a scheduled move to a lower subscription price.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:821
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:837
msgid "Cancel price change"
msgstr "Ακύρωση αλλαγής τιμής"
@@ -6484,14 +6484,14 @@ msgid "Cancel request"
msgstr "Ακύρωση αιτήματος"
#. Billing button that cancels a scheduled billing-cycle change.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:829
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:845
msgid "Cancel scheduled switch"
msgstr "Ακύρωση προγραμματισμένης αλλαγής"
#. Billing button that starts subscription cancellation.
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:844
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:142
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:860
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:141
#: src/features/user/components/settings_utils/search_index/PlutoniumIndex.ts:31
msgid "Cancel subscription"
msgstr "Ακύρωση συνδρομής"
@@ -6501,7 +6501,7 @@ msgid "Cancel subscription?"
msgstr "Ακύρωση συνδρομής;"
#. Plutonium subscription card hint shown to a subscriber who could move to a lower price but has another billing change already scheduled.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:647
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:663
msgid "Cancel the scheduled change to move to the current price instead."
msgstr "Ακυρώστε την προγραμματισμένη αλλαγή για να μεταβείτε στην τρέχουσα τιμή."
@@ -6511,7 +6511,7 @@ msgid "Cancel upload"
msgstr "Ακύρωση μεταφόρτωσης"
#. Billing button that cancels a scheduled yearly upgrade.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:825
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:841
msgid "Cancel yearly upgrade"
msgstr "Ακύρωση ετήσιας αναβάθμισης"
@@ -6530,7 +6530,7 @@ msgstr "Ακυρώνεται"
msgid "Cancellation"
msgstr "Ακύρωση ηχούς"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:501
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:517
msgid "Cancels on <0>{cancelDate}</0>. <1/> remain active until then."
msgstr "Ακυρώνεται στις <0>{cancelDate}</0>. <1/> παραμένουν ενεργά μέχρι τότε."
@@ -10872,7 +10872,7 @@ msgstr "Προσαρμοσμένο…"
#. Billing button that opens the external customer portal.
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:750
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:766
#: src/features/user/components/settings_utils/search_index/PlutoniumIndex.ts:39
msgid "Customer portal"
msgstr "Πύλη πελατών"
@@ -13877,15 +13877,15 @@ msgid "End date"
msgstr "Ημερομηνία λήξης"
#. Billing button that ends premium grace period immediately.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:856
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:872
msgid "End grace now"
msgstr "Τερματισμός περιόδου χάριτος τώρα"
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:164
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:163
msgid "End grace period"
msgstr "Τερματισμός περιόδου χάριτος"
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:157
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:156
msgid "End grace period now?"
msgstr "Να τερματιστεί τώρα η περίοδος χάριτος;"
@@ -16347,7 +16347,7 @@ msgstr "Δώρο: λήγει σύντομα"
msgid "Gift: grace period (still have access)"
msgstr "Δώρο: περίοδος χάριτος (έχετε ακόμα πρόσβαση)"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:486
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:502
msgid "Gifted <0/> until <1>{giftEndDate}</1>. Does not renew automatically. Redeem more gift codes to extend."
msgstr "Έχετε ως δώρο <0/> έως <1>{giftEndDate}</1>. Δεν ανανεώνεται αυτόματα. Εξαργυρώστε περισσότερους κωδικούς δώρου για παράταση."
@@ -16826,7 +16826,7 @@ msgid "Hate speech"
msgstr "Ρητορική μίσους"
#. Premium page text shown on an instance where the premium tier cannot be bought, only redeemed. {PREMIUM_PRODUCT_NAME} is the premium tier name.
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:297
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:296
msgid "Have a gift code? Redeem it to unlock {PREMIUM_PRODUCT_NAME}."
msgstr "Έχετε κωδικό δώρου; Εξαργυρώστε τον για να ξεκλειδώσετε το {PREMIUM_PRODUCT_NAME}."
@@ -18926,7 +18926,7 @@ msgstr "Διατήρηση συνημμένων κατά την εκκαθάρι
msgid "Keep free and premium tiers. You can customize the tiers, sell premium through Stripe, or hand out gift codes later from the admin panel."
msgstr "Διατήρησε δωρεάν και premium βαθμίδες. Μπορείς να προσαρμόσεις τις βαθμίδες, να πουλήσεις premium μέσω Stripe ή να διανείμεις κωδικούς δώρου αργότερα από τον πίνακα διαχειριστή."
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:166
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:165
msgid "Keep grace period"
msgstr "Διατήρηση περιόδου χάριτος"
@@ -18940,7 +18940,7 @@ msgstr "Κράτα το Neko ακίνητο"
msgid "Keep running"
msgstr "Παραμονή σε λειτουργία"
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:144
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:143
msgid "Keep subscription"
msgstr "Διατήρηση συνδρομής"
@@ -19297,8 +19297,8 @@ msgstr "Αριστερό κουμπί ποντικιού"
msgid "Left tooltip"
msgstr "Αριστερή επεξήγηση εργαλείου"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:539
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:561
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:555
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:577
msgid "Legacy rate"
msgstr "Παλιά τιμή"
@@ -21339,11 +21339,11 @@ msgstr "Μηνιαία"
msgid "Monthly {monthlyPrice}"
msgstr "Μηνιαία {monthlyPrice}"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:631
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:647
msgid "Monthly billing starts on <0>{pendingChangeDate}</0>."
msgstr "Η μηνιαία χρέωση ξεκινά στις <0>{pendingChangeDate}</0>."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:624
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:640
msgid "Monthly billing starts on <0>{pendingChangeDate}</0>. First monthly charge: {pendingInitialPriceLabel}. Future monthly renewals: {pendingRecurringPriceLabel}/month."
msgstr "Η μηνιαία χρέωση ξεκινά στις <0>{pendingChangeDate}</0>. Πρώτη μηνιαία χρέωση: {pendingInitialPriceLabel}. Μελλοντικές μηνιαίες ανανεώσεις: {pendingRecurringPriceLabel}/μήνα."
@@ -22269,12 +22269,12 @@ msgid "New password"
msgstr "Νέος κωδικός πρόσβασης"
#. Plutonium subscription card line shown when a move to a lower price is scheduled but the new amount is unknown. {pendingChangeDate} is a date already formatted and localized by code; never write a date into the translation.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:595
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:611
msgid "New price scheduled for <0>{pendingChangeDate}</0>."
msgstr "Νέα τιμή προγραμματισμένη για <0>{pendingChangeDate}</0>."
#. Plutonium subscription card line shown when a move to a lower price is scheduled. {pendingChangeDate} is a date and {pendingTargetPriceLabel} is a currency amount, both already formatted and localized by code; never write a date or an amount into the translation.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:589
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:605
msgid "New price scheduled for <0>{pendingChangeDate}</0>. Renewals will be {pendingTargetPriceLabel} from then on."
msgstr "Νέα τιμή προγραμματισμένη για <0>{pendingChangeDate}</0>. Οι ανανεώσεις θα είναι {pendingTargetPriceLabel} από εκείνη την ημερομηνία και μετά."
@@ -26152,7 +26152,7 @@ msgstr "Αντιδράσεις"
#. Billing button that cancels a scheduled subscription cancellation.
#. Button label on the premium-expired nagbar. Opens billing so the user can reactivate their subscription.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:746
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:762
#: src/features/app/components/layout/app_layout/nagbars/PremiumExpiredNagbar.tsx:25
msgid "Reactivate"
msgstr "Ενεργοποίηση ξανά"
@@ -26375,8 +26375,8 @@ msgstr "Εξαργύρωση για εσάς"
#. Billing button for entering a premium gift code.
#. Billing button for entering a premium gift code.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:719
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:307
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:735
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:306
msgid "Redeem gift code"
msgstr "Εξαργύρωση κωδικού δώρου"
@@ -27147,7 +27147,7 @@ msgstr "Όριο ανανέωσης (ημέρες)"
msgid "Renew window (days)"
msgstr "Παράθυρο ανανέωσης (ημέρες)"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:701
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:717
msgid "Renews on <0>{renewalDate}.</0>"
msgstr "Ανανεώνεται στις <0>{renewalDate}.</0>"
@@ -27896,8 +27896,8 @@ msgstr "Επαναφορά παραθύρου"
#. Billing button for restarting a subscription during the grace period.
#. Billing button for starting a new subscription after premium expired.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:738
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:742
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:754
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:758
msgid "Resubscribe"
msgstr "Επανεγγραφή"
@@ -32521,7 +32521,7 @@ msgid "Switch price"
msgstr "Αλλαγή τιμής"
#. Billing button that opens confirmation to move the subscription down to the current price. {listPriceNewLabel} is the localized new price.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:806
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:822
msgid "Switch to {listPriceNewLabel}"
msgstr "Μετάβαση στο {listPriceNewLabel}"
@@ -32546,7 +32546,7 @@ msgstr "Εναλλαγή σε απευθείας εισαγωγή"
#. Billing button that opens confirmation to switch to monthly billing.
#. Button confirming a change to monthly subscription billing.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:57
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:789
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:805
msgid "Switch to monthly"
msgstr "Αλλαγή σε μηνιαία συνδρομή"
@@ -32615,7 +32615,7 @@ msgstr "Εναλλαγή σε δύο στήλες"
#. Billing button that opens confirmation to switch to yearly billing.
#. Button confirming a change to yearly subscription billing.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:53
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:785
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:801
msgid "Switch to yearly"
msgstr "Αλλαγή σε ετήσια συνδρομή"
@@ -35865,7 +35865,7 @@ msgstr "Ξεκλειδώστε προσαρμοσμένα emoji σε DM με τ
msgid "Unlock HD screen share with {premiumProductName}"
msgstr "Ξεκλειδώστε την κοινή χρήση οθόνης HD με το {premiumProductName}"
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:217
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:216
msgid "Unlock higher limits and exclusive features while supporting an independent communication platform."
msgstr "Ξεκλειδώστε υψηλότερα όρια και αποκλειστικές λειτουργίες, υποστηρίζοντας ταυτόχρονα μια ανεξάρτητη πλατφόρμα επικοινωνίας."
@@ -39015,15 +39015,15 @@ msgstr "Ετήσια {yearlyPrice}"
msgid "Yearly gift"
msgstr "Ετήσιο δώρο"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:618
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:634
msgid "Yearly upgrade scheduled for <0>{pendingChangeDate}</0>."
msgstr "Η αναβάθμιση σε ετήσια συνδρομή έχει προγραμματιστεί για <0>{pendingChangeDate}</0>."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:603
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:619
msgid "Yearly upgrade scheduled for <0>{pendingChangeDate}</0>. First yearly charge: {pendingInitialPriceLabel} after a {pendingCreditPriceLabel} credit. Future yearly renewals: {pendingRecurringPriceLabel}/year."
msgstr "Η ετήσια αναβάθμιση έχει προγραμματιστεί για <0>{pendingChangeDate}</0>. Πρώτη ετήσια χρέωση: {pendingInitialPriceLabel} μετά από πίστωση {pendingCreditPriceLabel}. Μελλοντικές ετήσιες ανανεώσεις: {pendingRecurringPriceLabel}/έτος."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:610
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:626
msgid "Yearly upgrade scheduled for <0>{pendingChangeDate}</0>. First yearly charge: {pendingInitialPriceLabel}. Future yearly renewals: {pendingRecurringPriceLabel}/year."
msgstr "Η ετήσια αναβάθμιση έχει προγραμματιστεί για <0>{pendingChangeDate}</0>. Πρώτη ετήσια χρέωση: {pendingInitialPriceLabel}. Μελλοντικές ετήσιες ανανεώσεις: {pendingRecurringPriceLabel}/έτος."
@@ -39493,10 +39493,10 @@ msgid "You just pressed Tab. Keyboard mode is now on so you can navigate {produc
msgstr "Μόλις πατήσατε Tab. Η λειτουργία πληκτρολογίου είναι πλέον ενεργή, ώστε να μπορείτε να περιηγηθείτε στο {productName} χωρίς ποντίκι."
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:137
msgid "You keep your perks until your next renewal date, then have a 3-day grace period to resubscribe and keep your subscriber history."
msgstr "Διατηρείτε τα προνόμιά σας μέχρι την επόμενη ημερομηνία ανανέωσης και, στη συνέχεια, έχετε μια περίοδο χάριτος 3 ημερών για να εγγραφείτε ξανά και να διατηρήσετε το ιστορικό συνδρομών σας."
msgid "You keep your perks until your next renewal date. Reactivate before then to keep your subscriber history."
msgstr "Διατηρείτε τα προνόμιά σας μέχρι την επόμενη ημερομηνία ανανέωσης. Ενεργοποιήστε ξανά τη συνδρομή σας πριν από τότε για να διατηρήσετε το ιστορικό συνδρομών σας."
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:159
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:158
msgid "You lose all {PREMIUM_PRODUCT_NAME} perks immediately and your subscriber history resets. This cannot be undone."
msgstr "Χάνετε όλα τα προνόμια {PREMIUM_PRODUCT_NAME} αμέσως και το ιστορικό συνδρομών σας μηδενίζεται. Αυτό δεν μπορεί να αναιρεθεί."
@@ -40231,6 +40231,11 @@ msgstr "η περιοχή σας"
msgid "Your registration needs an extra anti-spam check before you can continue."
msgstr "Η εγγραφή σας χρειάζεται έναν επιπλέον έλεγχο κατά των ανεπιθύμητων μηνυμάτων πριν συνεχίσετε."
#. Plutonium subscription card text shown while a failed renewal payment is being retried. {graceDate} is a date already formatted and localized by code; never write a date into the translation.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:470
msgid "Your renewal payment failed but <0/> stay active until <1>{graceDate}</1>. Update your payment method before then to keep your subscription."
msgstr "Η πληρωμή ανανέωσης απέτυχε, αλλά τα <0/> παραμένουν ενεργά έως <1>{graceDate}</1>. Ενημερώστε τον τρόπο πληρωμής σας πριν από τότε για να διατηρήσετε τη συνδρομή σας."
#. Video settings note shown when the saved screen share quality is above what this account can send. Resolutions are short labels such as 1440p or Source and rates are whole numbers. FPS is a technical token.
#: src/features/user/components/modals/tabs/UserVideoTab.tsx:92
msgid "Your saved {savedResolution} at {savedFrameRate} FPS needs {premiumProductName}, so shares use {resolution} at {frameRate} FPS."
@@ -40252,7 +40257,7 @@ msgstr "Η ροή σας είναι ακόμα ενεργή"
msgid "Your subscription can't move to the new price right now."
msgstr "Η συνδρομή σας δεν μπορεί να μετακινηθεί στη νέα τιμή αυτήν τη στιγμή."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:470
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:486
msgid "Your subscription ended but <0/> stay active until <1>{graceDate}</1>. Resubscribe before then to keep your subscriber history."
msgstr "Η συνδρομή σας έληξε, αλλά τα <0/> παραμένουν ενεργά έως <1>{graceDate}</1>. Κάντε επανεγγραφή πριν από τότε για να διατηρήσετε το ιστορικό συνδρομής σας."
@@ -40281,7 +40286,7 @@ msgstr "Η συνδρομή σας άλλαξε σε μηνιαία χρέωση
msgid "Your subscription has been switched to yearly billing."
msgstr "Η συνδρομή σας έχει αλλάξει σε ετήσια χρέωση."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:512
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:528
msgid "Your subscription is active but perks are temporarily paused."
msgstr "Η συνδρομή σας είναι ενεργή, αλλά τα προνόμια έχουν προσωρινά τεθεί σε παύση."
@@ -40301,7 +40306,7 @@ msgid "Your subscription moves to the new price on {effectiveDate}."
msgstr "Η συνδρομή σας μεταβαίνει στη νέα τιμή στις {effectiveDate}."
#. Plutonium subscription card line shown to a subscriber on a legacy price whose subscription is already set to cancel. {cancelDate} is a date and {listPriceNewLabel} is a currency amount, both already formatted and localized by code; never write a date or an amount into the translation.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:666
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:682
msgid "Your subscription still ends on <0>{cancelDate}</0>. The current price is now {listPriceNewLabel}. If you reactivate, you can switch to it from here."
msgstr "Η συνδρομή σας εξακολουθεί να λήγει στις <0>{cancelDate}</0>. Η τρέχουσα τιμή είναι τώρα {listPriceNewLabel}. Αν ενεργοποιήσετε ξανά τη συνδρομή, μπορείτε να περάσετε σε αυτήν την τιμή από εδώ."
@@ -2471,7 +2471,7 @@ msgid "A Linux desktop update is available. Choose the package format for this s
msgstr "A Linux desktop update is available. Choose the package format for this system and {productName} will save it locally."
#. Plutonium subscription card line offering a move to a lower price. {listPriceEffectiveDate} is a date already formatted and localized by code; never write a date into the translation.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:684
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:700
msgid "A lower price is available. Switching takes effect on <0>{listPriceEffectiveDate}</0> and changes nothing else."
msgstr "A lower price is available. Switching takes effect on <0>{listPriceEffectiveDate}</0> and changes nothing else."
@@ -3487,19 +3487,19 @@ msgstr "Alignment controls are only available on wider screens"
msgid "All"
msgstr "All"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:524
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:540
msgid "All <0/> for <1>{effectiveMonthlyPrice}/month</1>."
msgstr "All <0/> for <1>{effectiveMonthlyPrice}/month</1>."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:546
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:562
msgid "All <0/> for <1>{effectiveYearlyPrice}/year</1>."
msgstr "All <0/> for <1>{effectiveYearlyPrice}/year</1>."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:567
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:583
msgid "All <0/> included with your subscription."
msgstr "All <0/> included with your subscription."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:514
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:530
msgid "All <0/>, forever. No billing, no renewals."
msgstr "All <0/>, forever. No billing, no renewals."
@@ -6469,7 +6469,7 @@ msgid "Cancel import"
msgstr "Cancel import"
#. Billing button that cancels a scheduled move to a lower subscription price.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:821
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:837
msgid "Cancel price change"
msgstr "Cancel price change"
@@ -6484,14 +6484,14 @@ msgid "Cancel request"
msgstr "Cancel request"
#. Billing button that cancels a scheduled billing-cycle change.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:829
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:845
msgid "Cancel scheduled switch"
msgstr "Cancel scheduled switch"
#. Billing button that starts subscription cancellation.
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:844
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:142
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:860
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:141
#: src/features/user/components/settings_utils/search_index/PlutoniumIndex.ts:31
msgid "Cancel subscription"
msgstr "Cancel subscription"
@@ -6501,7 +6501,7 @@ msgid "Cancel subscription?"
msgstr "Cancel subscription?"
#. Plutonium subscription card hint shown to a subscriber who could move to a lower price but has another billing change already scheduled.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:647
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:663
msgid "Cancel the scheduled change to move to the current price instead."
msgstr "Cancel the scheduled change to move to the current price instead."
@@ -6511,7 +6511,7 @@ msgid "Cancel upload"
msgstr "Cancel upload"
#. Billing button that cancels a scheduled yearly upgrade.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:825
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:841
msgid "Cancel yearly upgrade"
msgstr "Cancel yearly upgrade"
@@ -6530,7 +6530,7 @@ msgstr "Cancelling"
msgid "Cancellation"
msgstr "Cancellation"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:501
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:517
msgid "Cancels on <0>{cancelDate}</0>. <1/> remain active until then."
msgstr "Cancels on <0>{cancelDate}</0>. <1/> remain active until then."
@@ -10872,7 +10872,7 @@ msgstr "Custom…"
#. Billing button that opens the external customer portal.
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:750
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:766
#: src/features/user/components/settings_utils/search_index/PlutoniumIndex.ts:39
msgid "Customer portal"
msgstr "Customer portal"
@@ -13877,15 +13877,15 @@ msgid "End date"
msgstr "End date"
#. Billing button that ends premium grace period immediately.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:856
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:872
msgid "End grace now"
msgstr "End grace now"
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:164
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:163
msgid "End grace period"
msgstr "End grace period"
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:157
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:156
msgid "End grace period now?"
msgstr "End grace period now?"
@@ -16347,7 +16347,7 @@ msgstr "Gift: expiring soon"
msgid "Gift: grace period (still have access)"
msgstr "Gift: grace period (still have access)"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:486
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:502
msgid "Gifted <0/> until <1>{giftEndDate}</1>. Does not renew automatically. Redeem more gift codes to extend."
msgstr "Gifted <0/> until <1>{giftEndDate}</1>. Does not renew automatically. Redeem more gift codes to extend."
@@ -16826,7 +16826,7 @@ msgid "Hate speech"
msgstr "Hate speech"
#. Premium page text shown on an instance where the premium tier cannot be bought, only redeemed. {PREMIUM_PRODUCT_NAME} is the premium tier name.
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:297
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:296
msgid "Have a gift code? Redeem it to unlock {PREMIUM_PRODUCT_NAME}."
msgstr "Have a gift code? Redeem it to unlock {PREMIUM_PRODUCT_NAME}."
@@ -18926,7 +18926,7 @@ msgstr "Keep attachments when clearing an edit"
msgid "Keep free and premium tiers. You can customize the tiers, sell premium through Stripe, or hand out gift codes later from the admin panel."
msgstr "Keep free and premium tiers. You can customise the tiers, sell premium through Stripe, or hand out gift codes later from the admin panel."
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:166
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:165
msgid "Keep grace period"
msgstr "Keep grace period"
@@ -18940,7 +18940,7 @@ msgstr "Keep Neko still"
msgid "Keep running"
msgstr "Keep running"
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:144
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:143
msgid "Keep subscription"
msgstr "Keep subscription"
@@ -19297,8 +19297,8 @@ msgstr "Left mouse button"
msgid "Left tooltip"
msgstr "Left tooltip"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:539
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:561
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:555
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:577
msgid "Legacy rate"
msgstr "Legacy rate"
@@ -21339,11 +21339,11 @@ msgstr "Monthly"
msgid "Monthly {monthlyPrice}"
msgstr "Monthly {monthlyPrice}"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:631
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:647
msgid "Monthly billing starts on <0>{pendingChangeDate}</0>."
msgstr "Monthly billing starts on <0>{pendingChangeDate}</0>."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:624
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:640
msgid "Monthly billing starts on <0>{pendingChangeDate}</0>. First monthly charge: {pendingInitialPriceLabel}. Future monthly renewals: {pendingRecurringPriceLabel}/month."
msgstr "Monthly billing starts on <0>{pendingChangeDate}</0>. First monthly charge: {pendingInitialPriceLabel}. Future monthly renewals: {pendingRecurringPriceLabel}/month."
@@ -22269,12 +22269,12 @@ msgid "New password"
msgstr "New password"
#. Plutonium subscription card line shown when a move to a lower price is scheduled but the new amount is unknown. {pendingChangeDate} is a date already formatted and localized by code; never write a date into the translation.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:595
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:611
msgid "New price scheduled for <0>{pendingChangeDate}</0>."
msgstr "New price scheduled for <0>{pendingChangeDate}</0>."
#. Plutonium subscription card line shown when a move to a lower price is scheduled. {pendingChangeDate} is a date and {pendingTargetPriceLabel} is a currency amount, both already formatted and localized by code; never write a date or an amount into the translation.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:589
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:605
msgid "New price scheduled for <0>{pendingChangeDate}</0>. Renewals will be {pendingTargetPriceLabel} from then on."
msgstr "New price scheduled for <0>{pendingChangeDate}</0>. Renewals will be {pendingTargetPriceLabel} from then on."
@@ -26152,7 +26152,7 @@ msgstr "Reactions"
#. Billing button that cancels a scheduled subscription cancellation.
#. Button label on the premium-expired nagbar. Opens billing so the user can reactivate their subscription.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:746
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:762
#: src/features/app/components/layout/app_layout/nagbars/PremiumExpiredNagbar.tsx:25
msgid "Reactivate"
msgstr "Reactivate"
@@ -26375,8 +26375,8 @@ msgstr "Redeem for yourself"
#. Billing button for entering a premium gift code.
#. Billing button for entering a premium gift code.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:719
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:307
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:735
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:306
msgid "Redeem gift code"
msgstr "Redeem gift code"
@@ -27147,7 +27147,7 @@ msgstr "Renew threshold (days)"
msgid "Renew window (days)"
msgstr "Renew window (days)"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:701
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:717
msgid "Renews on <0>{renewalDate}.</0>"
msgstr "Renews on <0>{renewalDate}.</0>"
@@ -27896,8 +27896,8 @@ msgstr "Restore window"
#. Billing button for restarting a subscription during the grace period.
#. Billing button for starting a new subscription after premium expired.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:738
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:742
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:754
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:758
msgid "Resubscribe"
msgstr "Resubscribe"
@@ -32521,7 +32521,7 @@ msgid "Switch price"
msgstr "Switch price"
#. Billing button that opens confirmation to move the subscription down to the current price. {listPriceNewLabel} is the localized new price.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:806
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:822
msgid "Switch to {listPriceNewLabel}"
msgstr "Switch to {listPriceNewLabel}"
@@ -32546,7 +32546,7 @@ msgstr "Switch to direct input"
#. Billing button that opens confirmation to switch to monthly billing.
#. Button confirming a change to monthly subscription billing.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:57
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:789
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:805
msgid "Switch to monthly"
msgstr "Switch to monthly"
@@ -32615,7 +32615,7 @@ msgstr "Switch to two columns"
#. Billing button that opens confirmation to switch to yearly billing.
#. Button confirming a change to yearly subscription billing.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:53
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:785
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:801
msgid "Switch to yearly"
msgstr "Switch to yearly"
@@ -35865,7 +35865,7 @@ msgstr "Unlock custom emojis in DMs with {premiumProductName}"
msgid "Unlock HD screen share with {premiumProductName}"
msgstr "Unlock HD screen share with {premiumProductName}"
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:217
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:216
msgid "Unlock higher limits and exclusive features while supporting an independent communication platform."
msgstr "Unlock higher limits and exclusive features while supporting an independent communication platform."
@@ -39015,15 +39015,15 @@ msgstr "Yearly {yearlyPrice}"
msgid "Yearly gift"
msgstr "Yearly gift"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:618
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:634
msgid "Yearly upgrade scheduled for <0>{pendingChangeDate}</0>."
msgstr "Yearly upgrade scheduled for <0>{pendingChangeDate}</0>."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:603
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:619
msgid "Yearly upgrade scheduled for <0>{pendingChangeDate}</0>. First yearly charge: {pendingInitialPriceLabel} after a {pendingCreditPriceLabel} credit. Future yearly renewals: {pendingRecurringPriceLabel}/year."
msgstr "Yearly upgrade scheduled for <0>{pendingChangeDate}</0>. First yearly charge: {pendingInitialPriceLabel} after a {pendingCreditPriceLabel} credit. Future yearly renewals: {pendingRecurringPriceLabel}/year."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:610
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:626
msgid "Yearly upgrade scheduled for <0>{pendingChangeDate}</0>. First yearly charge: {pendingInitialPriceLabel}. Future yearly renewals: {pendingRecurringPriceLabel}/year."
msgstr "Yearly upgrade scheduled for <0>{pendingChangeDate}</0>. First yearly charge: {pendingInitialPriceLabel}. Future yearly renewals: {pendingRecurringPriceLabel}/year."
@@ -39493,10 +39493,10 @@ msgid "You just pressed Tab. Keyboard mode is now on so you can navigate {produc
msgstr "You just pressed Tab. Keyboard mode is now on so you can navigate {productName} without a mouse."
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:137
msgid "You keep your perks until your next renewal date, then have a 3-day grace period to resubscribe and keep your subscriber history."
msgstr "You keep your perks until your next renewal date, then have a 3-day grace period to resubscribe and keep your subscriber history."
msgid "You keep your perks until your next renewal date. Reactivate before then to keep your subscriber history."
msgstr "You keep your perks until your next renewal date. Reactivate before then to keep your subscriber history."
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:159
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:158
msgid "You lose all {PREMIUM_PRODUCT_NAME} perks immediately and your subscriber history resets. This cannot be undone."
msgstr "You lose all {PREMIUM_PRODUCT_NAME} perks immediately and your subscriber history resets. This cannot be undone."
@@ -40231,6 +40231,11 @@ msgstr "your region"
msgid "Your registration needs an extra anti-spam check before you can continue."
msgstr "Your registration needs an extra anti-spam check before you can continue."
#. Plutonium subscription card text shown while a failed renewal payment is being retried. {graceDate} is a date already formatted and localized by code; never write a date into the translation.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:470
msgid "Your renewal payment failed but <0/> stay active until <1>{graceDate}</1>. Update your payment method before then to keep your subscription."
msgstr "Your renewal payment failed but <0/> stay active until <1>{graceDate}</1>. Update your payment method before then to keep your subscription."
#. Video settings note shown when the saved screen share quality is above what this account can send. Resolutions are short labels such as 1440p or Source and rates are whole numbers. FPS is a technical token.
#: src/features/user/components/modals/tabs/UserVideoTab.tsx:92
msgid "Your saved {savedResolution} at {savedFrameRate} FPS needs {premiumProductName}, so shares use {resolution} at {frameRate} FPS."
@@ -40252,7 +40257,7 @@ msgstr "Your stream is still live"
msgid "Your subscription can't move to the new price right now."
msgstr "Your subscription can't move to the new price right now."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:470
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:486
msgid "Your subscription ended but <0/> stay active until <1>{graceDate}</1>. Resubscribe before then to keep your subscriber history."
msgstr "Your subscription ended but <0/> stay active until <1>{graceDate}</1>. Resubscribe before then to keep your subscriber history."
@@ -40281,7 +40286,7 @@ msgstr "Your subscription has been switched to monthly billing."
msgid "Your subscription has been switched to yearly billing."
msgstr "Your subscription has been switched to yearly billing."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:512
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:528
msgid "Your subscription is active but perks are temporarily paused."
msgstr "Your subscription is active but perks are temporarily paused."
@@ -40301,7 +40306,7 @@ msgid "Your subscription moves to the new price on {effectiveDate}."
msgstr "Your subscription moves to the new price on {effectiveDate}."
#. Plutonium subscription card line shown to a subscriber on a legacy price whose subscription is already set to cancel. {cancelDate} is a date and {listPriceNewLabel} is a currency amount, both already formatted and localized by code; never write a date or an amount into the translation.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:666
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:682
msgid "Your subscription still ends on <0>{cancelDate}</0>. The current price is now {listPriceNewLabel}. If you reactivate, you can switch to it from here."
msgstr "Your subscription still ends on <0>{cancelDate}</0>. The current price is now {listPriceNewLabel}. If you reactivate, you can switch to it from here."
@@ -2471,7 +2471,7 @@ msgid "A Linux desktop update is available. Choose the package format for this s
msgstr "A Linux desktop update is available. Choose the package format for this system and {productName} will save it locally."
#. Plutonium subscription card line offering a move to a lower price. {listPriceEffectiveDate} is a date already formatted and localized by code; never write a date into the translation.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:684
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:700
msgid "A lower price is available. Switching takes effect on <0>{listPriceEffectiveDate}</0> and changes nothing else."
msgstr "A lower price is available. Switching takes effect on <0>{listPriceEffectiveDate}</0> and changes nothing else."
@@ -3487,19 +3487,19 @@ msgstr "Alignment controls are only available on wider screens"
msgid "All"
msgstr "All"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:524
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:540
msgid "All <0/> for <1>{effectiveMonthlyPrice}/month</1>."
msgstr "All <0/> for <1>{effectiveMonthlyPrice}/month</1>."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:546
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:562
msgid "All <0/> for <1>{effectiveYearlyPrice}/year</1>."
msgstr "All <0/> for <1>{effectiveYearlyPrice}/year</1>."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:567
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:583
msgid "All <0/> included with your subscription."
msgstr "All <0/> included with your subscription."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:514
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:530
msgid "All <0/>, forever. No billing, no renewals."
msgstr "All <0/>, forever. No billing, no renewals."
@@ -6469,7 +6469,7 @@ msgid "Cancel import"
msgstr "Cancel import"
#. Billing button that cancels a scheduled move to a lower subscription price.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:821
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:837
msgid "Cancel price change"
msgstr "Cancel price change"
@@ -6484,14 +6484,14 @@ msgid "Cancel request"
msgstr "Cancel request"
#. Billing button that cancels a scheduled billing-cycle change.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:829
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:845
msgid "Cancel scheduled switch"
msgstr "Cancel scheduled switch"
#. Billing button that starts subscription cancellation.
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:844
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:142
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:860
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:141
#: src/features/user/components/settings_utils/search_index/PlutoniumIndex.ts:31
msgid "Cancel subscription"
msgstr "Cancel subscription"
@@ -6501,7 +6501,7 @@ msgid "Cancel subscription?"
msgstr "Cancel subscription?"
#. Plutonium subscription card hint shown to a subscriber who could move to a lower price but has another billing change already scheduled.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:647
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:663
msgid "Cancel the scheduled change to move to the current price instead."
msgstr "Cancel the scheduled change to move to the current price instead."
@@ -6511,7 +6511,7 @@ msgid "Cancel upload"
msgstr "Cancel upload"
#. Billing button that cancels a scheduled yearly upgrade.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:825
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:841
msgid "Cancel yearly upgrade"
msgstr "Cancel yearly upgrade"
@@ -6530,7 +6530,7 @@ msgstr "Canceling"
msgid "Cancellation"
msgstr "Cancellation"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:501
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:517
msgid "Cancels on <0>{cancelDate}</0>. <1/> remain active until then."
msgstr "Cancels on <0>{cancelDate}</0>. <1/> remain active until then."
@@ -10872,7 +10872,7 @@ msgstr "Custom…"
#. Billing button that opens the external customer portal.
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:750
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:766
#: src/features/user/components/settings_utils/search_index/PlutoniumIndex.ts:39
msgid "Customer portal"
msgstr "Customer portal"
@@ -13877,15 +13877,15 @@ msgid "End date"
msgstr "End date"
#. Billing button that ends premium grace period immediately.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:856
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:872
msgid "End grace now"
msgstr "End grace now"
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:164
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:163
msgid "End grace period"
msgstr "End grace period"
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:157
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:156
msgid "End grace period now?"
msgstr "End grace period now?"
@@ -16347,7 +16347,7 @@ msgstr "Gift: expiring soon"
msgid "Gift: grace period (still have access)"
msgstr "Gift: grace period (still have access)"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:486
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:502
msgid "Gifted <0/> until <1>{giftEndDate}</1>. Does not renew automatically. Redeem more gift codes to extend."
msgstr "Gifted <0/> until <1>{giftEndDate}</1>. Does not renew automatically. Redeem more gift codes to extend."
@@ -16826,7 +16826,7 @@ msgid "Hate speech"
msgstr "Hate speech"
#. Premium page text shown on an instance where the premium tier cannot be bought, only redeemed. {PREMIUM_PRODUCT_NAME} is the premium tier name.
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:297
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:296
msgid "Have a gift code? Redeem it to unlock {PREMIUM_PRODUCT_NAME}."
msgstr "Have a gift code? Redeem it to unlock {PREMIUM_PRODUCT_NAME}."
@@ -18926,7 +18926,7 @@ msgstr "Keep attachments when clearing an edit"
msgid "Keep free and premium tiers. You can customize the tiers, sell premium through Stripe, or hand out gift codes later from the admin panel."
msgstr "Keep free and premium tiers. You can customize the tiers, sell premium through Stripe, or hand out gift codes later from the admin panel."
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:166
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:165
msgid "Keep grace period"
msgstr "Keep grace period"
@@ -18940,7 +18940,7 @@ msgstr "Keep Neko still"
msgid "Keep running"
msgstr "Keep running"
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:144
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:143
msgid "Keep subscription"
msgstr "Keep subscription"
@@ -19297,8 +19297,8 @@ msgstr "Left mouse button"
msgid "Left tooltip"
msgstr "Left tooltip"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:539
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:561
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:555
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:577
msgid "Legacy rate"
msgstr "Legacy rate"
@@ -21339,11 +21339,11 @@ msgstr "Monthly"
msgid "Monthly {monthlyPrice}"
msgstr "Monthly {monthlyPrice}"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:631
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:647
msgid "Monthly billing starts on <0>{pendingChangeDate}</0>."
msgstr "Monthly billing starts on <0>{pendingChangeDate}</0>."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:624
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:640
msgid "Monthly billing starts on <0>{pendingChangeDate}</0>. First monthly charge: {pendingInitialPriceLabel}. Future monthly renewals: {pendingRecurringPriceLabel}/month."
msgstr "Monthly billing starts on <0>{pendingChangeDate}</0>. First monthly charge: {pendingInitialPriceLabel}. Future monthly renewals: {pendingRecurringPriceLabel}/month."
@@ -22269,12 +22269,12 @@ msgid "New password"
msgstr "New password"
#. Plutonium subscription card line shown when a move to a lower price is scheduled but the new amount is unknown. {pendingChangeDate} is a date already formatted and localized by code; never write a date into the translation.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:595
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:611
msgid "New price scheduled for <0>{pendingChangeDate}</0>."
msgstr "New price scheduled for <0>{pendingChangeDate}</0>."
#. Plutonium subscription card line shown when a move to a lower price is scheduled. {pendingChangeDate} is a date and {pendingTargetPriceLabel} is a currency amount, both already formatted and localized by code; never write a date or an amount into the translation.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:589
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:605
msgid "New price scheduled for <0>{pendingChangeDate}</0>. Renewals will be {pendingTargetPriceLabel} from then on."
msgstr "New price scheduled for <0>{pendingChangeDate}</0>. Renewals will be {pendingTargetPriceLabel} from then on."
@@ -26152,7 +26152,7 @@ msgstr "Reactions"
#. Billing button that cancels a scheduled subscription cancellation.
#. Button label on the premium-expired nagbar. Opens billing so the user can reactivate their subscription.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:746
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:762
#: src/features/app/components/layout/app_layout/nagbars/PremiumExpiredNagbar.tsx:25
msgid "Reactivate"
msgstr "Reactivate"
@@ -26375,8 +26375,8 @@ msgstr "Redeem for yourself"
#. Billing button for entering a premium gift code.
#. Billing button for entering a premium gift code.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:719
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:307
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:735
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:306
msgid "Redeem gift code"
msgstr "Redeem gift code"
@@ -27147,7 +27147,7 @@ msgstr "Renew threshold (days)"
msgid "Renew window (days)"
msgstr "Renew window (days)"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:701
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:717
msgid "Renews on <0>{renewalDate}.</0>"
msgstr "Renews on <0>{renewalDate}.</0>"
@@ -27896,8 +27896,8 @@ msgstr "Restore window"
#. Billing button for restarting a subscription during the grace period.
#. Billing button for starting a new subscription after premium expired.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:738
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:742
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:754
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:758
msgid "Resubscribe"
msgstr "Resubscribe"
@@ -32521,7 +32521,7 @@ msgid "Switch price"
msgstr "Switch price"
#. Billing button that opens confirmation to move the subscription down to the current price. {listPriceNewLabel} is the localized new price.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:806
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:822
msgid "Switch to {listPriceNewLabel}"
msgstr "Switch to {listPriceNewLabel}"
@@ -32546,7 +32546,7 @@ msgstr "Switch to direct input"
#. Billing button that opens confirmation to switch to monthly billing.
#. Button confirming a change to monthly subscription billing.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:57
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:789
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:805
msgid "Switch to monthly"
msgstr "Switch to monthly"
@@ -32615,7 +32615,7 @@ msgstr "Switch to two columns"
#. Billing button that opens confirmation to switch to yearly billing.
#. Button confirming a change to yearly subscription billing.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:53
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:785
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:801
msgid "Switch to yearly"
msgstr "Switch to yearly"
@@ -35865,7 +35865,7 @@ msgstr "Unlock custom emojis in DMs with {premiumProductName}"
msgid "Unlock HD screen share with {premiumProductName}"
msgstr "Unlock HD screen share with {premiumProductName}"
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:217
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:216
msgid "Unlock higher limits and exclusive features while supporting an independent communication platform."
msgstr "Unlock higher limits and exclusive features while supporting an independent communication platform."
@@ -39015,15 +39015,15 @@ msgstr "Yearly {yearlyPrice}"
msgid "Yearly gift"
msgstr "Yearly gift"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:618
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:634
msgid "Yearly upgrade scheduled for <0>{pendingChangeDate}</0>."
msgstr "Yearly upgrade scheduled for <0>{pendingChangeDate}</0>."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:603
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:619
msgid "Yearly upgrade scheduled for <0>{pendingChangeDate}</0>. First yearly charge: {pendingInitialPriceLabel} after a {pendingCreditPriceLabel} credit. Future yearly renewals: {pendingRecurringPriceLabel}/year."
msgstr "Yearly upgrade scheduled for <0>{pendingChangeDate}</0>. First yearly charge: {pendingInitialPriceLabel} after a {pendingCreditPriceLabel} credit. Future yearly renewals: {pendingRecurringPriceLabel}/year."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:610
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:626
msgid "Yearly upgrade scheduled for <0>{pendingChangeDate}</0>. First yearly charge: {pendingInitialPriceLabel}. Future yearly renewals: {pendingRecurringPriceLabel}/year."
msgstr "Yearly upgrade scheduled for <0>{pendingChangeDate}</0>. First yearly charge: {pendingInitialPriceLabel}. Future yearly renewals: {pendingRecurringPriceLabel}/year."
@@ -39493,10 +39493,10 @@ msgid "You just pressed Tab. Keyboard mode is now on so you can navigate {produc
msgstr "You just pressed Tab. Keyboard mode is now on so you can navigate {productName} without a mouse."
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:137
msgid "You keep your perks until your next renewal date, then have a 3-day grace period to resubscribe and keep your subscriber history."
msgstr "You keep your perks until your next renewal date, then have a 3-day grace period to resubscribe and keep your subscriber history."
msgid "You keep your perks until your next renewal date. Reactivate before then to keep your subscriber history."
msgstr "You keep your perks until your next renewal date. Reactivate before then to keep your subscriber history."
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:159
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:158
msgid "You lose all {PREMIUM_PRODUCT_NAME} perks immediately and your subscriber history resets. This cannot be undone."
msgstr "You lose all {PREMIUM_PRODUCT_NAME} perks immediately and your subscriber history resets. This cannot be undone."
@@ -40231,6 +40231,11 @@ msgstr "your region"
msgid "Your registration needs an extra anti-spam check before you can continue."
msgstr "Your registration needs an extra anti-spam check before you can continue."
#. Plutonium subscription card text shown while a failed renewal payment is being retried. {graceDate} is a date already formatted and localized by code; never write a date into the translation.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:470
msgid "Your renewal payment failed but <0/> stay active until <1>{graceDate}</1>. Update your payment method before then to keep your subscription."
msgstr "Your renewal payment failed but <0/> stay active until <1>{graceDate}</1>. Update your payment method before then to keep your subscription."
#. Video settings note shown when the saved screen share quality is above what this account can send. Resolutions are short labels such as 1440p or Source and rates are whole numbers. FPS is a technical token.
#: src/features/user/components/modals/tabs/UserVideoTab.tsx:92
msgid "Your saved {savedResolution} at {savedFrameRate} FPS needs {premiumProductName}, so shares use {resolution} at {frameRate} FPS."
@@ -40252,7 +40257,7 @@ msgstr "Your stream is still live"
msgid "Your subscription can't move to the new price right now."
msgstr "Your subscription can't move to the new price right now."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:470
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:486
msgid "Your subscription ended but <0/> stay active until <1>{graceDate}</1>. Resubscribe before then to keep your subscriber history."
msgstr "Your subscription ended but <0/> stay active until <1>{graceDate}</1>. Resubscribe before then to keep your subscriber history."
@@ -40281,7 +40286,7 @@ msgstr "Your subscription has been switched to monthly billing."
msgid "Your subscription has been switched to yearly billing."
msgstr "Your subscription has been switched to yearly billing."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:512
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:528
msgid "Your subscription is active but perks are temporarily paused."
msgstr "Your subscription is active but perks are temporarily paused."
@@ -40301,7 +40306,7 @@ msgid "Your subscription moves to the new price on {effectiveDate}."
msgstr "Your subscription moves to the new price on {effectiveDate}."
#. Plutonium subscription card line shown to a subscriber on a legacy price whose subscription is already set to cancel. {cancelDate} is a date and {listPriceNewLabel} is a currency amount, both already formatted and localized by code; never write a date or an amount into the translation.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:666
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:682
msgid "Your subscription still ends on <0>{cancelDate}</0>. The current price is now {listPriceNewLabel}. If you reactivate, you can switch to it from here."
msgstr "Your subscription still ends on <0>{cancelDate}</0>. The current price is now {listPriceNewLabel}. If you reactivate, you can switch to it from here."
@@ -2471,7 +2471,7 @@ msgid "A Linux desktop update is available. Choose the package format for this s
msgstr "Hay una actualización de escritorio para Linux disponible. Elige el formato del paquete para este sistema y {productName} lo guardará localmente."
#. Plutonium subscription card line offering a move to a lower price. {listPriceEffectiveDate} is a date already formatted and localized by code; never write a date into the translation.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:684
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:700
msgid "A lower price is available. Switching takes effect on <0>{listPriceEffectiveDate}</0> and changes nothing else."
msgstr "Hay un precio más bajo disponible. El cambio entra en vigor el <0>{listPriceEffectiveDate}</0> y no cambia nada más."
@@ -3487,19 +3487,19 @@ msgstr "Los controles de alineación solo están disponibles en pantallas más a
msgid "All"
msgstr "Todo"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:524
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:540
msgid "All <0/> for <1>{effectiveMonthlyPrice}/month</1>."
msgstr "Todos los <0/> por <1>{effectiveMonthlyPrice}/mes</1>."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:546
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:562
msgid "All <0/> for <1>{effectiveYearlyPrice}/year</1>."
msgstr "Todos los <0/> por <1>{effectiveYearlyPrice}/año</1>."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:567
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:583
msgid "All <0/> included with your subscription."
msgstr "Tu suscripción incluye todos los <0/>."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:514
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:530
msgid "All <0/>, forever. No billing, no renewals."
msgstr "Todos los <0/>, para siempre. Sin facturación ni renovaciones."
@@ -6469,7 +6469,7 @@ msgid "Cancel import"
msgstr "Cancelar importación"
#. Billing button that cancels a scheduled move to a lower subscription price.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:821
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:837
msgid "Cancel price change"
msgstr "Cancelar cambio de precio"
@@ -6484,14 +6484,14 @@ msgid "Cancel request"
msgstr "Cancelar solicitud"
#. Billing button that cancels a scheduled billing-cycle change.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:829
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:845
msgid "Cancel scheduled switch"
msgstr "Cancelar cambio programado"
#. Billing button that starts subscription cancellation.
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:844
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:142
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:860
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:141
#: src/features/user/components/settings_utils/search_index/PlutoniumIndex.ts:31
msgid "Cancel subscription"
msgstr "Cancelar suscripción"
@@ -6501,7 +6501,7 @@ msgid "Cancel subscription?"
msgstr "¿Cancelar suscripción?"
#. Plutonium subscription card hint shown to a subscriber who could move to a lower price but has another billing change already scheduled.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:647
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:663
msgid "Cancel the scheduled change to move to the current price instead."
msgstr "Cancela el cambio programado para pasar al precio actual en su lugar."
@@ -6511,7 +6511,7 @@ msgid "Cancel upload"
msgstr "Cancelar carga"
#. Billing button that cancels a scheduled yearly upgrade.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:825
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:841
msgid "Cancel yearly upgrade"
msgstr "Cancelar cambio al plan anual"
@@ -6530,7 +6530,7 @@ msgstr "Cancelando"
msgid "Cancellation"
msgstr "Cancelación de eco"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:501
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:517
msgid "Cancels on <0>{cancelDate}</0>. <1/> remain active until then."
msgstr "Se cancela el <0>{cancelDate}</0>. Los <1/> seguirán activos hasta entonces."
@@ -10872,7 +10872,7 @@ msgstr "Personalizar…"
#. Billing button that opens the external customer portal.
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:750
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:766
#: src/features/user/components/settings_utils/search_index/PlutoniumIndex.ts:39
msgid "Customer portal"
msgstr "Portal de clientes"
@@ -13877,15 +13877,15 @@ msgid "End date"
msgstr "Fecha de finalización"
#. Billing button that ends premium grace period immediately.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:856
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:872
msgid "End grace now"
msgstr "Terminar período de gracia ahora"
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:164
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:163
msgid "End grace period"
msgstr "Finalizar período de gracia"
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:157
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:156
msgid "End grace period now?"
msgstr "¿Terminar período de gracia ahora?"
@@ -16347,7 +16347,7 @@ msgstr "Regalo: vence pronto"
msgid "Gift: grace period (still have access)"
msgstr "Regalo: período de gracia (aún tiene acceso)"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:486
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:502
msgid "Gifted <0/> until <1>{giftEndDate}</1>. Does not renew automatically. Redeem more gift codes to extend."
msgstr "Los <0/> de regalo están activos hasta el <1>{giftEndDate}</1>. No se renuevan automáticamente. Canjea más códigos de regalo para prolongarlos."
@@ -16826,7 +16826,7 @@ msgid "Hate speech"
msgstr "Discurso de odio"
#. Premium page text shown on an instance where the premium tier cannot be bought, only redeemed. {PREMIUM_PRODUCT_NAME} is the premium tier name.
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:297
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:296
msgid "Have a gift code? Redeem it to unlock {PREMIUM_PRODUCT_NAME}."
msgstr "¿Tienes un código de regalo? Canjéalo para desbloquear {PREMIUM_PRODUCT_NAME}."
@@ -18926,7 +18926,7 @@ msgstr "Conservar archivos adjuntos al borrar el texto de una edición"
msgid "Keep free and premium tiers. You can customize the tiers, sell premium through Stripe, or hand out gift codes later from the admin panel."
msgstr "Mantén los niveles gratuito y premium. Puedes personalizar los niveles, vender premium a través de Stripe o entregar códigos de regalo más tarde desde el panel de administración."
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:166
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:165
msgid "Keep grace period"
msgstr "Mantener período de gracia"
@@ -18940,7 +18940,7 @@ msgstr "Mantener a Neko quieto"
msgid "Keep running"
msgstr "Seguir ejecutándose"
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:144
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:143
msgid "Keep subscription"
msgstr "Mantener suscripción"
@@ -19297,8 +19297,8 @@ msgstr "Botón izquierdo del mouse"
msgid "Left tooltip"
msgstr "Ayuda emergente a la izquierda"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:539
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:561
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:555
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:577
msgid "Legacy rate"
msgstr "Tarifa anterior"
@@ -21339,11 +21339,11 @@ msgstr "Mensual"
msgid "Monthly {monthlyPrice}"
msgstr "Mensual {monthlyPrice}"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:631
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:647
msgid "Monthly billing starts on <0>{pendingChangeDate}</0>."
msgstr "La facturación mensual comienza el <0>{pendingChangeDate}</0>."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:624
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:640
msgid "Monthly billing starts on <0>{pendingChangeDate}</0>. First monthly charge: {pendingInitialPriceLabel}. Future monthly renewals: {pendingRecurringPriceLabel}/month."
msgstr "La facturación mensual comienza el <0>{pendingChangeDate}</0>. Primer cargo mensual: {pendingInitialPriceLabel}. Renovaciones mensuales futuras: {pendingRecurringPriceLabel}/mes."
@@ -22269,12 +22269,12 @@ msgid "New password"
msgstr "Nueva contraseña"
#. Plutonium subscription card line shown when a move to a lower price is scheduled but the new amount is unknown. {pendingChangeDate} is a date already formatted and localized by code; never write a date into the translation.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:595
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:611
msgid "New price scheduled for <0>{pendingChangeDate}</0>."
msgstr "Nuevo precio programado para el <0>{pendingChangeDate}</0>."
#. Plutonium subscription card line shown when a move to a lower price is scheduled. {pendingChangeDate} is a date and {pendingTargetPriceLabel} is a currency amount, both already formatted and localized by code; never write a date or an amount into the translation.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:589
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:605
msgid "New price scheduled for <0>{pendingChangeDate}</0>. Renewals will be {pendingTargetPriceLabel} from then on."
msgstr "Nuevo precio programado para el <0>{pendingChangeDate}</0>. Las renovaciones serán de {pendingTargetPriceLabel} en adelante."
@@ -26152,7 +26152,7 @@ msgstr "Reacciones"
#. Billing button that cancels a scheduled subscription cancellation.
#. Button label on the premium-expired nagbar. Opens billing so the user can reactivate their subscription.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:746
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:762
#: src/features/app/components/layout/app_layout/nagbars/PremiumExpiredNagbar.tsx:25
msgid "Reactivate"
msgstr "Reactivar"
@@ -26375,8 +26375,8 @@ msgstr "Canjear para ti"
#. Billing button for entering a premium gift code.
#. Billing button for entering a premium gift code.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:719
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:307
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:735
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:306
msgid "Redeem gift code"
msgstr "Canjear código de regalo"
@@ -27147,7 +27147,7 @@ msgstr "Umbral de renovación (días)"
msgid "Renew window (days)"
msgstr "Ventana de renovación (días)"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:701
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:717
msgid "Renews on <0>{renewalDate}.</0>"
msgstr "Se renueva el <0>{renewalDate}.</0>"
@@ -27896,8 +27896,8 @@ msgstr "Restaurar ventana"
#. Billing button for restarting a subscription during the grace period.
#. Billing button for starting a new subscription after premium expired.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:738
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:742
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:754
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:758
msgid "Resubscribe"
msgstr "Volver a suscribirte"
@@ -32521,7 +32521,7 @@ msgid "Switch price"
msgstr "Cambiar precio"
#. Billing button that opens confirmation to move the subscription down to the current price. {listPriceNewLabel} is the localized new price.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:806
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:822
msgid "Switch to {listPriceNewLabel}"
msgstr "Cambiar a {listPriceNewLabel}"
@@ -32546,7 +32546,7 @@ msgstr "Cambiar a entrada directa"
#. Billing button that opens confirmation to switch to monthly billing.
#. Button confirming a change to monthly subscription billing.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:57
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:789
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:805
msgid "Switch to monthly"
msgstr "Cambiar a mensual"
@@ -32615,7 +32615,7 @@ msgstr "Cambiar a dos columnas"
#. Billing button that opens confirmation to switch to yearly billing.
#. Button confirming a change to yearly subscription billing.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:53
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:785
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:801
msgid "Switch to yearly"
msgstr "Cambiar a anual"
@@ -35865,7 +35865,7 @@ msgstr "Desbloquea los emojis personalizados en los MD con {premiumProductName}"
msgid "Unlock HD screen share with {premiumProductName}"
msgstr "Desbloquea la pantalla compartida en HD con {premiumProductName}"
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:217
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:216
msgid "Unlock higher limits and exclusive features while supporting an independent communication platform."
msgstr "Desbloquea límites más altos y funciones exclusivas mientras apoyas una plataforma de comunicación independiente."
@@ -39015,15 +39015,15 @@ msgstr "Anual {yearlyPrice}"
msgid "Yearly gift"
msgstr "Regalo de un año"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:618
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:634
msgid "Yearly upgrade scheduled for <0>{pendingChangeDate}</0>."
msgstr "Cambio a facturación anual programado para el <0>{pendingChangeDate}</0>."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:603
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:619
msgid "Yearly upgrade scheduled for <0>{pendingChangeDate}</0>. First yearly charge: {pendingInitialPriceLabel} after a {pendingCreditPriceLabel} credit. Future yearly renewals: {pendingRecurringPriceLabel}/year."
msgstr "Cambio a facturación anual programado para el <0>{pendingChangeDate}</0>. Primer cargo anual: {pendingInitialPriceLabel} después de aplicar un crédito de {pendingCreditPriceLabel}. Futuras renovaciones anuales: {pendingRecurringPriceLabel}/año."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:610
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:626
msgid "Yearly upgrade scheduled for <0>{pendingChangeDate}</0>. First yearly charge: {pendingInitialPriceLabel}. Future yearly renewals: {pendingRecurringPriceLabel}/year."
msgstr "Cambio a facturación anual programado para el <0>{pendingChangeDate}</0>. Primer cargo anual: {pendingInitialPriceLabel}. Futuras renovaciones anuales: {pendingRecurringPriceLabel}/año."
@@ -39493,10 +39493,10 @@ msgid "You just pressed Tab. Keyboard mode is now on so you can navigate {produc
msgstr "Acabas de presionar Tab. El modo de teclado está activado para que puedas navegar por {productName} sin mouse."
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:137
msgid "You keep your perks until your next renewal date, then have a 3-day grace period to resubscribe and keep your subscriber history."
msgstr "Conservarás tus beneficios hasta la próxima fecha de renovación y luego tendrás un período de gracia de 3 días para volver a suscribirte y mantener tu historial de suscriptor."
msgid "You keep your perks until your next renewal date. Reactivate before then to keep your subscriber history."
msgstr "Conservarás tus beneficios hasta la próxima fecha de renovación. Reactiva tu suscripción antes de esa fecha para mantener tu historial de suscriptor."
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:159
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:158
msgid "You lose all {PREMIUM_PRODUCT_NAME} perks immediately and your subscriber history resets. This cannot be undone."
msgstr "Perderás todos los beneficios de {PREMIUM_PRODUCT_NAME} inmediatamente y tu historial de suscripción se restablecerá. Esto no se puede deshacer."
@@ -40231,6 +40231,11 @@ msgstr "tu región"
msgid "Your registration needs an extra anti-spam check before you can continue."
msgstr "Tu registro necesita una verificación antispam adicional antes de que puedas continuar."
#. Plutonium subscription card text shown while a failed renewal payment is being retried. {graceDate} is a date already formatted and localized by code; never write a date into the translation.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:470
msgid "Your renewal payment failed but <0/> stay active until <1>{graceDate}</1>. Update your payment method before then to keep your subscription."
msgstr "Tu pago de renovación falló, pero los <0/> siguen activos hasta el <1>{graceDate}</1>. Actualiza tu método de pago antes de esa fecha para conservar tu suscripción."
#. Video settings note shown when the saved screen share quality is above what this account can send. Resolutions are short labels such as 1440p or Source and rates are whole numbers. FPS is a technical token.
#: src/features/user/components/modals/tabs/UserVideoTab.tsx:92
msgid "Your saved {savedResolution} at {savedFrameRate} FPS needs {premiumProductName}, so shares use {resolution} at {frameRate} FPS."
@@ -40252,7 +40257,7 @@ msgstr "Tu transmisión sigue activa"
msgid "Your subscription can't move to the new price right now."
msgstr "Tu suscripción no puede cambiarse al nuevo precio en este momento."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:470
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:486
msgid "Your subscription ended but <0/> stay active until <1>{graceDate}</1>. Resubscribe before then to keep your subscriber history."
msgstr "Tu suscripción finalizó, pero los <0/> siguen activos hasta el <1>{graceDate}</1>. Vuelve a suscribirte antes de esa fecha para conservar tu historial de suscriptor."
@@ -40281,7 +40286,7 @@ msgstr "Tu suscripción se cambió a facturación mensual."
msgid "Your subscription has been switched to yearly billing."
msgstr "Tu suscripción se cambió a facturación anual."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:512
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:528
msgid "Your subscription is active but perks are temporarily paused."
msgstr "Tu suscripción está activa, pero los beneficios están pausados temporalmente."
@@ -40301,7 +40306,7 @@ msgid "Your subscription moves to the new price on {effectiveDate}."
msgstr "Tu suscripción cambia al nuevo precio el {effectiveDate}."
#. Plutonium subscription card line shown to a subscriber on a legacy price whose subscription is already set to cancel. {cancelDate} is a date and {listPriceNewLabel} is a currency amount, both already formatted and localized by code; never write a date or an amount into the translation.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:666
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:682
msgid "Your subscription still ends on <0>{cancelDate}</0>. The current price is now {listPriceNewLabel}. If you reactivate, you can switch to it from here."
msgstr "Tu suscripción sigue programada para finalizar el <0>{cancelDate}</0>. El precio actual es {listPriceNewLabel}. Si la reactivas, podrás cambiar a ese precio desde aquí."
@@ -2471,7 +2471,7 @@ msgid "A Linux desktop update is available. Choose the package format for this s
msgstr "Hay una actualización de escritorio para Linux disponible. Elige el formato del paquete para este sistema y {productName} lo guardará localmente."
#. Plutonium subscription card line offering a move to a lower price. {listPriceEffectiveDate} is a date already formatted and localized by code; never write a date into the translation.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:684
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:700
msgid "A lower price is available. Switching takes effect on <0>{listPriceEffectiveDate}</0> and changes nothing else."
msgstr "Hay un precio más bajo disponible. El cambio entrará en vigor el <0>{listPriceEffectiveDate}</0> y no cambia nada más."
@@ -3487,19 +3487,19 @@ msgstr "Los controles de alineación solo están disponibles en pantallas más a
msgid "All"
msgstr "Todo"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:524
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:540
msgid "All <0/> for <1>{effectiveMonthlyPrice}/month</1>."
msgstr "Todas las <0/> por <1>{effectiveMonthlyPrice}/mes</1>."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:546
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:562
msgid "All <0/> for <1>{effectiveYearlyPrice}/year</1>."
msgstr "Todas las <0/> por <1>{effectiveYearlyPrice}/año</1>."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:567
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:583
msgid "All <0/> included with your subscription."
msgstr "Tu suscripción incluye todas las <0/>."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:514
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:530
msgid "All <0/>, forever. No billing, no renewals."
msgstr "Todas las <0/>, para siempre. Sin facturación ni renovaciones."
@@ -6469,7 +6469,7 @@ msgid "Cancel import"
msgstr "Cancelar importación"
#. Billing button that cancels a scheduled move to a lower subscription price.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:821
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:837
msgid "Cancel price change"
msgstr "Cancelar cambio de precio"
@@ -6484,14 +6484,14 @@ msgid "Cancel request"
msgstr "Cancelar solicitud"
#. Billing button that cancels a scheduled billing-cycle change.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:829
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:845
msgid "Cancel scheduled switch"
msgstr "Cancelar cambio programado"
#. Billing button that starts subscription cancellation.
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:844
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:142
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:860
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:141
#: src/features/user/components/settings_utils/search_index/PlutoniumIndex.ts:31
msgid "Cancel subscription"
msgstr "Cancelar suscripción"
@@ -6501,7 +6501,7 @@ msgid "Cancel subscription?"
msgstr "¿Cancelar suscripción?"
#. Plutonium subscription card hint shown to a subscriber who could move to a lower price but has another billing change already scheduled.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:647
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:663
msgid "Cancel the scheduled change to move to the current price instead."
msgstr "Cancela el cambio programado para pasar al precio actual en su lugar."
@@ -6511,7 +6511,7 @@ msgid "Cancel upload"
msgstr "Cancelar subida"
#. Billing button that cancels a scheduled yearly upgrade.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:825
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:841
msgid "Cancel yearly upgrade"
msgstr "Cancelar cambio al plan anual"
@@ -6530,7 +6530,7 @@ msgstr "Cancelando"
msgid "Cancellation"
msgstr "Cancelación de eco"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:501
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:517
msgid "Cancels on <0>{cancelDate}</0>. <1/> remain active until then."
msgstr "Se cancela el <0>{cancelDate}</0>. Las <1/> seguirán activas hasta entonces."
@@ -10872,7 +10872,7 @@ msgstr "Personalizar…"
#. Billing button that opens the external customer portal.
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:750
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:766
#: src/features/user/components/settings_utils/search_index/PlutoniumIndex.ts:39
msgid "Customer portal"
msgstr "Portal de clientes"
@@ -13877,15 +13877,15 @@ msgid "End date"
msgstr "Fecha de finalización"
#. Billing button that ends premium grace period immediately.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:856
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:872
msgid "End grace now"
msgstr "Finalizar período de gracia ahora"
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:164
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:163
msgid "End grace period"
msgstr "Finalizar período de gracia"
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:157
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:156
msgid "End grace period now?"
msgstr "¿Finalizar el período de gracia ahora?"
@@ -16347,7 +16347,7 @@ msgstr "Regalo: caduca pronto"
msgid "Gift: grace period (still have access)"
msgstr "Regalo: período de gracia (aún tienes acceso)"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:486
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:502
msgid "Gifted <0/> until <1>{giftEndDate}</1>. Does not renew automatically. Redeem more gift codes to extend."
msgstr "Las <0/> de regalo están activas hasta el <1>{giftEndDate}</1>. No se renuevan automáticamente. Canjea más códigos de regalo para prolongarlas."
@@ -16826,7 +16826,7 @@ msgid "Hate speech"
msgstr "Discurso de odio"
#. Premium page text shown on an instance where the premium tier cannot be bought, only redeemed. {PREMIUM_PRODUCT_NAME} is the premium tier name.
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:297
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:296
msgid "Have a gift code? Redeem it to unlock {PREMIUM_PRODUCT_NAME}."
msgstr "¿Tienes un código de regalo? Canjéalo para desbloquear {PREMIUM_PRODUCT_NAME}."
@@ -18926,7 +18926,7 @@ msgstr "Conservar archivos adjuntos al borrar el texto de una edición"
msgid "Keep free and premium tiers. You can customize the tiers, sell premium through Stripe, or hand out gift codes later from the admin panel."
msgstr "Mantén los niveles gratuito y premium. Puedes personalizar los niveles, vender premium a través de Stripe o entregar códigos de regalo más tarde desde el panel de administración."
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:166
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:165
msgid "Keep grace period"
msgstr "Mantener período de gracia"
@@ -18940,7 +18940,7 @@ msgstr "Mantener a Neko quieto"
msgid "Keep running"
msgstr "Seguir ejecutando"
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:144
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:143
msgid "Keep subscription"
msgstr "Mantener suscripción"
@@ -19297,8 +19297,8 @@ msgstr "Botón izquierdo del ratón"
msgid "Left tooltip"
msgstr "Ayuda emergente a la izquierda"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:539
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:561
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:555
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:577
msgid "Legacy rate"
msgstr "Tarifa antigua"
@@ -21339,11 +21339,11 @@ msgstr "Mensual"
msgid "Monthly {monthlyPrice}"
msgstr "Mensual {monthlyPrice}"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:631
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:647
msgid "Monthly billing starts on <0>{pendingChangeDate}</0>."
msgstr "La facturación mensual comienza el <0>{pendingChangeDate}</0>."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:624
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:640
msgid "Monthly billing starts on <0>{pendingChangeDate}</0>. First monthly charge: {pendingInitialPriceLabel}. Future monthly renewals: {pendingRecurringPriceLabel}/month."
msgstr "La facturación mensual comienza el <0>{pendingChangeDate}</0>. Primer cargo mensual: {pendingInitialPriceLabel}. Futuras renovaciones mensuales: {pendingRecurringPriceLabel}/mes."
@@ -22269,12 +22269,12 @@ msgid "New password"
msgstr "Nueva contraseña"
#. Plutonium subscription card line shown when a move to a lower price is scheduled but the new amount is unknown. {pendingChangeDate} is a date already formatted and localized by code; never write a date into the translation.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:595
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:611
msgid "New price scheduled for <0>{pendingChangeDate}</0>."
msgstr "Nuevo precio programado para el <0>{pendingChangeDate}</0>."
#. Plutonium subscription card line shown when a move to a lower price is scheduled. {pendingChangeDate} is a date and {pendingTargetPriceLabel} is a currency amount, both already formatted and localized by code; never write a date or an amount into the translation.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:589
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:605
msgid "New price scheduled for <0>{pendingChangeDate}</0>. Renewals will be {pendingTargetPriceLabel} from then on."
msgstr "Nuevo precio programado para el <0>{pendingChangeDate}</0>. Las renovaciones serán de {pendingTargetPriceLabel} a partir de entonces."
@@ -26152,7 +26152,7 @@ msgstr "Reacciones"
#. Billing button that cancels a scheduled subscription cancellation.
#. Button label on the premium-expired nagbar. Opens billing so the user can reactivate their subscription.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:746
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:762
#: src/features/app/components/layout/app_layout/nagbars/PremiumExpiredNagbar.tsx:25
msgid "Reactivate"
msgstr "Reactivar"
@@ -26375,8 +26375,8 @@ msgstr "Canjear para mí"
#. Billing button for entering a premium gift code.
#. Billing button for entering a premium gift code.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:719
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:307
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:735
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:306
msgid "Redeem gift code"
msgstr "Canjear código de regalo"
@@ -27147,7 +27147,7 @@ msgstr "Umbral de renovación (días)"
msgid "Renew window (days)"
msgstr "Ventana de renovación (días)"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:701
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:717
msgid "Renews on <0>{renewalDate}.</0>"
msgstr "Se renueva el <0>{renewalDate}.</0>"
@@ -27896,8 +27896,8 @@ msgstr "Restaurar ventana"
#. Billing button for restarting a subscription during the grace period.
#. Billing button for starting a new subscription after premium expired.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:738
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:742
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:754
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:758
msgid "Resubscribe"
msgstr "Volver a suscribirse"
@@ -32521,7 +32521,7 @@ msgid "Switch price"
msgstr "Cambiar a este precio"
#. Billing button that opens confirmation to move the subscription down to the current price. {listPriceNewLabel} is the localized new price.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:806
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:822
msgid "Switch to {listPriceNewLabel}"
msgstr "Cambiar a {listPriceNewLabel}"
@@ -32546,7 +32546,7 @@ msgstr "Cambiar a entrada directa"
#. Billing button that opens confirmation to switch to monthly billing.
#. Button confirming a change to monthly subscription billing.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:57
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:789
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:805
msgid "Switch to monthly"
msgstr "Cambiar a mensual"
@@ -32615,7 +32615,7 @@ msgstr "Cambiar a dos columnas"
#. Billing button that opens confirmation to switch to yearly billing.
#. Button confirming a change to yearly subscription billing.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:53
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:785
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:801
msgid "Switch to yearly"
msgstr "Cambiar a anual"
@@ -35865,7 +35865,7 @@ msgstr "Desbloquea los emojis personalizados en los MD con {premiumProductName}"
msgid "Unlock HD screen share with {premiumProductName}"
msgstr "Desbloquea la pantalla compartida en HD con {premiumProductName}"
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:217
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:216
msgid "Unlock higher limits and exclusive features while supporting an independent communication platform."
msgstr "Desbloquea límites más altos y funciones exclusivas mientras apoyas una plataforma de comunicación independiente."
@@ -39015,15 +39015,15 @@ msgstr "Anual {yearlyPrice}"
msgid "Yearly gift"
msgstr "Regalo de un año"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:618
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:634
msgid "Yearly upgrade scheduled for <0>{pendingChangeDate}</0>."
msgstr "Cambio a facturación anual programado para el <0>{pendingChangeDate}</0>."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:603
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:619
msgid "Yearly upgrade scheduled for <0>{pendingChangeDate}</0>. First yearly charge: {pendingInitialPriceLabel} after a {pendingCreditPriceLabel} credit. Future yearly renewals: {pendingRecurringPriceLabel}/year."
msgstr "Cambio a facturación anual programado para el <0>{pendingChangeDate}</0>. Primer cargo anual: {pendingInitialPriceLabel} después de aplicar un crédito de {pendingCreditPriceLabel}. Futuras renovaciones anuales: {pendingRecurringPriceLabel}/año."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:610
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:626
msgid "Yearly upgrade scheduled for <0>{pendingChangeDate}</0>. First yearly charge: {pendingInitialPriceLabel}. Future yearly renewals: {pendingRecurringPriceLabel}/year."
msgstr "Cambio a facturación anual programado para el <0>{pendingChangeDate}</0>. Primer cargo anual: {pendingInitialPriceLabel}. Futuras renovaciones anuales: {pendingRecurringPriceLabel}/año."
@@ -39493,10 +39493,10 @@ msgid "You just pressed Tab. Keyboard mode is now on so you can navigate {produc
msgstr "Acabas de pulsar Tab. El modo de teclado está activado para que puedas navegar por {productName} sin ratón."
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:137
msgid "You keep your perks until your next renewal date, then have a 3-day grace period to resubscribe and keep your subscriber history."
msgstr "Conservarás tus ventajas hasta la próxima fecha de renovación y, después, tendrás un periodo de gracia de 3 días para volver a suscribirte y mantener tu historial de suscriptor."
msgid "You keep your perks until your next renewal date. Reactivate before then to keep your subscriber history."
msgstr "Conservarás tus ventajas hasta la próxima fecha de renovación. Reactiva tu suscripción antes de esa fecha para mantener tu historial de suscriptor."
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:159
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:158
msgid "You lose all {PREMIUM_PRODUCT_NAME} perks immediately and your subscriber history resets. This cannot be undone."
msgstr "Perderás todas las ventajas de {PREMIUM_PRODUCT_NAME} inmediatamente y tu historial de suscripción se restablecerá. Esto no se puede deshacer."
@@ -40231,6 +40231,11 @@ msgstr "tu región"
msgid "Your registration needs an extra anti-spam check before you can continue."
msgstr "Tu registro necesita una comprobación antispam adicional antes de que puedas continuar."
#. Plutonium subscription card text shown while a failed renewal payment is being retried. {graceDate} is a date already formatted and localized by code; never write a date into the translation.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:470
msgid "Your renewal payment failed but <0/> stay active until <1>{graceDate}</1>. Update your payment method before then to keep your subscription."
msgstr "El pago de renovación ha fallado, pero las <0/> siguen activas hasta el <1>{graceDate}</1>. Actualiza tu método de pago antes de esa fecha para mantener tu suscripción."
#. Video settings note shown when the saved screen share quality is above what this account can send. Resolutions are short labels such as 1440p or Source and rates are whole numbers. FPS is a technical token.
#: src/features/user/components/modals/tabs/UserVideoTab.tsx:92
msgid "Your saved {savedResolution} at {savedFrameRate} FPS needs {premiumProductName}, so shares use {resolution} at {frameRate} FPS."
@@ -40252,7 +40257,7 @@ msgstr "Tu transmisión sigue activa"
msgid "Your subscription can't move to the new price right now."
msgstr "Tu suscripción no puede cambiarse al nuevo precio en este momento."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:470
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:486
msgid "Your subscription ended but <0/> stay active until <1>{graceDate}</1>. Resubscribe before then to keep your subscriber history."
msgstr "Tu suscripción ha terminado, pero las <0/> siguen activas hasta el <1>{graceDate}</1>. Vuelve a suscribirte antes de esa fecha para mantener tu historial de suscriptor."
@@ -40281,7 +40286,7 @@ msgstr "Tu suscripción se ha cambiado a facturación mensual."
msgid "Your subscription has been switched to yearly billing."
msgstr "Tu suscripción se ha cambiado a facturación anual."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:512
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:528
msgid "Your subscription is active but perks are temporarily paused."
msgstr "Tu suscripción está activa, pero las ventajas están en pausa temporalmente."
@@ -40301,7 +40306,7 @@ msgid "Your subscription moves to the new price on {effectiveDate}."
msgstr "Tu suscripción cambiará al nuevo precio el {effectiveDate}."
#. Plutonium subscription card line shown to a subscriber on a legacy price whose subscription is already set to cancel. {cancelDate} is a date and {listPriceNewLabel} is a currency amount, both already formatted and localized by code; never write a date or an amount into the translation.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:666
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:682
msgid "Your subscription still ends on <0>{cancelDate}</0>. The current price is now {listPriceNewLabel}. If you reactivate, you can switch to it from here."
msgstr "Tu suscripción sigue activa hasta el <0>{cancelDate}</0>. El precio actual es de {listPriceNewLabel}. Si la reactivas, podrás cambiar a él desde aquí."
@@ -2471,7 +2471,7 @@ msgid "A Linux desktop update is available. Choose the package format for this s
msgstr "Linux-työpöytäpäivitys on saatavilla. Valitse pakettimuoto tälle järjestelmälle, niin {productName} tallentaa sen paikallisesti."
#. Plutonium subscription card line offering a move to a lower price. {listPriceEffectiveDate} is a date already formatted and localized by code; never write a date into the translation.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:684
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:700
msgid "A lower price is available. Switching takes effect on <0>{listPriceEffectiveDate}</0> and changes nothing else."
msgstr "Saatavilla on edullisempi hinta. Vaihto astuu voimaan <0>{listPriceEffectiveDate}</0>, eikä se muuta mitään muuta."
@@ -3487,19 +3487,19 @@ msgstr "Kohdistussäätimet ovat käytettävissä vain leveämmillä näytöill
msgid "All"
msgstr "Kaikki"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:524
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:540
msgid "All <0/> for <1>{effectiveMonthlyPrice}/month</1>."
msgstr "Kaikki <0/> hintaan <1>{effectiveMonthlyPrice}/kuukausi</1>."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:546
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:562
msgid "All <0/> for <1>{effectiveYearlyPrice}/year</1>."
msgstr "Kaikki <0/> hintaan <1>{effectiveYearlyPrice}/vuosi</1>."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:567
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:583
msgid "All <0/> included with your subscription."
msgstr "Kaikki <0/> sisältyvät tilaukseesi."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:514
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:530
msgid "All <0/>, forever. No billing, no renewals."
msgstr "Kaikki <0/> ikuisesti. Ei laskutusta, ei uusimisia."
@@ -6469,7 +6469,7 @@ msgid "Cancel import"
msgstr "Peruuta tuonti"
#. Billing button that cancels a scheduled move to a lower subscription price.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:821
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:837
msgid "Cancel price change"
msgstr "Peruuta hinnanmuutos"
@@ -6484,14 +6484,14 @@ msgid "Cancel request"
msgstr "Peruuta pyyntö"
#. Billing button that cancels a scheduled billing-cycle change.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:829
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:845
msgid "Cancel scheduled switch"
msgstr "Peruuta ajoitettu vaihto"
#. Billing button that starts subscription cancellation.
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:844
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:142
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:860
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:141
#: src/features/user/components/settings_utils/search_index/PlutoniumIndex.ts:31
msgid "Cancel subscription"
msgstr "Peruuta tilaus"
@@ -6501,7 +6501,7 @@ msgid "Cancel subscription?"
msgstr "Peruuta tilaus?"
#. Plutonium subscription card hint shown to a subscriber who could move to a lower price but has another billing change already scheduled.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:647
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:663
msgid "Cancel the scheduled change to move to the current price instead."
msgstr "Peruuta ajoitettu muutos ja siirry sen sijaan nykyiseen hintaan."
@@ -6511,7 +6511,7 @@ msgid "Cancel upload"
msgstr "Peruuta lähetys"
#. Billing button that cancels a scheduled yearly upgrade.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:825
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:841
msgid "Cancel yearly upgrade"
msgstr "Peruuta vaihto vuositilaukseen"
@@ -6530,7 +6530,7 @@ msgstr "Peruutetaan"
msgid "Cancellation"
msgstr "Kaiunvaimennus"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:501
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:517
msgid "Cancels on <0>{cancelDate}</0>. <1/> remain active until then."
msgstr "Peruuntuu <0>{cancelDate}</0>. <1/> pysyvät aktiivisina siihen asti."
@@ -10872,7 +10872,7 @@ msgstr "Mukautettu…"
#. Billing button that opens the external customer portal.
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:750
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:766
#: src/features/user/components/settings_utils/search_index/PlutoniumIndex.ts:39
msgid "Customer portal"
msgstr "Asiakasportaali"
@@ -13877,15 +13877,15 @@ msgid "End date"
msgstr "Päättymispäivä"
#. Billing button that ends premium grace period immediately.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:856
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:872
msgid "End grace now"
msgstr "Lopeta armonaika nyt"
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:164
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:163
msgid "End grace period"
msgstr "Lopeta armonaika"
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:157
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:156
msgid "End grace period now?"
msgstr "Päätetäänkö armonaika nyt?"
@@ -16347,7 +16347,7 @@ msgstr "Lahja: vanhenee pian"
msgid "Gift: grace period (still have access)"
msgstr "Lahja: armonaika (käyttöoikeus on yhä voimassa)"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:486
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:502
msgid "Gifted <0/> until <1>{giftEndDate}</1>. Does not renew automatically. Redeem more gift codes to extend."
msgstr "Sait <0/> lahjaksi <1>{giftEndDate}</1> asti. Lahja ei uusiudu automaattisesti. Lunasta lisää lahjakoodeja jatkaaksesi."
@@ -16826,7 +16826,7 @@ msgid "Hate speech"
msgstr "Vihapuhe"
#. Premium page text shown on an instance where the premium tier cannot be bought, only redeemed. {PREMIUM_PRODUCT_NAME} is the premium tier name.
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:297
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:296
msgid "Have a gift code? Redeem it to unlock {PREMIUM_PRODUCT_NAME}."
msgstr "Onko sinulla lahjakoodi? Lunasta se avataksesi {PREMIUM_PRODUCT_NAME}."
@@ -18926,7 +18926,7 @@ msgstr "Säilytä liitteet muokkauksen tyhjentämisen yhteydessä"
msgid "Keep free and premium tiers. You can customize the tiers, sell premium through Stripe, or hand out gift codes later from the admin panel."
msgstr "Pidä ilmaiset ja premium-tasot. Voit muokata tasoja, myydä premiumia Stripellä tai jakaa lahjakoodeja myöhemmin ylläpitopaneelista."
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:166
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:165
msgid "Keep grace period"
msgstr "Säilytä armonaika"
@@ -18940,7 +18940,7 @@ msgstr "Pidä Neko paikallaan"
msgid "Keep running"
msgstr "Pidä käynnissä"
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:144
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:143
msgid "Keep subscription"
msgstr "Säilytä tilaus"
@@ -19297,8 +19297,8 @@ msgstr "Hiiren vasen painike"
msgid "Left tooltip"
msgstr "Vasen työkaluvihje"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:539
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:561
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:555
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:577
msgid "Legacy rate"
msgstr "Vanha hinta"
@@ -21339,11 +21339,11 @@ msgstr "Kuukausittain"
msgid "Monthly {monthlyPrice}"
msgstr "Kuukausittain {monthlyPrice}"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:631
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:647
msgid "Monthly billing starts on <0>{pendingChangeDate}</0>."
msgstr "Kuukausilaskutus alkaa <0>{pendingChangeDate}</0>."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:624
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:640
msgid "Monthly billing starts on <0>{pendingChangeDate}</0>. First monthly charge: {pendingInitialPriceLabel}. Future monthly renewals: {pendingRecurringPriceLabel}/month."
msgstr "Kuukausilaskutus alkaa <0>{pendingChangeDate}</0>. Ensimmäinen kuukausimaksu: {pendingInitialPriceLabel}. Tulevat kuukausittaiset uusinnat: {pendingRecurringPriceLabel}/kuukausi."
@@ -22269,12 +22269,12 @@ msgid "New password"
msgstr "Uusi salasana"
#. Plutonium subscription card line shown when a move to a lower price is scheduled but the new amount is unknown. {pendingChangeDate} is a date already formatted and localized by code; never write a date into the translation.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:595
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:611
msgid "New price scheduled for <0>{pendingChangeDate}</0>."
msgstr "Uusi hinta on ajoitettu päivälle <0>{pendingChangeDate}</0>."
#. Plutonium subscription card line shown when a move to a lower price is scheduled. {pendingChangeDate} is a date and {pendingTargetPriceLabel} is a currency amount, both already formatted and localized by code; never write a date or an amount into the translation.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:589
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:605
msgid "New price scheduled for <0>{pendingChangeDate}</0>. Renewals will be {pendingTargetPriceLabel} from then on."
msgstr "Uusi hinta on ajoitettu päivälle <0>{pendingChangeDate}</0>. Uusiminen maksaa sen jälkeen {pendingTargetPriceLabel}."
@@ -26152,7 +26152,7 @@ msgstr "Reaktiot"
#. Billing button that cancels a scheduled subscription cancellation.
#. Button label on the premium-expired nagbar. Opens billing so the user can reactivate their subscription.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:746
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:762
#: src/features/app/components/layout/app_layout/nagbars/PremiumExpiredNagbar.tsx:25
msgid "Reactivate"
msgstr "Aktivoi uudelleen"
@@ -26375,8 +26375,8 @@ msgstr "Lunasta itsellesi"
#. Billing button for entering a premium gift code.
#. Billing button for entering a premium gift code.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:719
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:307
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:735
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:306
msgid "Redeem gift code"
msgstr "Lunasta lahjakoodi"
@@ -27147,7 +27147,7 @@ msgstr "Uusimiskynnys (päiviä)"
msgid "Renew window (days)"
msgstr "Uusimisikkuna (päiviä)"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:701
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:717
msgid "Renews on <0>{renewalDate}.</0>"
msgstr "Uusiutuu <0>{renewalDate}.</0>"
@@ -27896,8 +27896,8 @@ msgstr "Palauta ikkuna"
#. Billing button for restarting a subscription during the grace period.
#. Billing button for starting a new subscription after premium expired.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:738
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:742
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:754
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:758
msgid "Resubscribe"
msgstr "Tilaa uudelleen"
@@ -32521,7 +32521,7 @@ msgid "Switch price"
msgstr "Vaihda hintaa"
#. Billing button that opens confirmation to move the subscription down to the current price. {listPriceNewLabel} is the localized new price.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:806
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:822
msgid "Switch to {listPriceNewLabel}"
msgstr "Vaihda hintaan {listPriceNewLabel}"
@@ -32546,7 +32546,7 @@ msgstr "Vaihda suoraan syöttöön"
#. Billing button that opens confirmation to switch to monthly billing.
#. Button confirming a change to monthly subscription billing.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:57
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:789
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:805
msgid "Switch to monthly"
msgstr "Vaihda kuukausitilaukseen"
@@ -32615,7 +32615,7 @@ msgstr "Vaihda kaksipalstaiseen näkymään"
#. Billing button that opens confirmation to switch to yearly billing.
#. Button confirming a change to yearly subscription billing.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:53
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:785
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:801
msgid "Switch to yearly"
msgstr "Vaihda vuositilaukseen"
@@ -35865,7 +35865,7 @@ msgstr "Avaa mukautetut emojit yksityisviesteissä {premiumProductName}-tilaukse
msgid "Unlock HD screen share with {premiumProductName}"
msgstr "Avaa HD-näytönjako käyttöön {premiumProductName}-tilauksella"
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:217
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:216
msgid "Unlock higher limits and exclusive features while supporting an independent communication platform."
msgstr "Saat käyttöösi suuremmat rajat ja vain tilaajille tarkoitetut ominaisuudet sekä tuet samalla riippumatonta viestintäalustaa."
@@ -39015,15 +39015,15 @@ msgstr "Vuosittain {yearlyPrice}"
msgid "Yearly gift"
msgstr "Vuosilahja"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:618
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:634
msgid "Yearly upgrade scheduled for <0>{pendingChangeDate}</0>."
msgstr "Päivitys vuositilaukseen on ajoitettu päivälle <0>{pendingChangeDate}</0>."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:603
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:619
msgid "Yearly upgrade scheduled for <0>{pendingChangeDate}</0>. First yearly charge: {pendingInitialPriceLabel} after a {pendingCreditPriceLabel} credit. Future yearly renewals: {pendingRecurringPriceLabel}/year."
msgstr "Päivitys vuositilaukseen on ajoitettu päivälle <0>{pendingChangeDate}</0>. Ensimmäinen vuosimaksu: {pendingInitialPriceLabel} hyvityksen {pendingCreditPriceLabel} jälkeen. Tulevat vuosiuusinnat: {pendingRecurringPriceLabel}/vuosi."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:610
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:626
msgid "Yearly upgrade scheduled for <0>{pendingChangeDate}</0>. First yearly charge: {pendingInitialPriceLabel}. Future yearly renewals: {pendingRecurringPriceLabel}/year."
msgstr "Päivitys vuositilaukseen on ajoitettu päivälle <0>{pendingChangeDate}</0>. Ensimmäinen vuosimaksu: {pendingInitialPriceLabel}. Tulevat vuosiuusinnat: {pendingRecurringPriceLabel}/vuosi."
@@ -39493,10 +39493,10 @@ msgid "You just pressed Tab. Keyboard mode is now on so you can navigate {produc
msgstr "Painoit juuri sarkainta. Näppäimistötila on nyt käytössä, joten voit liikkua {productName}-sovelluksessa ilman hiirtä."
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:137
msgid "You keep your perks until your next renewal date, then have a 3-day grace period to resubscribe and keep your subscriber history."
msgstr "Pidät etusi seuraavaan uusimispäivään asti, minkä jälkeen sinulla on kolmen päivän lisäaika tilata uudelleen ja säilyttää tilaushistoriasi."
msgid "You keep your perks until your next renewal date. Reactivate before then to keep your subscriber history."
msgstr "Pidät etusi seuraavaan uusimispäivään asti. Aktivoi tilaus uudelleen ennen sitä, niin säilytät tilaushistoriasi."
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:159
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:158
msgid "You lose all {PREMIUM_PRODUCT_NAME} perks immediately and your subscriber history resets. This cannot be undone."
msgstr "Menetät kaikki {PREMIUM_PRODUCT_NAME}-edut välittömästi ja tilaushistoriasi nollataan. Tätä ei voi kumota."
@@ -40231,6 +40231,11 @@ msgstr "alueesi"
msgid "Your registration needs an extra anti-spam check before you can continue."
msgstr "Rekisteröitymisesi vaatii ylimääräisen roskapostitarkistuksen, ennen kuin voit jatkaa."
#. Plutonium subscription card text shown while a failed renewal payment is being retried. {graceDate} is a date already formatted and localized by code; never write a date into the translation.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:470
msgid "Your renewal payment failed but <0/> stay active until <1>{graceDate}</1>. Update your payment method before then to keep your subscription."
msgstr "Uusimismaksusi epäonnistui, mutta <0/> pysyvät voimassa <1>{graceDate}</1> asti. Päivitä maksutapasi ennen sitä, niin säilytät tilauksesi."
#. Video settings note shown when the saved screen share quality is above what this account can send. Resolutions are short labels such as 1440p or Source and rates are whole numbers. FPS is a technical token.
#: src/features/user/components/modals/tabs/UserVideoTab.tsx:92
msgid "Your saved {savedResolution} at {savedFrameRate} FPS needs {premiumProductName}, so shares use {resolution} at {frameRate} FPS."
@@ -40252,7 +40257,7 @@ msgstr "Striimisi on edelleen käynnissä"
msgid "Your subscription can't move to the new price right now."
msgstr "Tilauksesi ei voi siirtyä uuteen hintaan juuri nyt."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:470
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:486
msgid "Your subscription ended but <0/> stay active until <1>{graceDate}</1>. Resubscribe before then to keep your subscriber history."
msgstr "Tilauksesi päättyi, mutta <0/> pysyvät voimassa <1>{graceDate}</1> asti. Tilaa uudelleen ennen sitä, niin säilytät tilaushistoriasi."
@@ -40281,7 +40286,7 @@ msgstr "Tilauksesi on nyt kuukausilaskutuksella."
msgid "Your subscription has been switched to yearly billing."
msgstr "Tilauksesi on nyt vuosilaskutuksella."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:512
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:528
msgid "Your subscription is active but perks are temporarily paused."
msgstr "Tilauksesi on aktiivinen, mutta edut ovat väliaikaisesti keskeytettyinä."
@@ -40301,7 +40306,7 @@ msgid "Your subscription moves to the new price on {effectiveDate}."
msgstr "Tilauksesi siirtyy uuteen hintaan {effectiveDate}."
#. Plutonium subscription card line shown to a subscriber on a legacy price whose subscription is already set to cancel. {cancelDate} is a date and {listPriceNewLabel} is a currency amount, both already formatted and localized by code; never write a date or an amount into the translation.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:666
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:682
msgid "Your subscription still ends on <0>{cancelDate}</0>. The current price is now {listPriceNewLabel}. If you reactivate, you can switch to it from here."
msgstr "Tilauksesi päättyy silti <0>{cancelDate}</0>. Nykyinen hinta on nyt {listPriceNewLabel}. Jos aktivoit sen uudelleen, voit vaihtaa siihen täältä."
@@ -2471,7 +2471,7 @@ msgid "A Linux desktop update is available. Choose the package format for this s
msgstr "Une mise à jour de l’application pour Linux est disponible. Choisissez le format de paquet adapté à ce système et {productName} l’enregistrera sur votre ordinateur."
#. Plutonium subscription card line offering a move to a lower price. {listPriceEffectiveDate} is a date already formatted and localized by code; never write a date into the translation.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:684
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:700
msgid "A lower price is available. Switching takes effect on <0>{listPriceEffectiveDate}</0> and changes nothing else."
msgstr "Un prix inférieur est disponible. Le changement prendra effet le <0>{listPriceEffectiveDate}</0> et ne changera rien d'autre."
@@ -3487,19 +3487,19 @@ msgstr "Les contrôles d'alignement ne sont disponibles que sur les écrans plus
msgid "All"
msgstr "Tout"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:524
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:540
msgid "All <0/> for <1>{effectiveMonthlyPrice}/month</1>."
msgstr "Tous les <0/> pour <1>{effectiveMonthlyPrice}/mois</1>."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:546
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:562
msgid "All <0/> for <1>{effectiveYearlyPrice}/year</1>."
msgstr "Tous les <0/> pour <1>{effectiveYearlyPrice}/an</1>."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:567
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:583
msgid "All <0/> included with your subscription."
msgstr "Tous les <0/> sont inclus dans votre abonnement."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:514
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:530
msgid "All <0/>, forever. No billing, no renewals."
msgstr "Tous les <0/>, à vie. Sans facturation ni renouvellement."
@@ -6469,7 +6469,7 @@ msgid "Cancel import"
msgstr "Annuler l'importation"
#. Billing button that cancels a scheduled move to a lower subscription price.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:821
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:837
msgid "Cancel price change"
msgstr "Annuler la modification de prix"
@@ -6484,14 +6484,14 @@ msgid "Cancel request"
msgstr "Annuler la demande"
#. Billing button that cancels a scheduled billing-cycle change.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:829
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:845
msgid "Cancel scheduled switch"
msgstr "Annuler le changement programmé"
#. Billing button that starts subscription cancellation.
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:844
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:142
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:860
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:141
#: src/features/user/components/settings_utils/search_index/PlutoniumIndex.ts:31
msgid "Cancel subscription"
msgstr "Résilier l’abonnement"
@@ -6501,7 +6501,7 @@ msgid "Cancel subscription?"
msgstr "Résilier l’abonnement ?"
#. Plutonium subscription card hint shown to a subscriber who could move to a lower price but has another billing change already scheduled.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:647
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:663
msgid "Cancel the scheduled change to move to the current price instead."
msgstr "Annuler la modification prévue pour passer au prix actuel à la place."
@@ -6511,7 +6511,7 @@ msgid "Cancel upload"
msgstr "Annuler l'envoi"
#. Billing button that cancels a scheduled yearly upgrade.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:825
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:841
msgid "Cancel yearly upgrade"
msgstr "Annuler le passage à l’abonnement annuel"
@@ -6530,7 +6530,7 @@ msgstr "Résiliation programmée"
msgid "Cancellation"
msgstr "Annulation de l’écho"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:501
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:517
msgid "Cancels on <0>{cancelDate}</0>. <1/> remain active until then."
msgstr "Résiliation le <0>{cancelDate}</0>. Les <1/> restent actifs jusqu’à cette date."
@@ -10872,7 +10872,7 @@ msgstr "Personnalisé…"
#. Billing button that opens the external customer portal.
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:750
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:766
#: src/features/user/components/settings_utils/search_index/PlutoniumIndex.ts:39
msgid "Customer portal"
msgstr "Portail client"
@@ -13877,15 +13877,15 @@ msgid "End date"
msgstr "Date de fin"
#. Billing button that ends premium grace period immediately.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:856
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:872
msgid "End grace now"
msgstr "Mettre fin à la période de grâce"
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:164
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:163
msgid "End grace period"
msgstr "Mettre fin à la période de grâce"
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:157
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:156
msgid "End grace period now?"
msgstr "Mettre fin à la période de grâce maintenant ?"
@@ -16347,7 +16347,7 @@ msgstr "Cadeau : expire bientôt"
msgid "Gift: grace period (still have access)"
msgstr "Cadeau : période de grâce (accès toujours actif)"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:486
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:502
msgid "Gifted <0/> until <1>{giftEndDate}</1>. Does not renew automatically. Redeem more gift codes to extend."
msgstr "Les <0/> vous sont offerts jusqu’au <1>{giftEndDate}</1>. Le cadeau ne se renouvelle pas automatiquement. Utilisez d’autres codes cadeaux pour prolonger cette période."
@@ -16826,7 +16826,7 @@ msgid "Hate speech"
msgstr "Discours haineux"
#. Premium page text shown on an instance where the premium tier cannot be bought, only redeemed. {PREMIUM_PRODUCT_NAME} is the premium tier name.
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:297
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:296
msgid "Have a gift code? Redeem it to unlock {PREMIUM_PRODUCT_NAME}."
msgstr "Vous avez un code cadeau ? Échangez-le pour débloquer {PREMIUM_PRODUCT_NAME}."
@@ -18926,7 +18926,7 @@ msgstr "Conserver les pièces jointes lors de la suppression d'une modification"
msgid "Keep free and premium tiers. You can customize the tiers, sell premium through Stripe, or hand out gift codes later from the admin panel."
msgstr "Conservez les niveaux gratuit et premium. Vous pourrez personnaliser les niveaux, vendre des abonnements premium via Stripe, ou distribuer des codes cadeaux plus tard depuis le panneau d'administration."
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:166
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:165
msgid "Keep grace period"
msgstr "Conserver la période de grâce"
@@ -18940,7 +18940,7 @@ msgstr "Garder Neko immobile"
msgid "Keep running"
msgstr "Continuer à fonctionner"
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:144
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:143
msgid "Keep subscription"
msgstr "Garder l'abonnement"
@@ -19297,8 +19297,8 @@ msgstr "Bouton gauche de la souris"
msgid "Left tooltip"
msgstr "Info-bulle gauche"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:539
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:561
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:555
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:577
msgid "Legacy rate"
msgstr "Ancien tarif"
@@ -21339,11 +21339,11 @@ msgstr "Mensuel"
msgid "Monthly {monthlyPrice}"
msgstr "{monthlyPrice} par mois"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:631
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:647
msgid "Monthly billing starts on <0>{pendingChangeDate}</0>."
msgstr "La facturation mensuelle commence le <0>{pendingChangeDate}</0>."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:624
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:640
msgid "Monthly billing starts on <0>{pendingChangeDate}</0>. First monthly charge: {pendingInitialPriceLabel}. Future monthly renewals: {pendingRecurringPriceLabel}/month."
msgstr "La facturation mensuelle commence le <0>{pendingChangeDate}</0>. Premier paiement mensuel : {pendingInitialPriceLabel}. Renouvellements mensuels futurs : {pendingRecurringPriceLabel}/mois."
@@ -22269,12 +22269,12 @@ msgid "New password"
msgstr "Nouveau mot de passe"
#. Plutonium subscription card line shown when a move to a lower price is scheduled but the new amount is unknown. {pendingChangeDate} is a date already formatted and localized by code; never write a date into the translation.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:595
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:611
msgid "New price scheduled for <0>{pendingChangeDate}</0>."
msgstr "Nouveau prix prévu pour le <0>{pendingChangeDate}</0>."
#. Plutonium subscription card line shown when a move to a lower price is scheduled. {pendingChangeDate} is a date and {pendingTargetPriceLabel} is a currency amount, both already formatted and localized by code; never write a date or an amount into the translation.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:589
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:605
msgid "New price scheduled for <0>{pendingChangeDate}</0>. Renewals will be {pendingTargetPriceLabel} from then on."
msgstr "Nouveau prix prévu pour le <0>{pendingChangeDate}</0>. Les renouvellements seront à {pendingTargetPriceLabel} à partir de cette date."
@@ -26152,7 +26152,7 @@ msgstr "Réactions"
#. Billing button that cancels a scheduled subscription cancellation.
#. Button label on the premium-expired nagbar. Opens billing so the user can reactivate their subscription.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:746
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:762
#: src/features/app/components/layout/app_layout/nagbars/PremiumExpiredNagbar.tsx:25
msgid "Reactivate"
msgstr "Réactiver"
@@ -26375,8 +26375,8 @@ msgstr "Utiliser pour soi"
#. Billing button for entering a premium gift code.
#. Billing button for entering a premium gift code.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:719
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:307
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:735
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:306
msgid "Redeem gift code"
msgstr "Utiliser un code cadeau"
@@ -27147,7 +27147,7 @@ msgstr "Seuil de renouvellement (jours)"
msgid "Renew window (days)"
msgstr "Fenêtre de renouvellement (jours)"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:701
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:717
msgid "Renews on <0>{renewalDate}.</0>"
msgstr "Renouvellement le <0>{renewalDate}.</0>"
@@ -27896,8 +27896,8 @@ msgstr "Restaurer la fenêtre"
#. Billing button for restarting a subscription during the grace period.
#. Billing button for starting a new subscription after premium expired.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:738
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:742
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:754
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:758
msgid "Resubscribe"
msgstr "Se réabonner"
@@ -32521,7 +32521,7 @@ msgid "Switch price"
msgstr "Changer de prix"
#. Billing button that opens confirmation to move the subscription down to the current price. {listPriceNewLabel} is the localized new price.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:806
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:822
msgid "Switch to {listPriceNewLabel}"
msgstr "Passer à {listPriceNewLabel}"
@@ -32546,7 +32546,7 @@ msgstr "Passer en mode Entrée directe"
#. Billing button that opens confirmation to switch to monthly billing.
#. Button confirming a change to monthly subscription billing.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:57
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:789
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:805
msgid "Switch to monthly"
msgstr "Passer au forfait mensuel"
@@ -32615,7 +32615,7 @@ msgstr "Passer en mode deux colonnes"
#. Billing button that opens confirmation to switch to yearly billing.
#. Button confirming a change to yearly subscription billing.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:53
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:785
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:801
msgid "Switch to yearly"
msgstr "Passer à l'abonnement annuel"
@@ -35865,7 +35865,7 @@ msgstr "Débloquez les emojis personnalisés dans les MP avec {premiumProductNam
msgid "Unlock HD screen share with {premiumProductName}"
msgstr "Débloquez le partage d'écran HD avec {premiumProductName}"
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:217
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:216
msgid "Unlock higher limits and exclusive features while supporting an independent communication platform."
msgstr "Débloquez des limites plus élevées et des fonctionnalités exclusives tout en soutenant une plateforme de communication indépendante."
@@ -39015,15 +39015,15 @@ msgstr "{yearlyPrice} par an"
msgid "Yearly gift"
msgstr "Cadeau d’un an"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:618
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:634
msgid "Yearly upgrade scheduled for <0>{pendingChangeDate}</0>."
msgstr "Passage à l’abonnement annuel prévu le <0>{pendingChangeDate}</0>."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:603
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:619
msgid "Yearly upgrade scheduled for <0>{pendingChangeDate}</0>. First yearly charge: {pendingInitialPriceLabel} after a {pendingCreditPriceLabel} credit. Future yearly renewals: {pendingRecurringPriceLabel}/year."
msgstr "Passage à l’abonnement annuel prévu le <0>{pendingChangeDate}</0>. Premier paiement annuel : {pendingInitialPriceLabel}, après déduction d’un avoir de {pendingCreditPriceLabel}. Renouvellements suivants : {pendingRecurringPriceLabel}/an."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:610
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:626
msgid "Yearly upgrade scheduled for <0>{pendingChangeDate}</0>. First yearly charge: {pendingInitialPriceLabel}. Future yearly renewals: {pendingRecurringPriceLabel}/year."
msgstr "Passage à l’abonnement annuel prévu le <0>{pendingChangeDate}</0>. Premier paiement annuel : {pendingInitialPriceLabel}. Renouvellements suivants : {pendingRecurringPriceLabel}/an."
@@ -39493,10 +39493,10 @@ msgid "You just pressed Tab. Keyboard mode is now on so you can navigate {produc
msgstr "Vous venez d'appuyer sur Tab. Le mode clavier est maintenant activé pour que vous puissiez naviguer dans {productName} sans souris."
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:137
msgid "You keep your perks until your next renewal date, then have a 3-day grace period to resubscribe and keep your subscriber history."
msgstr "Vous conservez vos avantages jusqu’à la date de votre prochain renouvellement, puis vous disposez d’une période de grâce de 3 jours pour vous réabonner et conserver votre historique d’abonné."
msgid "You keep your perks until your next renewal date. Reactivate before then to keep your subscriber history."
msgstr "Vous conservez vos avantages jusqu’à la date de votre prochain renouvellement. Réactivez votre abonnement avant cette date pour conserver votre historique d’abonné."
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:159
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:158
msgid "You lose all {PREMIUM_PRODUCT_NAME} perks immediately and your subscriber history resets. This cannot be undone."
msgstr "Vous perdez immédiatement tous les avantages {PREMIUM_PRODUCT_NAME} et votre historique d’abonné est réinitialisé. Cette action est irréversible."
@@ -40231,6 +40231,11 @@ msgstr "votre région"
msgid "Your registration needs an extra anti-spam check before you can continue."
msgstr "Votre inscription nécessite une vérification anti-spam supplémentaire avant de pouvoir continuer."
#. Plutonium subscription card text shown while a failed renewal payment is being retried. {graceDate} is a date already formatted and localized by code; never write a date into the translation.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:470
msgid "Your renewal payment failed but <0/> stay active until <1>{graceDate}</1>. Update your payment method before then to keep your subscription."
msgstr "Le paiement de votre renouvellement a échoué, mais les <0/> restent actifs jusqu’au <1>{graceDate}</1>. Mettez à jour votre mode de paiement avant cette date pour conserver votre abonnement."
#. Video settings note shown when the saved screen share quality is above what this account can send. Resolutions are short labels such as 1440p or Source and rates are whole numbers. FPS is a technical token.
#: src/features/user/components/modals/tabs/UserVideoTab.tsx:92
msgid "Your saved {savedResolution} at {savedFrameRate} FPS needs {premiumProductName}, so shares use {resolution} at {frameRate} FPS."
@@ -40252,7 +40257,7 @@ msgstr "Votre diffusion est toujours en direct"
msgid "Your subscription can't move to the new price right now."
msgstr "Votre abonnement ne peut pas passer au nouveau tarif pour le moment."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:470
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:486
msgid "Your subscription ended but <0/> stay active until <1>{graceDate}</1>. Resubscribe before then to keep your subscriber history."
msgstr "Votre abonnement a pris fin, mais les <0/> restent actifs jusqu’au <1>{graceDate}</1>. Réabonnez-vous avant cette date pour conserver votre historique d’abonné."
@@ -40281,7 +40286,7 @@ msgstr "Votre abonnement est maintenant facturé mensuellement."
msgid "Your subscription has been switched to yearly billing."
msgstr "Votre abonnement est passé en facturation annuelle."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:512
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:528
msgid "Your subscription is active but perks are temporarily paused."
msgstr "Votre abonnement est actif, mais les avantages sont temporairement suspendus."
@@ -40301,7 +40306,7 @@ msgid "Your subscription moves to the new price on {effectiveDate}."
msgstr "Votre abonnement passera au nouveau tarif le {effectiveDate}."
#. Plutonium subscription card line shown to a subscriber on a legacy price whose subscription is already set to cancel. {cancelDate} is a date and {listPriceNewLabel} is a currency amount, both already formatted and localized by code; never write a date or an amount into the translation.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:666
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:682
msgid "Your subscription still ends on <0>{cancelDate}</0>. The current price is now {listPriceNewLabel}. If you reactivate, you can switch to it from here."
msgstr "Votre abonnement prendra toujours fin le <0>{cancelDate}</0>. Le tarif actuel est désormais de {listPriceNewLabel}. Si vous réactivez votre abonnement, vous pourrez passer à ce tarif ici."
@@ -2471,7 +2471,7 @@ msgid "A Linux desktop update is available. Choose the package format for this s
msgstr "זמין עדכון לאפליקציית שולחן העבודה ללינוקס. בחר את פורמט החבילה עבור המערכת הזו, ו-{productName} ישמור אותו באופן מקומי."
#. Plutonium subscription card line offering a move to a lower price. {listPriceEffectiveDate} is a date already formatted and localized by code; never write a date into the translation.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:684
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:700
msgid "A lower price is available. Switching takes effect on <0>{listPriceEffectiveDate}</0> and changes nothing else."
msgstr "מחיר נמוך יותר זמין. המעבר ייכנס לתוקף ב-<0>{listPriceEffectiveDate}</0> ולא ישנה דבר אחר."
@@ -3487,19 +3487,19 @@ msgstr "פקדי יישור זמינים רק במסכים רחבים יותר"
msgid "All"
msgstr "הכל"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:524
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:540
msgid "All <0/> for <1>{effectiveMonthlyPrice}/month</1>."
msgstr "כל <0/> תמורת <1>{effectiveMonthlyPrice} לחודש</1>."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:546
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:562
msgid "All <0/> for <1>{effectiveYearlyPrice}/year</1>."
msgstr "כל <0/> תמורת <1>{effectiveYearlyPrice} לשנה</1>."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:567
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:583
msgid "All <0/> included with your subscription."
msgstr "כל <0/> כלולות במנוי שלך."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:514
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:530
msgid "All <0/>, forever. No billing, no renewals."
msgstr "כל <0/>, לנצח. בלי חיובים, בלי חידושים."
@@ -6469,7 +6469,7 @@ msgid "Cancel import"
msgstr "ביטול ייבוא"
#. Billing button that cancels a scheduled move to a lower subscription price.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:821
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:837
msgid "Cancel price change"
msgstr "ביטול שינוי המחיר"
@@ -6484,14 +6484,14 @@ msgid "Cancel request"
msgstr "ביטול הבקשה"
#. Billing button that cancels a scheduled billing-cycle change.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:829
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:845
msgid "Cancel scheduled switch"
msgstr "ביטול המעבר המתוזמן"
#. Billing button that starts subscription cancellation.
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:844
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:142
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:860
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:141
#: src/features/user/components/settings_utils/search_index/PlutoniumIndex.ts:31
msgid "Cancel subscription"
msgstr "ביטול מינוי"
@@ -6501,7 +6501,7 @@ msgid "Cancel subscription?"
msgstr "לבטל את המינוי?"
#. Plutonium subscription card hint shown to a subscriber who could move to a lower price but has another billing change already scheduled.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:647
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:663
msgid "Cancel the scheduled change to move to the current price instead."
msgstr "בטל את השינוי המתוזמן כדי לעבור למחיר הנוכחי במקום זאת."
@@ -6511,7 +6511,7 @@ msgid "Cancel upload"
msgstr "ביטול העלאה"
#. Billing button that cancels a scheduled yearly upgrade.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:825
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:841
msgid "Cancel yearly upgrade"
msgstr "ביטול שדרוג שנתי"
@@ -6530,7 +6530,7 @@ msgstr "בתהליך ביטול"
msgid "Cancellation"
msgstr "ביטול הד"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:501
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:517
msgid "Cancels on <0>{cancelDate}</0>. <1/> remain active until then."
msgstr "הביטול ייכנס לתוקף ב-<0>{cancelDate}</0>. <1/> יישארו פעילות עד אז."
@@ -10872,7 +10872,7 @@ msgstr "מותאם אישית…"
#. Billing button that opens the external customer portal.
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:750
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:766
#: src/features/user/components/settings_utils/search_index/PlutoniumIndex.ts:39
msgid "Customer portal"
msgstr "פורטל לקוחות"
@@ -13877,15 +13877,15 @@ msgid "End date"
msgstr "תאריך סיום"
#. Billing button that ends premium grace period immediately.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:856
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:872
msgid "End grace now"
msgstr "סיים את תקופת החסד עכשיו"
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:164
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:163
msgid "End grace period"
msgstr "סיום תקופת החסד"
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:157
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:156
msgid "End grace period now?"
msgstr "לסיים את תקופת החסד עכשיו?"
@@ -16347,7 +16347,7 @@ msgstr "מתנה: יפוג בקרוב"
msgid "Gift: grace period (still have access)"
msgstr "מתנה: תקופת חסד (עדיין יש גישה)"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:486
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:502
msgid "Gifted <0/> until <1>{giftEndDate}</1>. Does not renew automatically. Redeem more gift codes to extend."
msgstr "ניתן במתנה <0/> עד <1>{giftEndDate}</1>. לא מתחדש באופן אוטומטי. ניתן לממש קודי מתנה נוספים כדי להאריך."
@@ -16826,7 +16826,7 @@ msgid "Hate speech"
msgstr "דברי שטנה"
#. Premium page text shown on an instance where the premium tier cannot be bought, only redeemed. {PREMIUM_PRODUCT_NAME} is the premium tier name.
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:297
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:296
msgid "Have a gift code? Redeem it to unlock {PREMIUM_PRODUCT_NAME}."
msgstr "יש לך קוד מתנה? הפק אותו כדי לפתוח את {PREMIUM_PRODUCT_NAME}."
@@ -18926,7 +18926,7 @@ msgstr "שמור קבצים מצורפים בעת ניקוי עריכה"
msgid "Keep free and premium tiers. You can customize the tiers, sell premium through Stripe, or hand out gift codes later from the admin panel."
msgstr "שמרו על רמות חינמיות ופרימיום. תוכלו להתאים אישית את הרמות, למכור פרימיום דרך Stripe, או לחלק קודי מתנה מאוחר יותר מלוח הבקרה של המנהל."
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:166
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:165
msgid "Keep grace period"
msgstr "השארת תקופת החסד"
@@ -18940,7 +18940,7 @@ msgstr "השאר את ניקו במקום"
msgid "Keep running"
msgstr "המשך לפעול"
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:144
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:143
msgid "Keep subscription"
msgstr "השארת המנוי"
@@ -19297,8 +19297,8 @@ msgstr "לחצן העכבר השמאלי"
msgid "Left tooltip"
msgstr "תיאור כלי שמאלי"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:539
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:561
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:555
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:577
msgid "Legacy rate"
msgstr "תעריף קודם"
@@ -21339,11 +21339,11 @@ msgstr "חודשי"
msgid "Monthly {monthlyPrice}"
msgstr "חודשי {monthlyPrice}"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:631
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:647
msgid "Monthly billing starts on <0>{pendingChangeDate}</0>."
msgstr "החיוב החודשי יתחיל ב-<0>{pendingChangeDate}</0>."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:624
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:640
msgid "Monthly billing starts on <0>{pendingChangeDate}</0>. First monthly charge: {pendingInitialPriceLabel}. Future monthly renewals: {pendingRecurringPriceLabel}/month."
msgstr "החיוב החודשי יתחיל ב-<0>{pendingChangeDate}</0>. חיוב חודשי ראשון: {pendingInitialPriceLabel}. חידושים חודשיים עתידיים: {pendingRecurringPriceLabel} לחודש."
@@ -22269,12 +22269,12 @@ msgid "New password"
msgstr "סיסמה חדשה"
#. Plutonium subscription card line shown when a move to a lower price is scheduled but the new amount is unknown. {pendingChangeDate} is a date already formatted and localized by code; never write a date into the translation.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:595
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:611
msgid "New price scheduled for <0>{pendingChangeDate}</0>."
msgstr "מחיר חדש מתוכנן ל-<0>{pendingChangeDate}</0>."
#. Plutonium subscription card line shown when a move to a lower price is scheduled. {pendingChangeDate} is a date and {pendingTargetPriceLabel} is a currency amount, both already formatted and localized by code; never write a date or an amount into the translation.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:589
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:605
msgid "New price scheduled for <0>{pendingChangeDate}</0>. Renewals will be {pendingTargetPriceLabel} from then on."
msgstr "מחיר חדש מתוכנן ל-<0>{pendingChangeDate}</0>. מאותו מועד ואילך החידושים יהיו {pendingTargetPriceLabel}."
@@ -26152,7 +26152,7 @@ msgstr "ריאקציות"
#. Billing button that cancels a scheduled subscription cancellation.
#. Button label on the premium-expired nagbar. Opens billing so the user can reactivate their subscription.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:746
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:762
#: src/features/app/components/layout/app_layout/nagbars/PremiumExpiredNagbar.tsx:25
msgid "Reactivate"
msgstr "הפעל מחדש"
@@ -26375,8 +26375,8 @@ msgstr "ממש לעצמך"
#. Billing button for entering a premium gift code.
#. Billing button for entering a premium gift code.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:719
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:307
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:735
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:306
msgid "Redeem gift code"
msgstr "מימוש קוד מתנה"
@@ -27147,7 +27147,7 @@ msgstr "סף חידוש (ימים)"
msgid "Renew window (days)"
msgstr "חלון חידוש (ימים)"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:701
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:717
msgid "Renews on <0>{renewalDate}.</0>"
msgstr "מתחדש ב-<0>{renewalDate}.</0>"
@@ -27896,8 +27896,8 @@ msgstr "שחזור חלון"
#. Billing button for restarting a subscription during the grace period.
#. Billing button for starting a new subscription after premium expired.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:738
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:742
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:754
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:758
msgid "Resubscribe"
msgstr "חדש את המנוי"
@@ -32521,7 +32521,7 @@ msgid "Switch price"
msgstr "החלף מחיר"
#. Billing button that opens confirmation to move the subscription down to the current price. {listPriceNewLabel} is the localized new price.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:806
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:822
msgid "Switch to {listPriceNewLabel}"
msgstr "עבור אל {listPriceNewLabel}"
@@ -32546,7 +32546,7 @@ msgstr "החלף לקלט ישיר"
#. Billing button that opens confirmation to switch to monthly billing.
#. Button confirming a change to monthly subscription billing.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:57
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:789
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:805
msgid "Switch to monthly"
msgstr "עבור למנוי חודשי"
@@ -32615,7 +32615,7 @@ msgstr "החלף לשתי עמודות"
#. Billing button that opens confirmation to switch to yearly billing.
#. Button confirming a change to yearly subscription billing.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:53
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:785
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:801
msgid "Switch to yearly"
msgstr "עבור למנוי שנתי"
@@ -35865,7 +35865,7 @@ msgstr "קבל גישה לאימוג'ים מותאמים אישית בהודעו
msgid "Unlock HD screen share with {premiumProductName}"
msgstr "קבל גישה לשיתוף מסך באיכות HD עם {premiumProductName}"
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:217
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:216
msgid "Unlock higher limits and exclusive features while supporting an independent communication platform."
msgstr "קבל גישה למגבלות גבוהות יותר ולתכונות בלעדיות, ותמוך בפלטפורמת תקשורת עצמאית."
@@ -39015,15 +39015,15 @@ msgstr "שנתי {yearlyPrice}"
msgid "Yearly gift"
msgstr "מתנה שנתית"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:618
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:634
msgid "Yearly upgrade scheduled for <0>{pendingChangeDate}</0>."
msgstr "שדרוג שנתי מתוזמן ל-<0>{pendingChangeDate}</0>."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:603
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:619
msgid "Yearly upgrade scheduled for <0>{pendingChangeDate}</0>. First yearly charge: {pendingInitialPriceLabel} after a {pendingCreditPriceLabel} credit. Future yearly renewals: {pendingRecurringPriceLabel}/year."
msgstr "שדרוג שנתי מתוכנן ל-<0>{pendingChangeDate}</0>. חיוב שנתי ראשון: {pendingInitialPriceLabel} לאחר זיכוי של {pendingCreditPriceLabel}. חידושים שנתיים עתידיים: {pendingRecurringPriceLabel} לשנה."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:610
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:626
msgid "Yearly upgrade scheduled for <0>{pendingChangeDate}</0>. First yearly charge: {pendingInitialPriceLabel}. Future yearly renewals: {pendingRecurringPriceLabel}/year."
msgstr "שדרוג שנתי מתוכנן ל-<0>{pendingChangeDate}</0>. חיוב שנתי ראשון: {pendingInitialPriceLabel}. חידושים שנתיים עתידיים: {pendingRecurringPriceLabel} לשנה."
@@ -39493,10 +39493,10 @@ msgid "You just pressed Tab. Keyboard mode is now on so you can navigate {produc
msgstr "לחצת על Tab. מצב מקלדת מופעל כעת, כך שתוכל לנווט ב-{productName} ללא עכבר."
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:137
msgid "You keep your perks until your next renewal date, then have a 3-day grace period to resubscribe and keep your subscriber history."
msgstr "ההטבות שלך יישמרו עד לתאריך החידוש הבא שלך, ולאחר מכן תהיה לך תקופת חסד של 3 ימים כדי להירשם מחדש ולשמור את היסטוריית המנוי שלך."
msgid "You keep your perks until your next renewal date. Reactivate before then to keep your subscriber history."
msgstr "ההטבות שלך יישמרו עד לתאריך החידוש הבא שלך. יש להפעיל מחדש את המנוי לפני כן כדי לשמור את היסטוריית המנוי שלך."
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:159
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:158
msgid "You lose all {PREMIUM_PRODUCT_NAME} perks immediately and your subscriber history resets. This cannot be undone."
msgstr "תאבד את כל ההטבות של {PREMIUM_PRODUCT_NAME} באופן מיידי והיסטוריית המנוי שלך תתאפס. לא ניתן לבטל פעולה זו."
@@ -40231,6 +40231,11 @@ msgstr "האזור שלך"
msgid "Your registration needs an extra anti-spam check before you can continue."
msgstr "ההרשמה שלך דורשת בדיקה נוספת למניעת ספאם לפני שתוכל להמשיך."
#. Plutonium subscription card text shown while a failed renewal payment is being retried. {graceDate} is a date already formatted and localized by code; never write a date into the translation.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:470
msgid "Your renewal payment failed but <0/> stay active until <1>{graceDate}</1>. Update your payment method before then to keep your subscription."
msgstr "תשלום החידוש נכשל, אבל <0/> יישארו פעילות עד <1>{graceDate}</1>. עדכן את אמצעי התשלום לפני כן כדי לשמור על המנוי שלך."
#. Video settings note shown when the saved screen share quality is above what this account can send. Resolutions are short labels such as 1440p or Source and rates are whole numbers. FPS is a technical token.
#: src/features/user/components/modals/tabs/UserVideoTab.tsx:92
msgid "Your saved {savedResolution} at {savedFrameRate} FPS needs {premiumProductName}, so shares use {resolution} at {frameRate} FPS."
@@ -40252,7 +40257,7 @@ msgstr "השידור שלך עדיין פעיל"
msgid "Your subscription can't move to the new price right now."
msgstr "המנוי שלך לא יכול לעבור למחיר החדש כרגע."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:470
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:486
msgid "Your subscription ended but <0/> stay active until <1>{graceDate}</1>. Resubscribe before then to keep your subscriber history."
msgstr "המנוי שלך הסתיים, אבל <0/> יישארו פעילות עד <1>{graceDate}</1>. הירשם מחדש לפני כן כדי לשמור את היסטוריית המנויים שלך."
@@ -40281,7 +40286,7 @@ msgstr "המנוי שלך הועבר לחיוב חודשי."
msgid "Your subscription has been switched to yearly billing."
msgstr "המנוי שלך הועבר לחיוב שנתי."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:512
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:528
msgid "Your subscription is active but perks are temporarily paused."
msgstr "המנוי שלך פעיל, אך ההטבות מושהות באופן זמני."
@@ -40301,7 +40306,7 @@ msgid "Your subscription moves to the new price on {effectiveDate}."
msgstr "המנוי שלך יעבור למחיר החדש בתאריך {effectiveDate}."
#. Plutonium subscription card line shown to a subscriber on a legacy price whose subscription is already set to cancel. {cancelDate} is a date and {listPriceNewLabel} is a currency amount, both already formatted and localized by code; never write a date or an amount into the translation.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:666
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:682
msgid "Your subscription still ends on <0>{cancelDate}</0>. The current price is now {listPriceNewLabel}. If you reactivate, you can switch to it from here."
msgstr "המנוי שלך עדיין יסתיים בתאריך <0>{cancelDate}</0>. המחיר הנוכחי הוא כעת {listPriceNewLabel}. אם תפעיל מחדש, תוכל לעבור אליו מכאן."
@@ -2471,7 +2471,7 @@ msgid "A Linux desktop update is available. Choose the package format for this s
msgstr "लिनक्स डेस्कटॉप के लिए एक अपडेट उपलब्ध है। इस सिस्टम के लिए पैकेज फ़ॉर्मैट चुनें और {productName} उसे आपके डिवाइस पर सेव कर लेगा।"
#. Plutonium subscription card line offering a move to a lower price. {listPriceEffectiveDate} is a date already formatted and localized by code; never write a date into the translation.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:684
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:700
msgid "A lower price is available. Switching takes effect on <0>{listPriceEffectiveDate}</0> and changes nothing else."
msgstr "कम कीमत उपलब्ध है। स्विच <0>{listPriceEffectiveDate}</0> से लागू होगा और इससे कुछ और नहीं बदलेगा।"
@@ -3487,19 +3487,19 @@ msgstr "अलाइनमेंट कंट्रोल केवल चौड
msgid "All"
msgstr "सभी"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:524
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:540
msgid "All <0/> for <1>{effectiveMonthlyPrice}/month</1>."
msgstr "सभी <0/> <1>{effectiveMonthlyPrice}/माह</1> में।"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:546
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:562
msgid "All <0/> for <1>{effectiveYearlyPrice}/year</1>."
msgstr "सभी <0/> <1>{effectiveYearlyPrice}/साल</1> में।"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:567
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:583
msgid "All <0/> included with your subscription."
msgstr "आपकी सदस्यता के साथ सभी <0/> शामिल हैं।"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:514
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:530
msgid "All <0/>, forever. No billing, no renewals."
msgstr "सभी <0/>, हमेशा के लिए। कोई बिलिंग नहीं, कोई नवीनीकरण नहीं।"
@@ -6469,7 +6469,7 @@ msgid "Cancel import"
msgstr "इंपोर्ट रद्द करें"
#. Billing button that cancels a scheduled move to a lower subscription price.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:821
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:837
msgid "Cancel price change"
msgstr "कीमत बदलना रद्द करें"
@@ -6484,14 +6484,14 @@ msgid "Cancel request"
msgstr "अनुरोध रद्द करें"
#. Billing button that cancels a scheduled billing-cycle change.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:829
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:845
msgid "Cancel scheduled switch"
msgstr "निर्धारित स्विच रद्द करें"
#. Billing button that starts subscription cancellation.
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:844
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:142
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:860
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:141
#: src/features/user/components/settings_utils/search_index/PlutoniumIndex.ts:31
msgid "Cancel subscription"
msgstr "सदस्यता रद्द करें"
@@ -6501,7 +6501,7 @@ msgid "Cancel subscription?"
msgstr "सदस्यता रद्द करें?"
#. Plutonium subscription card hint shown to a subscriber who could move to a lower price but has another billing change already scheduled.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:647
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:663
msgid "Cancel the scheduled change to move to the current price instead."
msgstr "निर्धारित बदलाव को रद्द करें और इसके बजाय वर्तमान मूल्य पर जाएँ।"
@@ -6511,7 +6511,7 @@ msgid "Cancel upload"
msgstr "अपलोड रद्द करें"
#. Billing button that cancels a scheduled yearly upgrade.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:825
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:841
msgid "Cancel yearly upgrade"
msgstr "सालाना अपग्रेड रद्द करें"
@@ -6530,7 +6530,7 @@ msgstr "रद्द किया जा रहा है"
msgid "Cancellation"
msgstr "इको कैंसलेशन"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:501
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:517
msgid "Cancels on <0>{cancelDate}</0>. <1/> remain active until then."
msgstr "<0>{cancelDate}</0> को रद्द हो जाएगा। <1/> तब तक सक्रिय रहेंगे।"
@@ -10872,7 +10872,7 @@ msgstr "कस्टम…"
#. Billing button that opens the external customer portal.
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:750
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:766
#: src/features/user/components/settings_utils/search_index/PlutoniumIndex.ts:39
msgid "Customer portal"
msgstr "ग्राहक पोर्टल"
@@ -13877,15 +13877,15 @@ msgid "End date"
msgstr "अंतिम तिथि"
#. Billing button that ends premium grace period immediately.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:856
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:872
msgid "End grace now"
msgstr "ग्रेस पीरियड अभी खत्म करें"
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:164
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:163
msgid "End grace period"
msgstr "ग्रेस पीरियड खत्म करें"
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:157
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:156
msgid "End grace period now?"
msgstr "ग्रेस पीरियड अभी खत्म करें?"
@@ -16347,7 +16347,7 @@ msgstr "उपहार: जल्द समाप्त होगा"
msgid "Gift: grace period (still have access)"
msgstr "उपहार: ग्रेस पीरियड (अभी भी एक्सेस है)"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:486
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:502
msgid "Gifted <0/> until <1>{giftEndDate}</1>. Does not renew automatically. Redeem more gift codes to extend."
msgstr "<1>{giftEndDate}</1> तक <0/> उपहार में मिला है। अपने आप रिन्यू नहीं होगा। अवधि बढ़ाने के लिए और उपहार कोड रिडीम करें।"
@@ -16826,7 +16826,7 @@ msgid "Hate speech"
msgstr "नफ़रत फैलाने वाला भाषण"
#. Premium page text shown on an instance where the premium tier cannot be bought, only redeemed. {PREMIUM_PRODUCT_NAME} is the premium tier name.
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:297
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:296
msgid "Have a gift code? Redeem it to unlock {PREMIUM_PRODUCT_NAME}."
msgstr "गिफ्ट कोड है? {PREMIUM_PRODUCT_NAME} को अनलॉक करने के लिए इसे रिडीम करें।"
@@ -18926,7 +18926,7 @@ msgstr "एडिट साफ़ करते समय अटैचमें
msgid "Keep free and premium tiers. You can customize the tiers, sell premium through Stripe, or hand out gift codes later from the admin panel."
msgstr "मुफ़्त और प्रीमियम टियर रखें। आप टियर को कस्टमाइज़ कर सकते हैं, स्ट्राइप के ज़रिए प्रीमियम बेच सकते हैं, या बाद में एडमिन पैनल से गिफ्ट कोड दे सकते हैं।"
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:166
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:165
msgid "Keep grace period"
msgstr "ग्रेस पीरियड रखें"
@@ -18940,7 +18940,7 @@ msgstr "नेको को स्थिर रखें"
msgid "Keep running"
msgstr "चालू रखें"
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:144
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:143
msgid "Keep subscription"
msgstr "सदस्यता रखें"
@@ -19297,8 +19297,8 @@ msgstr "माउस का बायाँ बटन"
msgid "Left tooltip"
msgstr "बायां टूलटिप"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:539
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:561
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:555
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:577
msgid "Legacy rate"
msgstr "पुरानी दर"
@@ -21339,11 +21339,11 @@ msgstr "मासिक"
msgid "Monthly {monthlyPrice}"
msgstr "मासिक {monthlyPrice}"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:631
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:647
msgid "Monthly billing starts on <0>{pendingChangeDate}</0>."
msgstr "<0>{pendingChangeDate}</0> से मासिक बिलिंग शुरू होगी।"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:624
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:640
msgid "Monthly billing starts on <0>{pendingChangeDate}</0>. First monthly charge: {pendingInitialPriceLabel}. Future monthly renewals: {pendingRecurringPriceLabel}/month."
msgstr "<0>{pendingChangeDate}</0> से मासिक बिलिंग शुरू होगी। पहला मासिक शुल्क: {pendingInitialPriceLabel}। भविष्य के मासिक नवीनीकरण: {pendingRecurringPriceLabel}/माह।"
@@ -22269,12 +22269,12 @@ msgid "New password"
msgstr "नया पासवर्ड"
#. Plutonium subscription card line shown when a move to a lower price is scheduled but the new amount is unknown. {pendingChangeDate} is a date already formatted and localized by code; never write a date into the translation.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:595
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:611
msgid "New price scheduled for <0>{pendingChangeDate}</0>."
msgstr "नई कीमत <0>{pendingChangeDate}</0> के लिए शेड्यूल की गई है।"
#. Plutonium subscription card line shown when a move to a lower price is scheduled. {pendingChangeDate} is a date and {pendingTargetPriceLabel} is a currency amount, both already formatted and localized by code; never write a date or an amount into the translation.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:589
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:605
msgid "New price scheduled for <0>{pendingChangeDate}</0>. Renewals will be {pendingTargetPriceLabel} from then on."
msgstr "नई कीमत <0>{pendingChangeDate}</0> के लिए शेड्यूल की गई है। उसके बाद हर नवीनीकरण {pendingTargetPriceLabel} का होगा।"
@@ -26152,7 +26152,7 @@ msgstr "रिएक्शन"
#. Billing button that cancels a scheduled subscription cancellation.
#. Button label on the premium-expired nagbar. Opens billing so the user can reactivate their subscription.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:746
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:762
#: src/features/app/components/layout/app_layout/nagbars/PremiumExpiredNagbar.tsx:25
msgid "Reactivate"
msgstr "फिर से सक्रिय करें"
@@ -26375,8 +26375,8 @@ msgstr "अपने लिए रिडीम करें"
#. Billing button for entering a premium gift code.
#. Billing button for entering a premium gift code.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:719
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:307
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:735
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:306
msgid "Redeem gift code"
msgstr "उपहार कोड रिडीम करें"
@@ -27147,7 +27147,7 @@ msgstr "नवीनीकरण सीमा (दिन)"
msgid "Renew window (days)"
msgstr "नवीनीकरण विंडो (दिन)"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:701
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:717
msgid "Renews on <0>{renewalDate}.</0>"
msgstr "<0>{renewalDate}</0> को रिन्यू होगा।"
@@ -27896,8 +27896,8 @@ msgstr "विंडो को पहले जैसा करें"
#. Billing button for restarting a subscription during the grace period.
#. Billing button for starting a new subscription after premium expired.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:738
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:742
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:754
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:758
msgid "Resubscribe"
msgstr "फिर से सदस्यता लें"
@@ -32521,7 +32521,7 @@ msgid "Switch price"
msgstr "कीमत बदलें"
#. Billing button that opens confirmation to move the subscription down to the current price. {listPriceNewLabel} is the localized new price.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:806
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:822
msgid "Switch to {listPriceNewLabel}"
msgstr "{listPriceNewLabel} पर स्विच करें"
@@ -32546,7 +32546,7 @@ msgstr "सीधे इनपुट पर स्विच करें"
#. Billing button that opens confirmation to switch to monthly billing.
#. Button confirming a change to monthly subscription billing.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:57
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:789
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:805
msgid "Switch to monthly"
msgstr "मासिक पर स्विच करें"
@@ -32615,7 +32615,7 @@ msgstr "दो कॉलम पर स्विच करें"
#. Billing button that opens confirmation to switch to yearly billing.
#. Button confirming a change to yearly subscription billing.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:53
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:785
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:801
msgid "Switch to yearly"
msgstr "सालाना पर स्विच करें"
@@ -35865,7 +35865,7 @@ msgstr "{premiumProductName} के साथ DM में कस्टम इ
msgid "Unlock HD screen share with {premiumProductName}"
msgstr "{premiumProductName} के साथ HD स्क्रीन शेयर अनलॉक करें"
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:217
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:216
msgid "Unlock higher limits and exclusive features while supporting an independent communication platform."
msgstr "एक स्वतंत्र संचार प्लेटफ़ॉर्म को सपोर्ट करते हुए ज़्यादा बड़ी सीमाएँ और खास सुविधाएँ अनलॉक करें।"
@@ -39015,15 +39015,15 @@ msgstr "सालाना {yearlyPrice}"
msgid "Yearly gift"
msgstr "सालाना उपहार"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:618
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:634
msgid "Yearly upgrade scheduled for <0>{pendingChangeDate}</0>."
msgstr "<0>{pendingChangeDate}</0> के लिए सालाना अपग्रेड शेड्यूल किया गया है।"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:603
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:619
msgid "Yearly upgrade scheduled for <0>{pendingChangeDate}</0>. First yearly charge: {pendingInitialPriceLabel} after a {pendingCreditPriceLabel} credit. Future yearly renewals: {pendingRecurringPriceLabel}/year."
msgstr "<0>{pendingChangeDate}</0> के लिए सालाना अपग्रेड शेड्यूल किया गया है। पहला सालाना शुल्क: {pendingCreditPriceLabel} क्रेडिट के बाद {pendingInitialPriceLabel}। आगे के सालाना रिन्यूअल: {pendingRecurringPriceLabel}/वर्ष।"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:610
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:626
msgid "Yearly upgrade scheduled for <0>{pendingChangeDate}</0>. First yearly charge: {pendingInitialPriceLabel}. Future yearly renewals: {pendingRecurringPriceLabel}/year."
msgstr "<0>{pendingChangeDate}</0> के लिए सालाना अपग्रेड शेड्यूल किया गया है। पहला सालाना शुल्क: {pendingInitialPriceLabel}। आगे के सालाना रिन्यूअल: {pendingRecurringPriceLabel}/वर्ष।"
@@ -39493,10 +39493,10 @@ msgid "You just pressed Tab. Keyboard mode is now on so you can navigate {produc
msgstr "आपने अभी Tab दबाया है। कीबोर्ड मोड अब चालू है, ताकि आप माउस के बिना {productName} को नेविगेट कर सकें।"
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:137
msgid "You keep your perks until your next renewal date, then have a 3-day grace period to resubscribe and keep your subscriber history."
msgstr "आपके पर्क आपकी अगली रिन्यूअल तारीख तक बने रहेंगे, फिर दोबारा सदस्यता लेने और अपनी सब्सक्राइबर हिस्ट्री बनाए रखने के लिए 3 दिन का ग्रेस पीरियड मिलेगा।"
msgid "You keep your perks until your next renewal date. Reactivate before then to keep your subscriber history."
msgstr "आपके पर्क आपकी अगली रिन्यूअल तारीख तक बने रहेंगे। अपनी सब्सक्राइबर हिस्ट्री बनाए रखने के लिए उससे पहले सदस्यता फिर से सक्रिय करें।"
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:159
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:158
msgid "You lose all {PREMIUM_PRODUCT_NAME} perks immediately and your subscriber history resets. This cannot be undone."
msgstr "आप तुरंत सभी {PREMIUM_PRODUCT_NAME} पर्क खो देंगे और आपकी सब्सक्राइबर हिस्ट्री रीसेट हो जाएगी। इसे पूर्ववत नहीं किया जा सकता।"
@@ -40231,6 +40231,11 @@ msgstr "आपका क्षेत्र"
msgid "Your registration needs an extra anti-spam check before you can continue."
msgstr "जारी रखने से पहले आपके रजिस्ट्रेशन के लिए एक अतिरिक्त एंटी-स्पैम जाँच की ज़रूरत है।"
#. Plutonium subscription card text shown while a failed renewal payment is being retried. {graceDate} is a date already formatted and localized by code; never write a date into the translation.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:470
msgid "Your renewal payment failed but <0/> stay active until <1>{graceDate}</1>. Update your payment method before then to keep your subscription."
msgstr "आपका नवीनीकरण भुगतान विफल हो गया, लेकिन <0/> <1>{graceDate}</1> तक सक्रिय रहेगी। अपनी सदस्यता बनाए रखने के लिए इससे पहले अपना भुगतान का तरीका अपडेट करें।"
#. Video settings note shown when the saved screen share quality is above what this account can send. Resolutions are short labels such as 1440p or Source and rates are whole numbers. FPS is a technical token.
#: src/features/user/components/modals/tabs/UserVideoTab.tsx:92
msgid "Your saved {savedResolution} at {savedFrameRate} FPS needs {premiumProductName}, so shares use {resolution} at {frameRate} FPS."
@@ -40252,7 +40257,7 @@ msgstr "आपकी स्ट्रीम अभी भी लाइव है"
msgid "Your subscription can't move to the new price right now."
msgstr "आपकी सदस्यता अभी नई कीमत पर नहीं जा सकती।"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:470
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:486
msgid "Your subscription ended but <0/> stay active until <1>{graceDate}</1>. Resubscribe before then to keep your subscriber history."
msgstr "आपकी सदस्यता समाप्त हो गई है, लेकिन <0/> <1>{graceDate}</1> तक सक्रिय रहेगी। अपनी सब्सक्राइबर हिस्ट्री बनाए रखने के लिए इससे पहले फिर से सदस्यता लें।"
@@ -40281,7 +40286,7 @@ msgstr "आपकी सदस्यता मासिक बिलिंग
msgid "Your subscription has been switched to yearly billing."
msgstr "आपकी सदस्यता सालाना बिलिंग पर स्विच कर दी गई है।"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:512
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:528
msgid "Your subscription is active but perks are temporarily paused."
msgstr "आपकी सदस्यता सक्रिय है, लेकिन पर्क कुछ समय के लिए रोक दिए गए हैं।"
@@ -40301,7 +40306,7 @@ msgid "Your subscription moves to the new price on {effectiveDate}."
msgstr "आपकी सदस्यता {effectiveDate} को नई कीमत पर चली जाएगी।"
#. Plutonium subscription card line shown to a subscriber on a legacy price whose subscription is already set to cancel. {cancelDate} is a date and {listPriceNewLabel} is a currency amount, both already formatted and localized by code; never write a date or an amount into the translation.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:666
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:682
msgid "Your subscription still ends on <0>{cancelDate}</0>. The current price is now {listPriceNewLabel}. If you reactivate, you can switch to it from here."
msgstr "आपकी सदस्यता अब भी <0>{cancelDate}</0> को खत्म होगी। मौजूदा कीमत अब {listPriceNewLabel} है। अगर आप इसे फिर से सक्रिय करते हैं, तो यहीं से उस पर स्विच कर सकते हैं।"
@@ -2471,7 +2471,7 @@ msgid "A Linux desktop update is available. Choose the package format for this s
msgstr "Dostupno je ažuriranje aplikacije za Linux. Odaberite format paketa za ovaj sustav i {productName} će ga spremiti lokalno."
#. Plutonium subscription card line offering a move to a lower price. {listPriceEffectiveDate} is a date already formatted and localized by code; never write a date into the translation.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:684
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:700
msgid "A lower price is available. Switching takes effect on <0>{listPriceEffectiveDate}</0> and changes nothing else."
msgstr "Dostupna je niža cijena. Prebacivanje stupa na snagu <0>{listPriceEffectiveDate}</0> i ništa se drugo ne mijenja."
@@ -3487,19 +3487,19 @@ msgstr "Kontrole poravnanja dostupne su samo na širim zaslonima"
msgid "All"
msgstr "Sve"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:524
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:540
msgid "All <0/> for <1>{effectiveMonthlyPrice}/month</1>."
msgstr "Sve <0/> za <1>{effectiveMonthlyPrice}/mjesec</1>."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:546
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:562
msgid "All <0/> for <1>{effectiveYearlyPrice}/year</1>."
msgstr "Sve <0/> za <1>{effectiveYearlyPrice}/godina</1>."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:567
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:583
msgid "All <0/> included with your subscription."
msgstr "Sve <0/> uključene su u vašu pretplatu."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:514
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:530
msgid "All <0/>, forever. No billing, no renewals."
msgstr "Sve <0/>, zauvijek. Bez naplate, bez obnova."
@@ -6469,7 +6469,7 @@ msgid "Cancel import"
msgstr "Odustani od uvoza"
#. Billing button that cancels a scheduled move to a lower subscription price.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:821
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:837
msgid "Cancel price change"
msgstr "Otkaži promjenu cijene"
@@ -6484,14 +6484,14 @@ msgid "Cancel request"
msgstr "Poništi zahtjev"
#. Billing button that cancels a scheduled billing-cycle change.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:829
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:845
msgid "Cancel scheduled switch"
msgstr "Poništi zakazanu promjenu"
#. Billing button that starts subscription cancellation.
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:844
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:142
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:860
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:141
#: src/features/user/components/settings_utils/search_index/PlutoniumIndex.ts:31
msgid "Cancel subscription"
msgstr "Otkaži pretplatu"
@@ -6501,7 +6501,7 @@ msgid "Cancel subscription?"
msgstr "Otkaži pretplatu?"
#. Plutonium subscription card hint shown to a subscriber who could move to a lower price but has another billing change already scheduled.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:647
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:663
msgid "Cancel the scheduled change to move to the current price instead."
msgstr "Otkažite zakazanu promjenu da biste umjesto toga prešli na trenutnu cijenu."
@@ -6511,7 +6511,7 @@ msgid "Cancel upload"
msgstr "Odustani od prijenosa"
#. Billing button that cancels a scheduled yearly upgrade.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:825
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:841
msgid "Cancel yearly upgrade"
msgstr "Poništi godišnju nadogradnju"
@@ -6530,7 +6530,7 @@ msgstr "Otkazivanje"
msgid "Cancellation"
msgstr "Poništavanje jeke"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:501
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:517
msgid "Cancels on <0>{cancelDate}</0>. <1/> remain active until then."
msgstr "Otkazuje se <0>{cancelDate}</0>. <1/> ostaju aktivne do tada."
@@ -10872,7 +10872,7 @@ msgstr "Prilagođeno…"
#. Billing button that opens the external customer portal.
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:750
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:766
#: src/features/user/components/settings_utils/search_index/PlutoniumIndex.ts:39
msgid "Customer portal"
msgstr "Korisnički portal"
@@ -13877,15 +13877,15 @@ msgid "End date"
msgstr "Datum završetka"
#. Billing button that ends premium grace period immediately.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:856
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:872
msgid "End grace now"
msgstr "Završi poček sada"
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:164
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:163
msgid "End grace period"
msgstr "Završi razdoblje počeka"
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:157
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:156
msgid "End grace period now?"
msgstr "Završiti poček sada?"
@@ -16347,7 +16347,7 @@ msgstr "Poklon: ističe uskoro"
msgid "Gift: grace period (still have access)"
msgstr "Poklon: poček (i dalje imate pristup)"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:486
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:502
msgid "Gifted <0/> until <1>{giftEndDate}</1>. Does not renew automatically. Redeem more gift codes to extend."
msgstr "Poklonjeno <0/> do <1>{giftEndDate}</1>. Ne obnavlja se automatski. Iskoristite više kodova poklona za produljenje."
@@ -16826,7 +16826,7 @@ msgid "Hate speech"
msgstr "Govor mržnje"
#. Premium page text shown on an instance where the premium tier cannot be bought, only redeemed. {PREMIUM_PRODUCT_NAME} is the premium tier name.
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:297
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:296
msgid "Have a gift code? Redeem it to unlock {PREMIUM_PRODUCT_NAME}."
msgstr "Imaš poklon-kod? Iskoristi ga za otključavanje {PREMIUM_PRODUCT_NAME}."
@@ -18926,7 +18926,7 @@ msgstr "Zadrži privitke pri brisanju izmjene"
msgid "Keep free and premium tiers. You can customize the tiers, sell premium through Stripe, or hand out gift codes later from the admin panel."
msgstr "Zadržite besplatnu i premium razinu. Možete prilagoditi razine, prodavati premium putem Stripe-a ili kasnije dijeliti poklon-kodove iz administratorske ploče."
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:166
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:165
msgid "Keep grace period"
msgstr "Zadrži poček"
@@ -18940,7 +18940,7 @@ msgstr "Neka Neko miruje"
msgid "Keep running"
msgstr "Nastavi raditi"
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:144
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:143
msgid "Keep subscription"
msgstr "Zadrži pretplatu"
@@ -19297,8 +19297,8 @@ msgstr "Lijeva tipka miša"
msgid "Left tooltip"
msgstr "Lijevi opis alata"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:539
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:561
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:555
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:577
msgid "Legacy rate"
msgstr "Stara cijena"
@@ -21339,11 +21339,11 @@ msgstr "Mjesečno"
msgid "Monthly {monthlyPrice}"
msgstr "Mjesečno {monthlyPrice}"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:631
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:647
msgid "Monthly billing starts on <0>{pendingChangeDate}</0>."
msgstr "Mjesečna naplata počinje <0>{pendingChangeDate}</0>."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:624
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:640
msgid "Monthly billing starts on <0>{pendingChangeDate}</0>. First monthly charge: {pendingInitialPriceLabel}. Future monthly renewals: {pendingRecurringPriceLabel}/month."
msgstr "Mjesečna naplata počinje <0>{pendingChangeDate}</0>. Prva mjesečna naknada: {pendingInitialPriceLabel}. Buduće mjesečne obnove: {pendingRecurringPriceLabel}/mjesec."
@@ -22269,12 +22269,12 @@ msgid "New password"
msgstr "Nova lozinka"
#. Plutonium subscription card line shown when a move to a lower price is scheduled but the new amount is unknown. {pendingChangeDate} is a date already formatted and localized by code; never write a date into the translation.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:595
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:611
msgid "New price scheduled for <0>{pendingChangeDate}</0>."
msgstr "Nova cijena zakazana za <0>{pendingChangeDate}</0>."
#. Plutonium subscription card line shown when a move to a lower price is scheduled. {pendingChangeDate} is a date and {pendingTargetPriceLabel} is a currency amount, both already formatted and localized by code; never write a date or an amount into the translation.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:589
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:605
msgid "New price scheduled for <0>{pendingChangeDate}</0>. Renewals will be {pendingTargetPriceLabel} from then on."
msgstr "Nova cijena zakazana za <0>{pendingChangeDate}</0>. Obnove će od tada iznositi {pendingTargetPriceLabel}."
@@ -26152,7 +26152,7 @@ msgstr "Reakcije"
#. Billing button that cancels a scheduled subscription cancellation.
#. Button label on the premium-expired nagbar. Opens billing so the user can reactivate their subscription.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:746
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:762
#: src/features/app/components/layout/app_layout/nagbars/PremiumExpiredNagbar.tsx:25
msgid "Reactivate"
msgstr "Ponovno aktiviraj"
@@ -26375,8 +26375,8 @@ msgstr "Iskoristi za sebe"
#. Billing button for entering a premium gift code.
#. Billing button for entering a premium gift code.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:719
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:307
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:735
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:306
msgid "Redeem gift code"
msgstr "Iskoristi kôd poklona"
@@ -27147,7 +27147,7 @@ msgstr "Prag obnove (dani)"
msgid "Renew window (days)"
msgstr "Prozor obnove (dani)"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:701
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:717
msgid "Renews on <0>{renewalDate}.</0>"
msgstr "Obnavlja se <0>{renewalDate}.</0>"
@@ -27896,8 +27896,8 @@ msgstr "Vrati prozor"
#. Billing button for restarting a subscription during the grace period.
#. Billing button for starting a new subscription after premium expired.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:738
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:742
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:754
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:758
msgid "Resubscribe"
msgstr "Ponovno se pretplati"
@@ -32521,7 +32521,7 @@ msgid "Switch price"
msgstr "Promijeni cijenu"
#. Billing button that opens confirmation to move the subscription down to the current price. {listPriceNewLabel} is the localized new price.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:806
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:822
msgid "Switch to {listPriceNewLabel}"
msgstr "Prebaci na {listPriceNewLabel}"
@@ -32546,7 +32546,7 @@ msgstr "Prebaci na izravan unos"
#. Billing button that opens confirmation to switch to monthly billing.
#. Button confirming a change to monthly subscription billing.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:57
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:789
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:805
msgid "Switch to monthly"
msgstr "Prijeđi na mjesečnu pretplatu"
@@ -32615,7 +32615,7 @@ msgstr "Prebaci na dva stupca"
#. Billing button that opens confirmation to switch to yearly billing.
#. Button confirming a change to yearly subscription billing.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:53
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:785
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:801
msgid "Switch to yearly"
msgstr "Prijeđi na godišnju pretplatu"
@@ -35865,7 +35865,7 @@ msgstr "Otključajte prilagođene emojije u izravnim porukama uz {premiumProduct
msgid "Unlock HD screen share with {premiumProductName}"
msgstr "Otključajte HD dijeljenje zaslona uz {premiumProductName}"
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:217
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:216
msgid "Unlock higher limits and exclusive features while supporting an independent communication platform."
msgstr "Otključajte veća ograničenja i ekskluzivne značajke, a istovremeno podržite neovisnu komunikacijsku platformu."
@@ -39015,15 +39015,15 @@ msgstr "Godišnje {yearlyPrice}"
msgid "Yearly gift"
msgstr "Godišnji poklon"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:618
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:634
msgid "Yearly upgrade scheduled for <0>{pendingChangeDate}</0>."
msgstr "Godišnja nadogradnja zakazana za <0>{pendingChangeDate}</0>."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:603
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:619
msgid "Yearly upgrade scheduled for <0>{pendingChangeDate}</0>. First yearly charge: {pendingInitialPriceLabel} after a {pendingCreditPriceLabel} credit. Future yearly renewals: {pendingRecurringPriceLabel}/year."
msgstr "Godišnja nadogradnja zakazana za <0>{pendingChangeDate}</0>. Prva godišnja naplata: {pendingInitialPriceLabel} nakon {pendingCreditPriceLabel} kredita. Buduće godišnje obnove: {pendingRecurringPriceLabel}/godina."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:610
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:626
msgid "Yearly upgrade scheduled for <0>{pendingChangeDate}</0>. First yearly charge: {pendingInitialPriceLabel}. Future yearly renewals: {pendingRecurringPriceLabel}/year."
msgstr "Godišnja nadogradnja zakazana za <0>{pendingChangeDate}</0>. Prva godišnja naplata: {pendingInitialPriceLabel}. Buduće godišnje obnove: {pendingRecurringPriceLabel}/godina."
@@ -39493,10 +39493,10 @@ msgid "You just pressed Tab. Keyboard mode is now on so you can navigate {produc
msgstr "Upravo ste pritisnuli tipku Tab. Način rada tipkovnice sada je uključen, tako da se možete kretati kroz {productName} bez miša."
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:137
msgid "You keep your perks until your next renewal date, then have a 3-day grace period to resubscribe and keep your subscriber history."
msgstr "Zadržavate svoje pogodnosti do sljedećeg datuma obnove, a zatim imate razdoblje od 3 dana za ponovnu pretplatu i zadržavanje povijesti pretplate."
msgid "You keep your perks until your next renewal date. Reactivate before then to keep your subscriber history."
msgstr "Zadržavate svoje pogodnosti do sljedećeg datuma obnove. Ponovno aktivirajte pretplatu prije toga kako biste zadržali povijest pretplate."
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:159
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:158
msgid "You lose all {PREMIUM_PRODUCT_NAME} perks immediately and your subscriber history resets. This cannot be undone."
msgstr "Odmah gubite sve pogodnosti {PREMIUM_PRODUCT_NAME} i vaša se povijest pretplate poništava. Ovo se ne može poništiti."
@@ -40231,6 +40231,11 @@ msgstr "vaša regija"
msgid "Your registration needs an extra anti-spam check before you can continue."
msgstr "Vaša registracija zahtijeva dodatnu provjeru radi zaštite od neželjene pošte prije nego što možete nastaviti."
#. Plutonium subscription card text shown while a failed renewal payment is being retried. {graceDate} is a date already formatted and localized by code; never write a date into the translation.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:470
msgid "Your renewal payment failed but <0/> stay active until <1>{graceDate}</1>. Update your payment method before then to keep your subscription."
msgstr "Plaćanje za obnovu pretplate nije uspjelo, ali <0/> ostaju aktivne do <1>{graceDate}</1>. Ažurirajte način plaćanja prije tog datuma kako biste zadržali pretplatu."
#. Video settings note shown when the saved screen share quality is above what this account can send. Resolutions are short labels such as 1440p or Source and rates are whole numbers. FPS is a technical token.
#: src/features/user/components/modals/tabs/UserVideoTab.tsx:92
msgid "Your saved {savedResolution} at {savedFrameRate} FPS needs {premiumProductName}, so shares use {resolution} at {frameRate} FPS."
@@ -40252,7 +40257,7 @@ msgstr "Vaš prijenos je i dalje aktivan"
msgid "Your subscription can't move to the new price right now."
msgstr "Vaša se pretplata trenutačno ne može prebaciti na novu cijenu."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:470
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:486
msgid "Your subscription ended but <0/> stay active until <1>{graceDate}</1>. Resubscribe before then to keep your subscriber history."
msgstr "Vaša je pretplata istekla, ali <0/> ostaju aktivne do <1>{graceDate}</1>. Ponovno se pretplatite prije tog datuma kako biste zadržali povijest pretplate."
@@ -40281,7 +40286,7 @@ msgstr "Pretplata vam je prebačena na mjesečnu naplatu."
msgid "Your subscription has been switched to yearly billing."
msgstr "Pretplata vam je prebačena na godišnju naplatu."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:512
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:528
msgid "Your subscription is active but perks are temporarily paused."
msgstr "Vaša je pretplata aktivna, ali su pogodnosti privremeno pauzirane."
@@ -40301,7 +40306,7 @@ msgid "Your subscription moves to the new price on {effectiveDate}."
msgstr "Vaša pretplata prelazi na novu cijenu {effectiveDate}."
#. Plutonium subscription card line shown to a subscriber on a legacy price whose subscription is already set to cancel. {cancelDate} is a date and {listPriceNewLabel} is a currency amount, both already formatted and localized by code; never write a date or an amount into the translation.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:666
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:682
msgid "Your subscription still ends on <0>{cancelDate}</0>. The current price is now {listPriceNewLabel}. If you reactivate, you can switch to it from here."
msgstr "Vaša pretplata i dalje završava <0>{cancelDate}</0>. Trenutna cijena je sada {listPriceNewLabel}. Ako ponovno aktivirate pretplatu, odavde možete prijeći na nju."
@@ -2471,7 +2471,7 @@ msgid "A Linux desktop update is available. Choose the package format for this s
msgstr "Elérhető egy frissítés az asztali Linux-alkalmazáshoz. Válaszd ki a rendszeredhez megfelelő csomagformátumot, és a(z) {productName} helyileg menti a csomagot."
#. Plutonium subscription card line offering a move to a lower price. {listPriceEffectiveDate} is a date already formatted and localized by code; never write a date into the translation.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:684
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:700
msgid "A lower price is available. Switching takes effect on <0>{listPriceEffectiveDate}</0> and changes nothing else."
msgstr "Alacsonyabb ár érhető el. A váltás ekkor lép életbe: <0>{listPriceEffectiveDate}</0>. Minden más változatlan marad."
@@ -3487,19 +3487,19 @@ msgstr "Az igazítási vezérlők csak szélesebb képernyőkön érhetők el"
msgid "All"
msgstr "Összes"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:524
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:540
msgid "All <0/> for <1>{effectiveMonthlyPrice}/month</1>."
msgstr "Az <0/> teljes köre <1>{effectiveMonthlyPrice}/hó</1> áron."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:546
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:562
msgid "All <0/> for <1>{effectiveYearlyPrice}/year</1>."
msgstr "Az <0/> teljes köre <1>{effectiveYearlyPrice}/év</1> áron."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:567
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:583
msgid "All <0/> included with your subscription."
msgstr "Az előfizetésed az <0/> teljes körét tartalmazza."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:514
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:530
msgid "All <0/>, forever. No billing, no renewals."
msgstr "Az <0/> teljes köre, örökre. Nincs számlázás, nincs megújítás."
@@ -6469,7 +6469,7 @@ msgid "Cancel import"
msgstr "Importálás megszakítása"
#. Billing button that cancels a scheduled move to a lower subscription price.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:821
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:837
msgid "Cancel price change"
msgstr "Árváltozás visszavonása"
@@ -6484,14 +6484,14 @@ msgid "Cancel request"
msgstr "Kérelem visszavonása"
#. Billing button that cancels a scheduled billing-cycle change.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:829
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:845
msgid "Cancel scheduled switch"
msgstr "Ütemezett váltás visszavonása"
#. Billing button that starts subscription cancellation.
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:844
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:142
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:860
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:141
#: src/features/user/components/settings_utils/search_index/PlutoniumIndex.ts:31
msgid "Cancel subscription"
msgstr "Előfizetés lemondása"
@@ -6501,7 +6501,7 @@ msgid "Cancel subscription?"
msgstr "Előfizetés lemondása?"
#. Plutonium subscription card hint shown to a subscriber who could move to a lower price but has another billing change already scheduled.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:647
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:663
msgid "Cancel the scheduled change to move to the current price instead."
msgstr "Vond vissza az ütemezett módosítást, hogy ehelyett az aktuális árra válthass."
@@ -6511,7 +6511,7 @@ msgid "Cancel upload"
msgstr "Feltöltés megszakítása"
#. Billing button that cancels a scheduled yearly upgrade.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:825
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:841
msgid "Cancel yearly upgrade"
msgstr "Éves előfizetésre váltás visszavonása"
@@ -6530,7 +6530,7 @@ msgstr "Lemondás folyamatban"
msgid "Cancellation"
msgstr "Visszhangszűrés"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:501
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:517
msgid "Cancels on <0>{cancelDate}</0>. <1/> remain active until then."
msgstr "Megszűnik ekkor: <0>{cancelDate}</0>. Az <1/> addig érvényben maradnak."
@@ -10872,7 +10872,7 @@ msgstr "Egyéni…"
#. Billing button that opens the external customer portal.
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:750
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:766
#: src/features/user/components/settings_utils/search_index/PlutoniumIndex.ts:39
msgid "Customer portal"
msgstr "Ügyfélportál"
@@ -13877,15 +13877,15 @@ msgid "End date"
msgstr "Befejezés dátuma"
#. Billing button that ends premium grace period immediately.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:856
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:872
msgid "End grace now"
msgstr "Türelmi időszak befejezése most"
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:164
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:163
msgid "End grace period"
msgstr "Türelmi időszak befejezése"
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:157
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:156
msgid "End grace period now?"
msgstr "Befejezed most a türelmi időszakot?"
@@ -16347,7 +16347,7 @@ msgstr "Ajándék: hamarosan lejár"
msgid "Gift: grace period (still have access)"
msgstr "Ajándék: türelmi időszak (továbbra is hozzáférsz)"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:486
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:502
msgid "Gifted <0/> until <1>{giftEndDate}</1>. Does not renew automatically. Redeem more gift codes to extend."
msgstr "Ajándékba kapott <0/> eddig: <1>{giftEndDate}</1>. Nem újul meg automatikusan. További ajándékkódok beváltásával meghosszabbítható."
@@ -16826,7 +16826,7 @@ msgid "Hate speech"
msgstr "Gyűlöletbeszéd"
#. Premium page text shown on an instance where the premium tier cannot be bought, only redeemed. {PREMIUM_PRODUCT_NAME} is the premium tier name.
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:297
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:296
msgid "Have a gift code? Redeem it to unlock {PREMIUM_PRODUCT_NAME}."
msgstr "Van ajándékkódod? Váltsd be, hogy feloldd a(z) {PREMIUM_PRODUCT_NAME} funkciót."
@@ -18926,7 +18926,7 @@ msgstr "Mellékletek megtartása a szerkesztett szöveg törlésekor"
msgid "Keep free and premium tiers. You can customize the tiers, sell premium through Stripe, or hand out gift codes later from the admin panel."
msgstr "Tartsd meg az ingyenes és a prémium szinteket. Testre szabhatod a szinteket, prémiumot adhatsz el a Stripe-on keresztül, vagy később ajándékkódokat osztogathatsz az admin panelből."
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:166
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:165
msgid "Keep grace period"
msgstr "Türelmi időszak megtartása"
@@ -18940,7 +18940,7 @@ msgstr "Tartsd mozdulatlanul Nekót"
msgid "Keep running"
msgstr "Futtatás folytatása"
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:144
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:143
msgid "Keep subscription"
msgstr "Előfizetés megtartása"
@@ -19297,8 +19297,8 @@ msgstr "Bal egérgomb"
msgid "Left tooltip"
msgstr "Bal oldali buboréksúgó"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:539
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:561
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:555
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:577
msgid "Legacy rate"
msgstr "Régi díjszabás"
@@ -21339,11 +21339,11 @@ msgstr "Havi"
msgid "Monthly {monthlyPrice}"
msgstr "Havi {monthlyPrice}"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:631
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:647
msgid "Monthly billing starts on <0>{pendingChangeDate}</0>."
msgstr "A havi számlázás ekkor kezdődik: <0>{pendingChangeDate}</0>."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:624
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:640
msgid "Monthly billing starts on <0>{pendingChangeDate}</0>. First monthly charge: {pendingInitialPriceLabel}. Future monthly renewals: {pendingRecurringPriceLabel}/month."
msgstr "A havi számlázás ekkor kezdődik: <0>{pendingChangeDate}</0>. Első havi díj: {pendingInitialPriceLabel}. Jövőbeli havi megújítások: {pendingRecurringPriceLabel}/hó."
@@ -22269,12 +22269,12 @@ msgid "New password"
msgstr "Új jelszó"
#. Plutonium subscription card line shown when a move to a lower price is scheduled but the new amount is unknown. {pendingChangeDate} is a date already formatted and localized by code; never write a date into the translation.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:595
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:611
msgid "New price scheduled for <0>{pendingChangeDate}</0>."
msgstr "Új ár ütemezve: <0>{pendingChangeDate}</0>."
#. Plutonium subscription card line shown when a move to a lower price is scheduled. {pendingChangeDate} is a date and {pendingTargetPriceLabel} is a currency amount, both already formatted and localized by code; never write a date or an amount into the translation.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:589
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:605
msgid "New price scheduled for <0>{pendingChangeDate}</0>. Renewals will be {pendingTargetPriceLabel} from then on."
msgstr "Új ár ütemezve: <0>{pendingChangeDate}</0>. A megújítások díja ettől kezdve {pendingTargetPriceLabel} lesz."
@@ -26152,7 +26152,7 @@ msgstr "Reakciók"
#. Billing button that cancels a scheduled subscription cancellation.
#. Button label on the premium-expired nagbar. Opens billing so the user can reactivate their subscription.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:746
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:762
#: src/features/app/components/layout/app_layout/nagbars/PremiumExpiredNagbar.tsx:25
msgid "Reactivate"
msgstr "Újraaktiválás"
@@ -26375,8 +26375,8 @@ msgstr "Beváltás magadnak"
#. Billing button for entering a premium gift code.
#. Billing button for entering a premium gift code.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:719
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:307
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:735
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:306
msgid "Redeem gift code"
msgstr "Ajándékkód beváltása"
@@ -27147,7 +27147,7 @@ msgstr "Megújítási küszöb (nap)"
msgid "Renew window (days)"
msgstr "Megújítási ablak (nap)"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:701
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:717
msgid "Renews on <0>{renewalDate}.</0>"
msgstr "Megújul ekkor: <0>{renewalDate}.</0>"
@@ -27896,8 +27896,8 @@ msgstr "Ablak visszaállítása"
#. Billing button for restarting a subscription during the grace period.
#. Billing button for starting a new subscription after premium expired.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:738
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:742
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:754
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:758
msgid "Resubscribe"
msgstr "Újra előfizetek"
@@ -32521,7 +32521,7 @@ msgid "Switch price"
msgstr "Ár váltása"
#. Billing button that opens confirmation to move the subscription down to the current price. {listPriceNewLabel} is the localized new price.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:806
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:822
msgid "Switch to {listPriceNewLabel}"
msgstr "Váltás erre: {listPriceNewLabel}"
@@ -32546,7 +32546,7 @@ msgstr "Váltás közvetlen bemenetre"
#. Billing button that opens confirmation to switch to monthly billing.
#. Button confirming a change to monthly subscription billing.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:57
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:789
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:805
msgid "Switch to monthly"
msgstr "Váltás havi fizetésre"
@@ -32615,7 +32615,7 @@ msgstr "Váltás két oszlopra"
#. Billing button that opens confirmation to switch to yearly billing.
#. Button confirming a change to yearly subscription billing.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:53
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:785
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:801
msgid "Switch to yearly"
msgstr "Váltás éves fizetésre"
@@ -35865,7 +35865,7 @@ msgstr "Egyéni emojik feloldása közvetlen beszélgetésekben a(z) {premiumPro
msgid "Unlock HD screen share with {premiumProductName}"
msgstr "HD-képernyőmegosztás feloldása a(z) {premiumProductName} csomaggal"
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:217
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:216
msgid "Unlock higher limits and exclusive features while supporting an independent communication platform."
msgstr "Oldj fel magasabb limiteket és exkluzív funkciókat, miközben támogatsz egy független kommunikációs platformot."
@@ -39015,15 +39015,15 @@ msgstr "Éves {yearlyPrice}"
msgid "Yearly gift"
msgstr "Éves ajándék"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:618
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:634
msgid "Yearly upgrade scheduled for <0>{pendingChangeDate}</0>."
msgstr "Éves előfizetésre váltás ütemezve: <0>{pendingChangeDate}</0>."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:603
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:619
msgid "Yearly upgrade scheduled for <0>{pendingChangeDate}</0>. First yearly charge: {pendingInitialPriceLabel} after a {pendingCreditPriceLabel} credit. Future yearly renewals: {pendingRecurringPriceLabel}/year."
msgstr "Éves előfizetésre váltás ütemezve: <0>{pendingChangeDate}</0>. Az első éves díj {pendingInitialPriceLabel}, a(z) {pendingCreditPriceLabel} jóváírás után. A további éves megújítások díja {pendingRecurringPriceLabel}/év."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:610
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:626
msgid "Yearly upgrade scheduled for <0>{pendingChangeDate}</0>. First yearly charge: {pendingInitialPriceLabel}. Future yearly renewals: {pendingRecurringPriceLabel}/year."
msgstr "Éves előfizetésre váltás ütemezve: <0>{pendingChangeDate}</0>. Első éves díj: {pendingInitialPriceLabel}. A további éves megújítások díja {pendingRecurringPriceLabel}/év."
@@ -39493,10 +39493,10 @@ msgid "You just pressed Tab. Keyboard mode is now on so you can navigate {produc
msgstr "Megnyomtad a Tab billentyűt. Bekapcsolt a billentyűzetes mód, így egér nélkül is navigálhatsz a(z) {productName} alkalmazásban."
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:137
msgid "You keep your perks until your next renewal date, then have a 3-day grace period to resubscribe and keep your subscriber history."
msgstr "Az előnyöket a következő megújítási dátumig megtartod. Ezután 3 napos türelmi időszak áll rendelkezésedre, hogy újra előfizess és megőrizd az előfizetői előzményeidet."
msgid "You keep your perks until your next renewal date. Reactivate before then to keep your subscriber history."
msgstr "Az előnyöket a következő megújítási dátumig megtartod. Ha addig újraaktiválod az előfizetést, megőrzöd az előfizetői előzményeidet."
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:159
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:158
msgid "You lose all {PREMIUM_PRODUCT_NAME} perks immediately and your subscriber history resets. This cannot be undone."
msgstr "Azonnal elveszíted a(z) {PREMIUM_PRODUCT_NAME} összes előnyét, és az előfizetői előzményeid lenullázódnak. Ez nem vonható vissza."
@@ -40231,6 +40231,11 @@ msgstr "saját"
msgid "Your registration needs an extra anti-spam check before you can continue."
msgstr "A regisztrációdhoz még egy spamellenőrzés szükséges, mielőtt folytathatnád."
#. Plutonium subscription card text shown while a failed renewal payment is being retried. {graceDate} is a date already formatted and localized by code; never write a date into the translation.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:470
msgid "Your renewal payment failed but <0/> stay active until <1>{graceDate}</1>. Update your payment method before then to keep your subscription."
msgstr "A megújítási fizetés sikertelen volt, de a(z) <0/> továbbra is aktívak eddig: <1>{graceDate}</1>. Addig frissítsd a fizetési módodat, hogy megtartsd az előfizetésedet."
#. Video settings note shown when the saved screen share quality is above what this account can send. Resolutions are short labels such as 1440p or Source and rates are whole numbers. FPS is a technical token.
#: src/features/user/components/modals/tabs/UserVideoTab.tsx:92
msgid "Your saved {savedResolution} at {savedFrameRate} FPS needs {premiumProductName}, so shares use {resolution} at {frameRate} FPS."
@@ -40252,7 +40257,7 @@ msgstr "A streamed továbbra is élőben megy"
msgid "Your subscription can't move to the new price right now."
msgstr "Az előfizetésed jelenleg nem váltható át az új árra."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:470
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:486
msgid "Your subscription ended but <0/> stay active until <1>{graceDate}</1>. Resubscribe before then to keep your subscriber history."
msgstr "Az előfizetésed lejárt, de a(z) <0/> továbbra is aktívak eddig: <1>{graceDate}</1>. Fizess elő újra addig, hogy megőrizd az előfizetői előzményeidet."
@@ -40281,7 +40286,7 @@ msgstr "Előfizetésed havi számlázásra váltott."
msgid "Your subscription has been switched to yearly billing."
msgstr "Előfizetésedet éves számlázásra váltottuk."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:512
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:528
msgid "Your subscription is active but perks are temporarily paused."
msgstr "Az előfizetésed aktív, de az előnyök ideiglenesen szünetelnek."
@@ -40301,7 +40306,7 @@ msgid "Your subscription moves to the new price on {effectiveDate}."
msgstr "Az előfizetésed új ára ekkor lép életbe: {effectiveDate}."
#. Plutonium subscription card line shown to a subscriber on a legacy price whose subscription is already set to cancel. {cancelDate} is a date and {listPriceNewLabel} is a currency amount, both already formatted and localized by code; never write a date or an amount into the translation.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:666
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:682
msgid "Your subscription still ends on <0>{cancelDate}</0>. The current price is now {listPriceNewLabel}. If you reactivate, you can switch to it from here."
msgstr "Az előfizetésed továbbra is ekkor ér véget: <0>{cancelDate}</0>. A jelenlegi ár most {listPriceNewLabel}. Ha újraaktiválod, innen átválthatsz rá."
@@ -2471,7 +2471,7 @@ msgid "A Linux desktop update is available. Choose the package format for this s
msgstr "Pembaruan desktop untuk Linux tersedia. Pilih format paket untuk sistem ini dan {productName} akan menyimpannya secara lokal."
#. Plutonium subscription card line offering a move to a lower price. {listPriceEffectiveDate} is a date already formatted and localized by code; never write a date into the translation.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:684
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:700
msgid "A lower price is available. Switching takes effect on <0>{listPriceEffectiveDate}</0> and changes nothing else."
msgstr "Harga yang lebih rendah tersedia. Peralihan berlaku mulai <0>{listPriceEffectiveDate}</0> dan tidak mengubah hal lain."
@@ -3487,19 +3487,19 @@ msgstr "Kontrol perataan hanya tersedia di layar yang lebih lebar"
msgid "All"
msgstr "Semua"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:524
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:540
msgid "All <0/> for <1>{effectiveMonthlyPrice}/month</1>."
msgstr "Semua <0/> seharga <1>{effectiveMonthlyPrice}/bulan</1>."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:546
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:562
msgid "All <0/> for <1>{effectiveYearlyPrice}/year</1>."
msgstr "Semua <0/> seharga <1>{effectiveYearlyPrice}/tahun</1>."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:567
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:583
msgid "All <0/> included with your subscription."
msgstr "Semua <0/> sudah termasuk dalam langgananmu."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:514
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:530
msgid "All <0/>, forever. No billing, no renewals."
msgstr "Semua <0/>, selamanya. Tanpa tagihan, tanpa perpanjangan."
@@ -6469,7 +6469,7 @@ msgid "Cancel import"
msgstr "Batalkan impor"
#. Billing button that cancels a scheduled move to a lower subscription price.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:821
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:837
msgid "Cancel price change"
msgstr "Batalkan perubahan harga"
@@ -6484,14 +6484,14 @@ msgid "Cancel request"
msgstr "Batalkan permintaan"
#. Billing button that cancels a scheduled billing-cycle change.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:829
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:845
msgid "Cancel scheduled switch"
msgstr "Batalkan perubahan terjadwal"
#. Billing button that starts subscription cancellation.
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:844
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:142
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:860
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:141
#: src/features/user/components/settings_utils/search_index/PlutoniumIndex.ts:31
msgid "Cancel subscription"
msgstr "Batalkan langganan"
@@ -6501,7 +6501,7 @@ msgid "Cancel subscription?"
msgstr "Batalkan langganan?"
#. Plutonium subscription card hint shown to a subscriber who could move to a lower price but has another billing change already scheduled.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:647
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:663
msgid "Cancel the scheduled change to move to the current price instead."
msgstr "Batalkan perubahan terjadwal untuk beralih ke harga saat ini."
@@ -6511,7 +6511,7 @@ msgid "Cancel upload"
msgstr "Batalkan unggahan"
#. Billing button that cancels a scheduled yearly upgrade.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:825
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:841
msgid "Cancel yearly upgrade"
msgstr "Batalkan peningkatan tahunan"
@@ -6530,7 +6530,7 @@ msgstr "Akan dibatalkan"
msgid "Cancellation"
msgstr "Pembatalan gema"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:501
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:517
msgid "Cancels on <0>{cancelDate}</0>. <1/> remain active until then."
msgstr "Dibatalkan pada <0>{cancelDate}</0>. <1/> tetap aktif sampai saat itu."
@@ -10872,7 +10872,7 @@ msgstr "Kustom…"
#. Billing button that opens the external customer portal.
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:750
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:766
#: src/features/user/components/settings_utils/search_index/PlutoniumIndex.ts:39
msgid "Customer portal"
msgstr "Portal pelanggan"
@@ -13877,15 +13877,15 @@ msgid "End date"
msgstr "Tanggal akhir"
#. Billing button that ends premium grace period immediately.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:856
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:872
msgid "End grace now"
msgstr "Akhiri masa tenggang sekarang"
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:164
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:163
msgid "End grace period"
msgstr "Akhiri masa tenggang"
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:157
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:156
msgid "End grace period now?"
msgstr "Akhiri masa tenggang sekarang?"
@@ -16347,7 +16347,7 @@ msgstr "Hadiah: akan segera berakhir"
msgid "Gift: grace period (still have access)"
msgstr "Hadiah: masa tenggang (masih memiliki akses)"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:486
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:502
msgid "Gifted <0/> until <1>{giftEndDate}</1>. Does not renew automatically. Redeem more gift codes to extend."
msgstr "Dihadiahkan <0/> hingga <1>{giftEndDate}</1>. Tidak diperpanjang secara otomatis. Tukarkan kode hadiah lainnya untuk memperpanjang."
@@ -16826,7 +16826,7 @@ msgid "Hate speech"
msgstr "Ujaran kebencian"
#. Premium page text shown on an instance where the premium tier cannot be bought, only redeemed. {PREMIUM_PRODUCT_NAME} is the premium tier name.
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:297
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:296
msgid "Have a gift code? Redeem it to unlock {PREMIUM_PRODUCT_NAME}."
msgstr "Punya kode hadiah? Tukarkan untuk membuka {PREMIUM_PRODUCT_NAME}."
@@ -18926,7 +18926,7 @@ msgstr "Pertahankan lampiran saat kolom edit dikosongkan"
msgid "Keep free and premium tiers. You can customize the tiers, sell premium through Stripe, or hand out gift codes later from the admin panel."
msgstr "Pertahankan tingkatan gratis dan premium. Anda dapat menyesuaikan tingkatan, menjual premium melalui Stripe, atau membagikan kode hadiah nanti dari panel admin."
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:166
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:165
msgid "Keep grace period"
msgstr "Pertahankan masa tenggang"
@@ -18940,7 +18940,7 @@ msgstr "Diamkan Neko"
msgid "Keep running"
msgstr "Tetap berjalan"
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:144
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:143
msgid "Keep subscription"
msgstr "Tetap berlangganan"
@@ -19297,8 +19297,8 @@ msgstr "Tombol kiri mouse"
msgid "Left tooltip"
msgstr "Tooltip kiri"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:539
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:561
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:555
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:577
msgid "Legacy rate"
msgstr "Harga lama"
@@ -21339,11 +21339,11 @@ msgstr "Bulanan"
msgid "Monthly {monthlyPrice}"
msgstr "Bulanan {monthlyPrice}"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:631
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:647
msgid "Monthly billing starts on <0>{pendingChangeDate}</0>."
msgstr "Penagihan bulanan dimulai pada <0>{pendingChangeDate}</0>."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:624
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:640
msgid "Monthly billing starts on <0>{pendingChangeDate}</0>. First monthly charge: {pendingInitialPriceLabel}. Future monthly renewals: {pendingRecurringPriceLabel}/month."
msgstr "Penagihan bulanan dimulai pada <0>{pendingChangeDate}</0>. Tagihan bulanan pertama: {pendingInitialPriceLabel}. Perpanjangan bulanan mendatang: {pendingRecurringPriceLabel}/bulan."
@@ -22269,12 +22269,12 @@ msgid "New password"
msgstr "Kata sandi baru"
#. Plutonium subscription card line shown when a move to a lower price is scheduled but the new amount is unknown. {pendingChangeDate} is a date already formatted and localized by code; never write a date into the translation.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:595
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:611
msgid "New price scheduled for <0>{pendingChangeDate}</0>."
msgstr "Harga baru dijadwalkan pada <0>{pendingChangeDate}</0>."
#. Plutonium subscription card line shown when a move to a lower price is scheduled. {pendingChangeDate} is a date and {pendingTargetPriceLabel} is a currency amount, both already formatted and localized by code; never write a date or an amount into the translation.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:589
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:605
msgid "New price scheduled for <0>{pendingChangeDate}</0>. Renewals will be {pendingTargetPriceLabel} from then on."
msgstr "Harga baru dijadwalkan pada <0>{pendingChangeDate}</0>. Perpanjangan akan dikenakan biaya {pendingTargetPriceLabel} mulai saat itu."
@@ -26152,7 +26152,7 @@ msgstr "Reaksi"
#. Billing button that cancels a scheduled subscription cancellation.
#. Button label on the premium-expired nagbar. Opens billing so the user can reactivate their subscription.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:746
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:762
#: src/features/app/components/layout/app_layout/nagbars/PremiumExpiredNagbar.tsx:25
msgid "Reactivate"
msgstr "Aktifkan lagi"
@@ -26375,8 +26375,8 @@ msgstr "Tukarkan untuk diri sendiri"
#. Billing button for entering a premium gift code.
#. Billing button for entering a premium gift code.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:719
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:307
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:735
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:306
msgid "Redeem gift code"
msgstr "Tukarkan kode hadiah"
@@ -27147,7 +27147,7 @@ msgstr "Ambang batas pembaruan (hari)"
msgid "Renew window (days)"
msgstr "Rentang pembaruan (hari)"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:701
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:717
msgid "Renews on <0>{renewalDate}.</0>"
msgstr "Diperpanjang pada <0>{renewalDate}.</0>"
@@ -27896,8 +27896,8 @@ msgstr "Pulihkan jendela"
#. Billing button for restarting a subscription during the grace period.
#. Billing button for starting a new subscription after premium expired.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:738
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:742
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:754
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:758
msgid "Resubscribe"
msgstr "Berlangganan lagi"
@@ -32521,7 +32521,7 @@ msgid "Switch price"
msgstr "Ubah harga"
#. Billing button that opens confirmation to move the subscription down to the current price. {listPriceNewLabel} is the localized new price.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:806
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:822
msgid "Switch to {listPriceNewLabel}"
msgstr "Beralih ke {listPriceNewLabel}"
@@ -32546,7 +32546,7 @@ msgstr "Beralih ke input langsung"
#. Billing button that opens confirmation to switch to monthly billing.
#. Button confirming a change to monthly subscription billing.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:57
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:789
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:805
msgid "Switch to monthly"
msgstr "Beralih ke bulanan"
@@ -32615,7 +32615,7 @@ msgstr "Beralih ke dua kolom"
#. Billing button that opens confirmation to switch to yearly billing.
#. Button confirming a change to yearly subscription billing.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:53
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:785
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:801
msgid "Switch to yearly"
msgstr "Beralih ke tahunan"
@@ -35865,7 +35865,7 @@ msgstr "Buka emoji kustom di DM dengan {premiumProductName}"
msgid "Unlock HD screen share with {premiumProductName}"
msgstr "Buka berbagi layar HD dengan {premiumProductName}"
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:217
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:216
msgid "Unlock higher limits and exclusive features while supporting an independent communication platform."
msgstr "Dapatkan batas lebih tinggi dan fitur eksklusif sambil mendukung platform komunikasi independen."
@@ -39015,15 +39015,15 @@ msgstr "Tahunan {yearlyPrice}"
msgid "Yearly gift"
msgstr "Hadiah tahunan"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:618
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:634
msgid "Yearly upgrade scheduled for <0>{pendingChangeDate}</0>."
msgstr "Peningkatan tahunan dijadwalkan pada <0>{pendingChangeDate}</0>."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:603
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:619
msgid "Yearly upgrade scheduled for <0>{pendingChangeDate}</0>. First yearly charge: {pendingInitialPriceLabel} after a {pendingCreditPriceLabel} credit. Future yearly renewals: {pendingRecurringPriceLabel}/year."
msgstr "Peningkatan tahunan dijadwalkan pada <0>{pendingChangeDate}</0>. Tagihan tahunan pertama: {pendingInitialPriceLabel} setelah kredit {pendingCreditPriceLabel}. Perpanjangan tahunan berikutnya: {pendingRecurringPriceLabel}/tahun."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:610
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:626
msgid "Yearly upgrade scheduled for <0>{pendingChangeDate}</0>. First yearly charge: {pendingInitialPriceLabel}. Future yearly renewals: {pendingRecurringPriceLabel}/year."
msgstr "Peningkatan tahunan dijadwalkan pada <0>{pendingChangeDate}</0>. Tagihan tahunan pertama: {pendingInitialPriceLabel}. Perpanjangan tahunan berikutnya: {pendingRecurringPriceLabel}/tahun."
@@ -39493,10 +39493,10 @@ msgid "You just pressed Tab. Keyboard mode is now on so you can navigate {produc
msgstr "Kamu baru saja menekan Tab. Mode keyboard kini aktif sehingga kamu bisa menavigasi {productName} tanpa mouse."
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:137
msgid "You keep your perks until your next renewal date, then have a 3-day grace period to resubscribe and keep your subscriber history."
msgstr "Kamu tetap mendapat semua keuntungan hingga tanggal perpanjangan berikutnya, lalu ada masa tenggang 3 hari untuk berlangganan lagi dan mempertahankan riwayat langgananmu."
msgid "You keep your perks until your next renewal date. Reactivate before then to keep your subscriber history."
msgstr "Kamu tetap mendapat semua keuntungan hingga tanggal perpanjangan berikutnya. Aktifkan lagi langgananmu sebelum tanggal itu untuk mempertahankan riwayat langgananmu."
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:159
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:158
msgid "You lose all {PREMIUM_PRODUCT_NAME} perks immediately and your subscriber history resets. This cannot be undone."
msgstr "Kamu langsung kehilangan semua keuntungan {PREMIUM_PRODUCT_NAME} dan riwayat langgananmu diatur ulang. Ini tidak dapat dibatalkan."
@@ -40231,6 +40231,11 @@ msgstr "wilayahmu"
msgid "Your registration needs an extra anti-spam check before you can continue."
msgstr "Pendaftaranmu memerlukan pemeriksaan anti-spam tambahan sebelum kamu bisa melanjutkan."
#. Plutonium subscription card text shown while a failed renewal payment is being retried. {graceDate} is a date already formatted and localized by code; never write a date into the translation.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:470
msgid "Your renewal payment failed but <0/> stay active until <1>{graceDate}</1>. Update your payment method before then to keep your subscription."
msgstr "Pembayaran perpanjanganmu gagal, tetapi <0/> tetap aktif hingga <1>{graceDate}</1>. Perbarui metode pembayaranmu sebelum tanggal itu untuk mempertahankan langgananmu."
#. Video settings note shown when the saved screen share quality is above what this account can send. Resolutions are short labels such as 1440p or Source and rates are whole numbers. FPS is a technical token.
#: src/features/user/components/modals/tabs/UserVideoTab.tsx:92
msgid "Your saved {savedResolution} at {savedFrameRate} FPS needs {premiumProductName}, so shares use {resolution} at {frameRate} FPS."
@@ -40252,7 +40257,7 @@ msgstr "Streamingmu masih aktif"
msgid "Your subscription can't move to the new price right now."
msgstr "Langgananmu tidak bisa beralih ke harga baru saat ini."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:470
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:486
msgid "Your subscription ended but <0/> stay active until <1>{graceDate}</1>. Resubscribe before then to keep your subscriber history."
msgstr "Langgananmu berakhir, tetapi <0/> tetap aktif hingga <1>{graceDate}</1>. Berlangganan lagi sebelum tanggal itu untuk mempertahankan riwayat langgananmu."
@@ -40281,7 +40286,7 @@ msgstr "Langgananmu telah diubah ke penagihan bulanan."
msgid "Your subscription has been switched to yearly billing."
msgstr "Langgananmu telah diubah ke penagihan tahunan."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:512
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:528
msgid "Your subscription is active but perks are temporarily paused."
msgstr "Langgananmu aktif, tetapi keuntungannya dijeda sementara."
@@ -40301,7 +40306,7 @@ msgid "Your subscription moves to the new price on {effectiveDate}."
msgstr "Langgananmu akan beralih ke harga baru pada {effectiveDate}."
#. Plutonium subscription card line shown to a subscriber on a legacy price whose subscription is already set to cancel. {cancelDate} is a date and {listPriceNewLabel} is a currency amount, both already formatted and localized by code; never write a date or an amount into the translation.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:666
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:682
msgid "Your subscription still ends on <0>{cancelDate}</0>. The current price is now {listPriceNewLabel}. If you reactivate, you can switch to it from here."
msgstr "Langgananmu tetap berakhir pada <0>{cancelDate}</0>. Harga saat ini adalah {listPriceNewLabel}. Jika kamu mengaktifkannya kembali, kamu bisa beralih ke harga itu dari sini."
@@ -2471,7 +2471,7 @@ msgid "A Linux desktop update is available. Choose the package format for this s
msgstr "È disponibile un aggiornamento dell’app desktop per Linux. Scegli il formato del pacchetto per questo sistema e {productName} lo salverà localmente."
#. Plutonium subscription card line offering a move to a lower price. {listPriceEffectiveDate} is a date already formatted and localized by code; never write a date into the translation.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:684
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:700
msgid "A lower price is available. Switching takes effect on <0>{listPriceEffectiveDate}</0> and changes nothing else."
msgstr "È disponibile un prezzo inferiore. Il passaggio avrà effetto il <0>{listPriceEffectiveDate}</0> e non cambierà nient'altro."
@@ -3487,19 +3487,19 @@ msgstr "I controlli di allineamento sono disponibili solo su schermi più ampi"
msgid "All"
msgstr "Tutti"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:524
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:540
msgid "All <0/> for <1>{effectiveMonthlyPrice}/month</1>."
msgstr "Tutti i <0/> a <1>{effectiveMonthlyPrice}/mese</1>."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:546
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:562
msgid "All <0/> for <1>{effectiveYearlyPrice}/year</1>."
msgstr "Tutti i <0/> a <1>{effectiveYearlyPrice}/anno</1>."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:567
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:583
msgid "All <0/> included with your subscription."
msgstr "Tutti i <0/> inclusi nel tuo abbonamento."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:514
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:530
msgid "All <0/>, forever. No billing, no renewals."
msgstr "Tutti i <0/>, per sempre. Nessun addebito, nessun rinnovo."
@@ -6469,7 +6469,7 @@ msgid "Cancel import"
msgstr "Annulla importazione"
#. Billing button that cancels a scheduled move to a lower subscription price.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:821
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:837
msgid "Cancel price change"
msgstr "Annulla modifica prezzo"
@@ -6484,14 +6484,14 @@ msgid "Cancel request"
msgstr "Annulla richiesta"
#. Billing button that cancels a scheduled billing-cycle change.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:829
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:845
msgid "Cancel scheduled switch"
msgstr "Annulla cambio programmato"
#. Billing button that starts subscription cancellation.
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:844
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:142
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:860
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:141
#: src/features/user/components/settings_utils/search_index/PlutoniumIndex.ts:31
msgid "Cancel subscription"
msgstr "Disdici abbonamento"
@@ -6501,7 +6501,7 @@ msgid "Cancel subscription?"
msgstr "Disdire l’abbonamento?"
#. Plutonium subscription card hint shown to a subscriber who could move to a lower price but has another billing change already scheduled.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:647
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:663
msgid "Cancel the scheduled change to move to the current price instead."
msgstr "Annulla la modifica programmata per passare invece al prezzo attuale."
@@ -6511,7 +6511,7 @@ msgid "Cancel upload"
msgstr "Annulla caricamento"
#. Billing button that cancels a scheduled yearly upgrade.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:825
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:841
msgid "Cancel yearly upgrade"
msgstr "Annulla il passaggio all’abbonamento annuale"
@@ -6530,7 +6530,7 @@ msgstr "Annullamento in corso"
msgid "Cancellation"
msgstr "Cancellazione dell'eco"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:501
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:517
msgid "Cancels on <0>{cancelDate}</0>. <1/> remain active until then."
msgstr "Termina il <0>{cancelDate}</0>. I <1/> rimangono attivi fino a quella data."
@@ -10872,7 +10872,7 @@ msgstr "Personalizzato…"
#. Billing button that opens the external customer portal.
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:750
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:766
#: src/features/user/components/settings_utils/search_index/PlutoniumIndex.ts:39
msgid "Customer portal"
msgstr "Portale clienti"
@@ -13877,15 +13877,15 @@ msgid "End date"
msgstr "Data di fine"
#. Billing button that ends premium grace period immediately.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:856
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:872
msgid "End grace now"
msgstr "Termina periodo di tolleranza"
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:164
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:163
msgid "End grace period"
msgstr "Termina periodo di tolleranza"
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:157
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:156
msgid "End grace period now?"
msgstr "Terminare subito il periodo di tolleranza?"
@@ -16347,7 +16347,7 @@ msgstr "Regalo: in scadenza"
msgid "Gift: grace period (still have access)"
msgstr "Regalo: periodo di tolleranza (hai ancora accesso)"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:486
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:502
msgid "Gifted <0/> until <1>{giftEndDate}</1>. Does not renew automatically. Redeem more gift codes to extend."
msgstr "Ricevi in regalo i <0/> fino al <1>{giftEndDate}</1>. Non si rinnovano automaticamente. Riscatta altri codici regalo per prolungarne la durata."
@@ -16826,7 +16826,7 @@ msgid "Hate speech"
msgstr "Incitamento all'odio"
#. Premium page text shown on an instance where the premium tier cannot be bought, only redeemed. {PREMIUM_PRODUCT_NAME} is the premium tier name.
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:297
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:296
msgid "Have a gift code? Redeem it to unlock {PREMIUM_PRODUCT_NAME}."
msgstr "Hai un codice regalo? Riscatta per sbloccare {PREMIUM_PRODUCT_NAME}."
@@ -18926,7 +18926,7 @@ msgstr "Mantieni gli allegati durante la cancellazione di una modifica"
msgid "Keep free and premium tiers. You can customize the tiers, sell premium through Stripe, or hand out gift codes later from the admin panel."
msgstr "Mantieni i livelli gratuiti e premium. Potrai personalizzare i livelli, vendere il premium tramite Stripe o distribuire codici regalo in seguito dal pannello di amministrazione."
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:166
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:165
msgid "Keep grace period"
msgstr "Mantieni periodo di tolleranza"
@@ -18940,7 +18940,7 @@ msgstr "Mantieni Neko fermo"
msgid "Keep running"
msgstr "Continua l’esecuzione"
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:144
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:143
msgid "Keep subscription"
msgstr "Mantieni abbonamento"
@@ -19297,8 +19297,8 @@ msgstr "Pulsante sinistro del mouse"
msgid "Left tooltip"
msgstr "Tooltip sinistro"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:539
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:561
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:555
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:577
msgid "Legacy rate"
msgstr "Tariffa precedente"
@@ -21339,11 +21339,11 @@ msgstr "Mensile"
msgid "Monthly {monthlyPrice}"
msgstr "{monthlyPrice} al mese"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:631
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:647
msgid "Monthly billing starts on <0>{pendingChangeDate}</0>."
msgstr "La fatturazione mensile inizia il <0>{pendingChangeDate}</0>."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:624
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:640
msgid "Monthly billing starts on <0>{pendingChangeDate}</0>. First monthly charge: {pendingInitialPriceLabel}. Future monthly renewals: {pendingRecurringPriceLabel}/month."
msgstr "La fatturazione mensile inizia il <0>{pendingChangeDate}</0>. Primo addebito mensile: {pendingInitialPriceLabel}. Rinnovi mensili futuri: {pendingRecurringPriceLabel}/mese."
@@ -22269,12 +22269,12 @@ msgid "New password"
msgstr "Nuova password"
#. Plutonium subscription card line shown when a move to a lower price is scheduled but the new amount is unknown. {pendingChangeDate} is a date already formatted and localized by code; never write a date into the translation.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:595
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:611
msgid "New price scheduled for <0>{pendingChangeDate}</0>."
msgstr "Nuovo prezzo previsto per il <0>{pendingChangeDate}</0>."
#. Plutonium subscription card line shown when a move to a lower price is scheduled. {pendingChangeDate} is a date and {pendingTargetPriceLabel} is a currency amount, both already formatted and localized by code; never write a date or an amount into the translation.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:589
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:605
msgid "New price scheduled for <0>{pendingChangeDate}</0>. Renewals will be {pendingTargetPriceLabel} from then on."
msgstr "Nuovo prezzo previsto per il <0>{pendingChangeDate}</0>. I rinnovi saranno di {pendingTargetPriceLabel} da allora."
@@ -26152,7 +26152,7 @@ msgstr "Reazioni"
#. Billing button that cancels a scheduled subscription cancellation.
#. Button label on the premium-expired nagbar. Opens billing so the user can reactivate their subscription.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:746
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:762
#: src/features/app/components/layout/app_layout/nagbars/PremiumExpiredNagbar.tsx:25
msgid "Reactivate"
msgstr "Riattiva"
@@ -26375,8 +26375,8 @@ msgstr "Riscatta per te"
#. Billing button for entering a premium gift code.
#. Billing button for entering a premium gift code.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:719
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:307
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:735
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:306
msgid "Redeem gift code"
msgstr "Riscatta codice regalo"
@@ -27147,7 +27147,7 @@ msgstr "Soglia rinnovo (giorni)"
msgid "Renew window (days)"
msgstr "Periodo rinnovo (giorni)"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:701
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:717
msgid "Renews on <0>{renewalDate}.</0>"
msgstr "Si rinnova il <0>{renewalDate}.</0>"
@@ -27896,8 +27896,8 @@ msgstr "Ripristina finestra"
#. Billing button for restarting a subscription during the grace period.
#. Billing button for starting a new subscription after premium expired.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:738
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:742
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:754
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:758
msgid "Resubscribe"
msgstr "Riattiva abbonamento"
@@ -32521,7 +32521,7 @@ msgid "Switch price"
msgstr "Cambia prezzo"
#. Billing button that opens confirmation to move the subscription down to the current price. {listPriceNewLabel} is the localized new price.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:806
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:822
msgid "Switch to {listPriceNewLabel}"
msgstr "Passa a {listPriceNewLabel}"
@@ -32546,7 +32546,7 @@ msgstr "Passa all'input diretto"
#. Billing button that opens confirmation to switch to monthly billing.
#. Button confirming a change to monthly subscription billing.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:57
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:789
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:805
msgid "Switch to monthly"
msgstr "Passa al piano mensile"
@@ -32615,7 +32615,7 @@ msgstr "Passa a due colonne"
#. Billing button that opens confirmation to switch to yearly billing.
#. Button confirming a change to yearly subscription billing.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:53
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:785
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:801
msgid "Switch to yearly"
msgstr "Passa al piano annuale"
@@ -35865,7 +35865,7 @@ msgstr "Sblocca le emoji personalizzate nei DM con {premiumProductName}"
msgid "Unlock HD screen share with {premiumProductName}"
msgstr "Sblocca la condivisione schermo HD con {premiumProductName}"
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:217
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:216
msgid "Unlock higher limits and exclusive features while supporting an independent communication platform."
msgstr "Sblocca limiti più elevati e funzionalità esclusive, supportando al contempo una piattaforma di comunicazione indipendente."
@@ -39015,15 +39015,15 @@ msgstr "Annuale {yearlyPrice}"
msgid "Yearly gift"
msgstr "Regalo annuale"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:618
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:634
msgid "Yearly upgrade scheduled for <0>{pendingChangeDate}</0>."
msgstr "Upgrade annuale programmato per il <0>{pendingChangeDate}</0>."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:603
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:619
msgid "Yearly upgrade scheduled for <0>{pendingChangeDate}</0>. First yearly charge: {pendingInitialPriceLabel} after a {pendingCreditPriceLabel} credit. Future yearly renewals: {pendingRecurringPriceLabel}/year."
msgstr "Upgrade annuale programmato per il <0>{pendingChangeDate}</0>. Primo addebito annuale: {pendingInitialPriceLabel} dopo un credito di {pendingCreditPriceLabel}. Rinnovi annuali futuri: {pendingRecurringPriceLabel}/anno."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:610
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:626
msgid "Yearly upgrade scheduled for <0>{pendingChangeDate}</0>. First yearly charge: {pendingInitialPriceLabel}. Future yearly renewals: {pendingRecurringPriceLabel}/year."
msgstr "Upgrade annuale programmato per il <0>{pendingChangeDate}</0>. Primo addebito annuale: {pendingInitialPriceLabel}. Rinnovi annuali futuri: {pendingRecurringPriceLabel}/anno."
@@ -39493,10 +39493,10 @@ msgid "You just pressed Tab. Keyboard mode is now on so you can navigate {produc
msgstr "Hai appena premuto Tab. La modalità tastiera è ora attiva, così puoi navigare in {productName} senza mouse."
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:137
msgid "You keep your perks until your next renewal date, then have a 3-day grace period to resubscribe and keep your subscriber history."
msgstr "Manterrai i tuoi vantaggi fino alla prossima data di rinnovo, poi avrai un periodo di tolleranza di 3 giorni per riabbonarti e mantenere la tua cronologia di abbonato."
msgid "You keep your perks until your next renewal date. Reactivate before then to keep your subscriber history."
msgstr "Manterrai i tuoi vantaggi fino alla prossima data di rinnovo. Riattiva l’abbonamento prima di allora per mantenere la tua cronologia di abbonato."
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:159
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:158
msgid "You lose all {PREMIUM_PRODUCT_NAME} perks immediately and your subscriber history resets. This cannot be undone."
msgstr "Perderai immediatamente tutti i vantaggi di {PREMIUM_PRODUCT_NAME} e la cronologia dell'abbonamento verrà reimpostata. Questa azione non può essere annullata."
@@ -40231,6 +40231,11 @@ msgstr "la tua regione"
msgid "Your registration needs an extra anti-spam check before you can continue."
msgstr "La tua registrazione richiede un controllo anti-spam aggiuntivo prima di poter continuare."
#. Plutonium subscription card text shown while a failed renewal payment is being retried. {graceDate} is a date already formatted and localized by code; never write a date into the translation.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:470
msgid "Your renewal payment failed but <0/> stay active until <1>{graceDate}</1>. Update your payment method before then to keep your subscription."
msgstr "Il pagamento del rinnovo non è andato a buon fine, ma i <0/> rimangono attivi fino al <1>{graceDate}</1>. Aggiorna il metodo di pagamento prima di allora per mantenere il tuo abbonamento."
#. Video settings note shown when the saved screen share quality is above what this account can send. Resolutions are short labels such as 1440p or Source and rates are whole numbers. FPS is a technical token.
#: src/features/user/components/modals/tabs/UserVideoTab.tsx:92
msgid "Your saved {savedResolution} at {savedFrameRate} FPS needs {premiumProductName}, so shares use {resolution} at {frameRate} FPS."
@@ -40252,7 +40257,7 @@ msgstr "Il tuo stream è ancora attivo"
msgid "Your subscription can't move to the new price right now."
msgstr "L'abbonamento non può essere spostato al nuovo prezzo al momento."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:470
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:486
msgid "Your subscription ended but <0/> stay active until <1>{graceDate}</1>. Resubscribe before then to keep your subscriber history."
msgstr "Il tuo abbonamento è terminato, ma i <0/> rimangono attivi fino al <1>{graceDate}</1>. Riabbonati prima di allora per mantenere la tua cronologia di abbonato."
@@ -40281,7 +40286,7 @@ msgstr "Il tuo abbonamento è stato convertito in fatturazione mensile."
msgid "Your subscription has been switched to yearly billing."
msgstr "Il tuo abbonamento è stato convertito in fatturazione annuale."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:512
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:528
msgid "Your subscription is active but perks are temporarily paused."
msgstr "Il tuo abbonamento è attivo, ma i vantaggi sono temporaneamente in pausa."
@@ -40301,7 +40306,7 @@ msgid "Your subscription moves to the new price on {effectiveDate}."
msgstr "Il tuo abbonamento passerà al nuovo prezzo il {effectiveDate}."
#. Plutonium subscription card line shown to a subscriber on a legacy price whose subscription is already set to cancel. {cancelDate} is a date and {listPriceNewLabel} is a currency amount, both already formatted and localized by code; never write a date or an amount into the translation.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:666
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:682
msgid "Your subscription still ends on <0>{cancelDate}</0>. The current price is now {listPriceNewLabel}. If you reactivate, you can switch to it from here."
msgstr "Il tuo abbonamento termina comunque il <0>{cancelDate}</0>. Il prezzo attuale è ora {listPriceNewLabel}. Se riattivi l’abbonamento, puoi passare al nuovo prezzo da qui."
@@ -2471,7 +2471,7 @@ msgid "A Linux desktop update is available. Choose the package format for this s
msgstr "Linuxデスクトップ版のアップデートが利用可能です。このシステムで使用するパッケージ形式を選択すると、{productName}がファイルをローカルに保存します。"
#. Plutonium subscription card line offering a move to a lower price. {listPriceEffectiveDate} is a date already formatted and localized by code; never write a date into the translation.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:684
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:700
msgid "A lower price is available. Switching takes effect on <0>{listPriceEffectiveDate}</0> and changes nothing else."
msgstr "より安い価格をご利用いただけます。切り替えは<0>{listPriceEffectiveDate}</0>から適用され、それ以外は何も変わりません。"
@@ -3487,19 +3487,19 @@ msgstr "配置調整は、画面幅が広い場合のみ利用できます"
msgid "All"
msgstr "すべて"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:524
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:540
msgid "All <0/> for <1>{effectiveMonthlyPrice}/month</1>."
msgstr "すべての<0/>を<1>{effectiveMonthlyPrice}/月</1>でご利用いただけます。"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:546
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:562
msgid "All <0/> for <1>{effectiveYearlyPrice}/year</1>."
msgstr "すべての<0/>を<1>{effectiveYearlyPrice}/年</1>でご利用いただけます。"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:567
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:583
msgid "All <0/> included with your subscription."
msgstr "すべての<0/>はサブスクリプションに含まれています。"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:514
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:530
msgid "All <0/>, forever. No billing, no renewals."
msgstr "すべての<0/>を永久にご利用いただけます。請求も更新もありません。"
@@ -6469,7 +6469,7 @@ msgid "Cancel import"
msgstr "インポートをキャンセル"
#. Billing button that cancels a scheduled move to a lower subscription price.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:821
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:837
msgid "Cancel price change"
msgstr "価格変更をキャンセル"
@@ -6484,14 +6484,14 @@ msgid "Cancel request"
msgstr "リクエストをキャンセル"
#. Billing button that cancels a scheduled billing-cycle change.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:829
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:845
msgid "Cancel scheduled switch"
msgstr "予約済みの切り替えをキャンセル"
#. Billing button that starts subscription cancellation.
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:844
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:142
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:860
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:141
#: src/features/user/components/settings_utils/search_index/PlutoniumIndex.ts:31
msgid "Cancel subscription"
msgstr "サブスクリプションをキャンセル"
@@ -6501,7 +6501,7 @@ msgid "Cancel subscription?"
msgstr "サブスクリプションをキャンセルしますか?"
#. Plutonium subscription card hint shown to a subscriber who could move to a lower price but has another billing change already scheduled.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:647
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:663
msgid "Cancel the scheduled change to move to the current price instead."
msgstr "現在の価格に変更するには、予定されている変更をキャンセルしてください。"
@@ -6511,7 +6511,7 @@ msgid "Cancel upload"
msgstr "アップロードをキャンセル"
#. Billing button that cancels a scheduled yearly upgrade.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:825
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:841
msgid "Cancel yearly upgrade"
msgstr "年額プランのアップグレードをキャンセル"
@@ -6530,7 +6530,7 @@ msgstr "キャンセル中"
msgid "Cancellation"
msgstr "エコーキャンセレーション"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:501
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:517
msgid "Cancels on <0>{cancelDate}</0>. <1/> remain active until then."
msgstr "<0>{cancelDate}</0>にキャンセルされます。<1/>それまでは引き続きご利用いただけます。"
@@ -10872,7 +10872,7 @@ msgstr "カスタム…"
#. Billing button that opens the external customer portal.
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:750
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:766
#: src/features/user/components/settings_utils/search_index/PlutoniumIndex.ts:39
msgid "Customer portal"
msgstr "カスタマーポータル"
@@ -13877,15 +13877,15 @@ msgid "End date"
msgstr "終了日"
#. Billing button that ends premium grace period immediately.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:856
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:872
msgid "End grace now"
msgstr "猶予期間を終了"
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:164
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:163
msgid "End grace period"
msgstr "猶予期間を終了"
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:157
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:156
msgid "End grace period now?"
msgstr "猶予期間を今すぐ終了しますか?"
@@ -16347,7 +16347,7 @@ msgstr "ギフト:もうすぐ期限切れ"
msgid "Gift: grace period (still have access)"
msgstr "ギフト:猶予期間(引き続きアクセス可能)"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:486
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:502
msgid "Gifted <0/> until <1>{giftEndDate}</1>. Does not renew automatically. Redeem more gift codes to extend."
msgstr "<0/>をギフトで<1>{giftEndDate}</1>まで利用できます。自動更新はされません。ギフトコードをさらに引き換えると期間を延長できます。"
@@ -16826,7 +16826,7 @@ msgid "Hate speech"
msgstr "ヘイトスピーチ"
#. Premium page text shown on an instance where the premium tier cannot be bought, only redeemed. {PREMIUM_PRODUCT_NAME} is the premium tier name.
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:297
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:296
msgid "Have a gift code? Redeem it to unlock {PREMIUM_PRODUCT_NAME}."
msgstr "ギフトコードをお持ちですか?{PREMIUM_PRODUCT_NAME}をアンロックするためにコードを入力してください。"
@@ -18926,7 +18926,7 @@ msgstr "編集をクリアしても添付ファイルを保持する"
msgid "Keep free and premium tiers. You can customize the tiers, sell premium through Stripe, or hand out gift codes later from the admin panel."
msgstr "無料版とプレミアム版を残します。ティアをカスタマイズしたり、Stripe で"
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:166
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:165
msgid "Keep grace period"
msgstr "猶予期間を保持"
@@ -18940,7 +18940,7 @@ msgstr "ネコを固定する"
msgid "Keep running"
msgstr "常駐"
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:144
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:143
msgid "Keep subscription"
msgstr "サブスクリプションを継続"
@@ -19297,8 +19297,8 @@ msgstr "マウスの左ボタン"
msgid "Left tooltip"
msgstr "左ツールチップ"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:539
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:561
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:555
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:577
msgid "Legacy rate"
msgstr "旧料金"
@@ -21339,11 +21339,11 @@ msgstr "月額"
msgid "Monthly {monthlyPrice}"
msgstr "月額{monthlyPrice}"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:631
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:647
msgid "Monthly billing starts on <0>{pendingChangeDate}</0>."
msgstr "月額の請求は<0>{pendingChangeDate}</0>に開始されます。"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:624
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:640
msgid "Monthly billing starts on <0>{pendingChangeDate}</0>. First monthly charge: {pendingInitialPriceLabel}. Future monthly renewals: {pendingRecurringPriceLabel}/month."
msgstr "<0>{pendingChangeDate}</0>より月額請求が開始されます。初回月額料金: {pendingInitialPriceLabel}。次月以降の月額更新料金: {pendingRecurringPriceLabel}/月。"
@@ -22269,12 +22269,12 @@ msgid "New password"
msgstr "新しいパスワード"
#. Plutonium subscription card line shown when a move to a lower price is scheduled but the new amount is unknown. {pendingChangeDate} is a date already formatted and localized by code; never write a date into the translation.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:595
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:611
msgid "New price scheduled for <0>{pendingChangeDate}</0>."
msgstr "新しい価格は<0>{pendingChangeDate}</0>に予定されています。"
#. Plutonium subscription card line shown when a move to a lower price is scheduled. {pendingChangeDate} is a date and {pendingTargetPriceLabel} is a currency amount, both already formatted and localized by code; never write a date or an amount into the translation.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:589
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:605
msgid "New price scheduled for <0>{pendingChangeDate}</0>. Renewals will be {pendingTargetPriceLabel} from then on."
msgstr "<0>{pendingChangeDate}</0>に新しい価格が適用されます。それ以降の更新は{pendingTargetPriceLabel}になります。"
@@ -26152,7 +26152,7 @@ msgstr "リアクション"
#. Billing button that cancels a scheduled subscription cancellation.
#. Button label on the premium-expired nagbar. Opens billing so the user can reactivate their subscription.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:746
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:762
#: src/features/app/components/layout/app_layout/nagbars/PremiumExpiredNagbar.tsx:25
msgid "Reactivate"
msgstr "再開する"
@@ -26375,8 +26375,8 @@ msgstr "自分で引き換える"
#. Billing button for entering a premium gift code.
#. Billing button for entering a premium gift code.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:719
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:307
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:735
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:306
msgid "Redeem gift code"
msgstr "ギフトコードを引き換える"
@@ -27147,7 +27147,7 @@ msgstr "更新しきい値(日)"
msgid "Renew window (days)"
msgstr "更新ウィンドウ(日)"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:701
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:717
msgid "Renews on <0>{renewalDate}.</0>"
msgstr "<0>{renewalDate}</0>に更新されます。"
@@ -27896,8 +27896,8 @@ msgstr "ウィンドウを元に戻す"
#. Billing button for restarting a subscription during the grace period.
#. Billing button for starting a new subscription after premium expired.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:738
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:742
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:754
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:758
msgid "Resubscribe"
msgstr "再登録"
@@ -32521,7 +32521,7 @@ msgid "Switch price"
msgstr "価格を変更"
#. Billing button that opens confirmation to move the subscription down to the current price. {listPriceNewLabel} is the localized new price.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:806
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:822
msgid "Switch to {listPriceNewLabel}"
msgstr "{listPriceNewLabel}に切り替える"
@@ -32546,7 +32546,7 @@ msgstr "直接入力に切り替える"
#. Billing button that opens confirmation to switch to monthly billing.
#. Button confirming a change to monthly subscription billing.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:57
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:789
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:805
msgid "Switch to monthly"
msgstr "月額払いに変更"
@@ -32615,7 +32615,7 @@ msgstr "2列表示に切り替える"
#. Billing button that opens confirmation to switch to yearly billing.
#. Button confirming a change to yearly subscription billing.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:53
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:785
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:801
msgid "Switch to yearly"
msgstr "年額払いに変更"
@@ -35865,7 +35865,7 @@ msgstr "{premiumProductName}でDMのカスタム絵文字をアンロック"
msgid "Unlock HD screen share with {premiumProductName}"
msgstr "{premiumProductName}でHD画面共有をアンロック"
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:217
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:216
msgid "Unlock higher limits and exclusive features while supporting an independent communication platform."
msgstr "独立したコミュニケーションプラットフォームを支援しながら、上限アップや限定機能をご利用いただけます。"
@@ -39015,15 +39015,15 @@ msgstr "年額{yearlyPrice}"
msgid "Yearly gift"
msgstr "年間ギフト"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:618
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:634
msgid "Yearly upgrade scheduled for <0>{pendingChangeDate}</0>."
msgstr "<0>{pendingChangeDate}</0>に年額プランへのアップグレードが予定されています。"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:603
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:619
msgid "Yearly upgrade scheduled for <0>{pendingChangeDate}</0>. First yearly charge: {pendingInitialPriceLabel} after a {pendingCreditPriceLabel} credit. Future yearly renewals: {pendingRecurringPriceLabel}/year."
msgstr "<0>{pendingChangeDate}</0>に年額プランへのアップグレードが予定されています。初回年額料金: {pendingCreditPriceLabel}のクレジット適用後、{pendingInitialPriceLabel}。翌年以降の年額更新料金: {pendingRecurringPriceLabel}/年。"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:610
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:626
msgid "Yearly upgrade scheduled for <0>{pendingChangeDate}</0>. First yearly charge: {pendingInitialPriceLabel}. Future yearly renewals: {pendingRecurringPriceLabel}/year."
msgstr "<0>{pendingChangeDate}</0>に年額プランへのアップグレードが予定されています。初回年額料金: {pendingInitialPriceLabel}。翌年以降の年額更新料金: {pendingRecurringPriceLabel}/年。"
@@ -39493,10 +39493,10 @@ msgid "You just pressed Tab. Keyboard mode is now on so you can navigate {produc
msgstr "Tabキーを押しましたね。キーボードモードがオンになり、マウスなしで{productName}を操作できます。"
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:137
msgid "You keep your perks until your next renewal date, then have a 3-day grace period to resubscribe and keep your subscriber history."
msgstr "特典は次回の更新日まで保持され、その後3日間の猶予期間中に再登録すると、サブスクリプション履歴を引き継ぐことができます。"
msgid "You keep your perks until your next renewal date. Reactivate before then to keep your subscriber history."
msgstr "特典は次回の更新日まで保持されます。サブスクリプション履歴を引き継ぐには、それまでに再開してください。"
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:159
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:158
msgid "You lose all {PREMIUM_PRODUCT_NAME} perks immediately and your subscriber history resets. This cannot be undone."
msgstr "{PREMIUM_PRODUCT_NAME}のすべての特典が直ちに失われ、サブスクリプション履歴がリセットされます。この操作は元に戻せません。"
@@ -40231,6 +40231,11 @@ msgstr "お住まいの地域"
msgid "Your registration needs an extra anti-spam check before you can continue."
msgstr "引き続きご利用いただくには、追加のスパム対策認証が必要です。"
#. Plutonium subscription card text shown while a failed renewal payment is being retried. {graceDate} is a date already formatted and localized by code; never write a date into the translation.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:470
msgid "Your renewal payment failed but <0/> stay active until <1>{graceDate}</1>. Update your payment method before then to keep your subscription."
msgstr "更新の支払いに失敗しましたが、<0/>は<1>{graceDate}</1>まで有効です。それまでに支払い方法を更新して、サブスクリプションを継続してください。"
#. Video settings note shown when the saved screen share quality is above what this account can send. Resolutions are short labels such as 1440p or Source and rates are whole numbers. FPS is a technical token.
#: src/features/user/components/modals/tabs/UserVideoTab.tsx:92
msgid "Your saved {savedResolution} at {savedFrameRate} FPS needs {premiumProductName}, so shares use {resolution} at {frameRate} FPS."
@@ -40252,7 +40257,7 @@ msgstr "配信は継続中です"
msgid "Your subscription can't move to the new price right now."
msgstr "現在、サブスクリプションを新しい価格に変更することはできません。"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:470
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:486
msgid "Your subscription ended but <0/> stay active until <1>{graceDate}</1>. Resubscribe before then to keep your subscriber history."
msgstr "サブスクリプションは終了しましたが、<0/>は<1>{graceDate}</1>まで有効です。それまでに再登録して、サブスクリプション履歴を保持してください。"
@@ -40281,7 +40286,7 @@ msgstr "サブスクリプションが月額請求に切り替わりました。
msgid "Your subscription has been switched to yearly billing."
msgstr "サブスクリプションが年額請求に切り替わりました。"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:512
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:528
msgid "Your subscription is active but perks are temporarily paused."
msgstr "サブスクリプションは有効ですが、特典は一時停止されています。"
@@ -40301,7 +40306,7 @@ msgid "Your subscription moves to the new price on {effectiveDate}."
msgstr "サブスクリプションは{effectiveDate}に新しい価格へ移行します。"
#. Plutonium subscription card line shown to a subscriber on a legacy price whose subscription is already set to cancel. {cancelDate} is a date and {listPriceNewLabel} is a currency amount, both already formatted and localized by code; never write a date or an amount into the translation.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:666
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:682
msgid "Your subscription still ends on <0>{cancelDate}</0>. The current price is now {listPriceNewLabel}. If you reactivate, you can switch to it from here."
msgstr "サブスクリプションは<0>{cancelDate}</0>に終了します。現在の料金は{listPriceNewLabel}です。再開すると、ここから切り替えることができます。"
@@ -2471,7 +2471,7 @@ msgid "A Linux desktop update is available. Choose the package format for this s
msgstr "Linux 데스크톱 업데이트가 있습니다. 이 시스템에 맞는 패키지 형식을 선택하면 {productName}이 파일을 로컬에 저장합니다."
#. Plutonium subscription card line offering a move to a lower price. {listPriceEffectiveDate} is a date already formatted and localized by code; never write a date into the translation.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:684
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:700
msgid "A lower price is available. Switching takes effect on <0>{listPriceEffectiveDate}</0> and changes nothing else."
msgstr "더 저렴한 가격으로 이용하실 수 있습니다. 변경 사항은 <0>{listPriceEffectiveDate}</0>부터 적용되며 다른 내용은 변경되지 않습니다."
@@ -3487,19 +3487,19 @@ msgstr "정렬 컨트롤은 더 넓은 화면에서만 사용할 수 있습니
msgid "All"
msgstr "전체"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:524
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:540
msgid "All <0/> for <1>{effectiveMonthlyPrice}/month</1>."
msgstr "모든 <0/>을 <1>월 {effectiveMonthlyPrice}</1>에 이용할 수 있습니다."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:546
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:562
msgid "All <0/> for <1>{effectiveYearlyPrice}/year</1>."
msgstr "모든 <0/>을 <1>연 {effectiveYearlyPrice}</1>에 이용할 수 있습니다."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:567
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:583
msgid "All <0/> included with your subscription."
msgstr "구독에 모든 <0/>이 포함됩니다."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:514
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:530
msgid "All <0/>, forever. No billing, no renewals."
msgstr "모든 <0/>을 평생 이용할 수 있습니다. 청구도 갱신도 없습니다."
@@ -6469,7 +6469,7 @@ msgid "Cancel import"
msgstr "가져오기 취소"
#. Billing button that cancels a scheduled move to a lower subscription price.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:821
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:837
msgid "Cancel price change"
msgstr "가격 변경 취소"
@@ -6484,14 +6484,14 @@ msgid "Cancel request"
msgstr "요청 취소"
#. Billing button that cancels a scheduled billing-cycle change.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:829
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:845
msgid "Cancel scheduled switch"
msgstr "예약된 전환 취소"
#. Billing button that starts subscription cancellation.
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:844
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:142
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:860
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:141
#: src/features/user/components/settings_utils/search_index/PlutoniumIndex.ts:31
msgid "Cancel subscription"
msgstr "구독 취소"
@@ -6501,7 +6501,7 @@ msgid "Cancel subscription?"
msgstr "구독을 취소하시겠어요?"
#. Plutonium subscription card hint shown to a subscriber who could move to a lower price but has another billing change already scheduled.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:647
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:663
msgid "Cancel the scheduled change to move to the current price instead."
msgstr "현재 가격으로 변경하려면 예약된 변경을 취소하세요."
@@ -6511,7 +6511,7 @@ msgid "Cancel upload"
msgstr "업로드 취소"
#. Billing button that cancels a scheduled yearly upgrade.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:825
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:841
msgid "Cancel yearly upgrade"
msgstr "연간 업그레이드 취소"
@@ -6530,7 +6530,7 @@ msgstr "취소 예정"
msgid "Cancellation"
msgstr "에코 제거"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:501
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:517
msgid "Cancels on <0>{cancelDate}</0>. <1/> remain active until then."
msgstr "<0>{cancelDate}</0>에 취소됩니다. <1/>은 그때까지 계속 유지됩니다."
@@ -10872,7 +10872,7 @@ msgstr "직접 지정…"
#. Billing button that opens the external customer portal.
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:750
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:766
#: src/features/user/components/settings_utils/search_index/PlutoniumIndex.ts:39
msgid "Customer portal"
msgstr "고객 포털"
@@ -13877,15 +13877,15 @@ msgid "End date"
msgstr "종료일"
#. Billing button that ends premium grace period immediately.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:856
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:872
msgid "End grace now"
msgstr "유예 기간 지금 종료"
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:164
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:163
msgid "End grace period"
msgstr "유예 기간 종료"
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:157
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:156
msgid "End grace period now?"
msgstr "유예 기간을 지금 종료할까요?"
@@ -16347,7 +16347,7 @@ msgstr "선물: 곧 만료"
msgid "Gift: grace period (still have access)"
msgstr "선물: 유예 기간(계속 이용 가능)"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:486
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:502
msgid "Gifted <0/> until <1>{giftEndDate}</1>. Does not renew automatically. Redeem more gift codes to extend."
msgstr "<0/>을 선물로 받아 <1>{giftEndDate}</1>까지 이용할 수 있습니다. 자동 갱신되지 않습니다. 선물 코드를 더 사용하면 기간을 연장할 수 있습니다."
@@ -16826,7 +16826,7 @@ msgid "Hate speech"
msgstr "혐오 발언"
#. Premium page text shown on an instance where the premium tier cannot be bought, only redeemed. {PREMIUM_PRODUCT_NAME} is the premium tier name.
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:297
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:296
msgid "Have a gift code? Redeem it to unlock {PREMIUM_PRODUCT_NAME}."
msgstr "선물 코드가 있으신가요? {PREMIUM_PRODUCT_NAME}을(를) 잠금 해제하려면 코드를 사용하세요."
@@ -18926,7 +18926,7 @@ msgstr "편집 내용을 지울 때 첨부 파일 유지"
msgid "Keep free and premium tiers. You can customize the tiers, sell premium through Stripe, or hand out gift codes later from the admin panel."
msgstr "무료 및 프리미엄 등급을 유지하세요. 등급을 맞춤 설정하거나, Stripe를 통해 프리미엄을 판매하거나, 나중에 관리자 패널에서 선물 코드를 배포할 수 있습니다."
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:166
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:165
msgid "Keep grace period"
msgstr "유예 기간 유지"
@@ -18940,7 +18940,7 @@ msgstr "네코 고정하기"
msgid "Keep running"
msgstr "계속 실행"
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:144
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:143
msgid "Keep subscription"
msgstr "구독 유지"
@@ -19297,8 +19297,8 @@ msgstr "마우스 왼쪽 버튼"
msgid "Left tooltip"
msgstr "왼쪽 툴팁"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:539
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:561
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:555
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:577
msgid "Legacy rate"
msgstr "기존 요금"
@@ -21339,11 +21339,11 @@ msgstr "월간"
msgid "Monthly {monthlyPrice}"
msgstr "월 {monthlyPrice}"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:631
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:647
msgid "Monthly billing starts on <0>{pendingChangeDate}</0>."
msgstr "월별 요금 청구는 <0>{pendingChangeDate}</0>에 시작됩니다."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:624
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:640
msgid "Monthly billing starts on <0>{pendingChangeDate}</0>. First monthly charge: {pendingInitialPriceLabel}. Future monthly renewals: {pendingRecurringPriceLabel}/month."
msgstr "<0>{pendingChangeDate}</0>부터 월별 요금이 청구됩니다. 첫 월별 요금: {pendingInitialPriceLabel}. 이후 월별 갱신 요금: 월 {pendingRecurringPriceLabel}."
@@ -22269,12 +22269,12 @@ msgid "New password"
msgstr "새 비밀번호"
#. Plutonium subscription card line shown when a move to a lower price is scheduled but the new amount is unknown. {pendingChangeDate} is a date already formatted and localized by code; never write a date into the translation.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:595
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:611
msgid "New price scheduled for <0>{pendingChangeDate}</0>."
msgstr "새 가격이 <0>{pendingChangeDate}</0>에 적용될 예정입니다."
#. Plutonium subscription card line shown when a move to a lower price is scheduled. {pendingChangeDate} is a date and {pendingTargetPriceLabel} is a currency amount, both already formatted and localized by code; never write a date or an amount into the translation.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:589
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:605
msgid "New price scheduled for <0>{pendingChangeDate}</0>. Renewals will be {pendingTargetPriceLabel} from then on."
msgstr "새 가격이 <0>{pendingChangeDate}</0>에 적용될 예정입니다. 이후 갱신 금액은 {pendingTargetPriceLabel}입니다."
@@ -26152,7 +26152,7 @@ msgstr "반응"
#. Billing button that cancels a scheduled subscription cancellation.
#. Button label on the premium-expired nagbar. Opens billing so the user can reactivate their subscription.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:746
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:762
#: src/features/app/components/layout/app_layout/nagbars/PremiumExpiredNagbar.tsx:25
msgid "Reactivate"
msgstr "재활성화"
@@ -26375,8 +26375,8 @@ msgstr "내 계정으로 사용"
#. Billing button for entering a premium gift code.
#. Billing button for entering a premium gift code.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:719
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:307
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:735
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:306
msgid "Redeem gift code"
msgstr "선물 코드 사용"
@@ -27147,7 +27147,7 @@ msgstr "갱신 임계값(일)"
msgid "Renew window (days)"
msgstr "갱신 기간(일)"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:701
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:717
msgid "Renews on <0>{renewalDate}.</0>"
msgstr "<0>{renewalDate}</0>에 갱신됩니다."
@@ -27896,8 +27896,8 @@ msgstr "창 복원"
#. Billing button for restarting a subscription during the grace period.
#. Billing button for starting a new subscription after premium expired.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:738
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:742
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:754
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:758
msgid "Resubscribe"
msgstr "재구독"
@@ -32521,7 +32521,7 @@ msgid "Switch price"
msgstr "가격 변경"
#. Billing button that opens confirmation to move the subscription down to the current price. {listPriceNewLabel} is the localized new price.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:806
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:822
msgid "Switch to {listPriceNewLabel}"
msgstr "{listPriceNewLabel}(으)로 전환"
@@ -32546,7 +32546,7 @@ msgstr "직접 입력으로 전환"
#. Billing button that opens confirmation to switch to monthly billing.
#. Button confirming a change to monthly subscription billing.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:57
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:789
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:805
msgid "Switch to monthly"
msgstr "월간으로 전환"
@@ -32615,7 +32615,7 @@ msgstr "2열로 전환"
#. Billing button that opens confirmation to switch to yearly billing.
#. Button confirming a change to yearly subscription billing.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:53
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:785
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:801
msgid "Switch to yearly"
msgstr "연간으로 전환"
@@ -35865,7 +35865,7 @@ msgstr "{premiumProductName}으로 DM에서 맞춤 이모티콘을 잠금 해제
msgid "Unlock HD screen share with {premiumProductName}"
msgstr "{premiumProductName}으로 HD 화면 공유를 잠금 해제하세요"
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:217
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:216
msgid "Unlock higher limits and exclusive features while supporting an independent communication platform."
msgstr "독립적인 커뮤니케이션 플랫폼을 후원하면서 더 높은 한도와 전용 기능을 이용해 보세요."
@@ -39015,15 +39015,15 @@ msgstr "연간 {yearlyPrice}"
msgid "Yearly gift"
msgstr "연간 선물"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:618
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:634
msgid "Yearly upgrade scheduled for <0>{pendingChangeDate}</0>."
msgstr "<0>{pendingChangeDate}</0>에 연간 업그레이드가 예정되어 있습니다."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:603
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:619
msgid "Yearly upgrade scheduled for <0>{pendingChangeDate}</0>. First yearly charge: {pendingInitialPriceLabel} after a {pendingCreditPriceLabel} credit. Future yearly renewals: {pendingRecurringPriceLabel}/year."
msgstr "<0>{pendingChangeDate}</0>에 연간 업그레이드가 예정되어 있습니다. 첫 연간 요금: {pendingCreditPriceLabel} 크레딧 적용 후 {pendingInitialPriceLabel}. 향후 연간 갱신 요금: 연간 {pendingRecurringPriceLabel}."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:610
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:626
msgid "Yearly upgrade scheduled for <0>{pendingChangeDate}</0>. First yearly charge: {pendingInitialPriceLabel}. Future yearly renewals: {pendingRecurringPriceLabel}/year."
msgstr "<0>{pendingChangeDate}</0>에 연간 업그레이드가 예정되어 있습니다. 첫 연간 요금: {pendingInitialPriceLabel}. 향후 연간 갱신 요금: 연간 {pendingRecurringPriceLabel}."
@@ -39493,10 +39493,10 @@ msgid "You just pressed Tab. Keyboard mode is now on so you can navigate {produc
msgstr "Tab 키를 누르셨습니다. 이제 키보드 모드가 켜져 마우스 없이 {productName}을(를) 탐색할 수 있습니다."
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:137
msgid "You keep your perks until your next renewal date, then have a 3-day grace period to resubscribe and keep your subscriber history."
msgstr "다음 갱신일까지 혜택이 유지되며, 3일의 유예 기간 동안 재구독하여 구독 기록을 유지할 수 있습니다."
msgid "You keep your perks until your next renewal date. Reactivate before then to keep your subscriber history."
msgstr "다음 갱신일까지 혜택이 유지됩니다. 구독 기록을 유지하려면 그 전에 재활성화하세요."
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:159
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:158
msgid "You lose all {PREMIUM_PRODUCT_NAME} perks immediately and your subscriber history resets. This cannot be undone."
msgstr "모든 {PREMIUM_PRODUCT_NAME} 혜택이 즉시 사라지며 구독 기록이 초기화됩니다. 이 작업은 되돌릴 수 없습니다."
@@ -40231,6 +40231,11 @@ msgstr "현재 지역"
msgid "Your registration needs an extra anti-spam check before you can continue."
msgstr "가입을 계속하려면 추가 스팸 방지 확인이 필요합니다."
#. Plutonium subscription card text shown while a failed renewal payment is being retried. {graceDate} is a date already formatted and localized by code; never write a date into the translation.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:470
msgid "Your renewal payment failed but <0/> stay active until <1>{graceDate}</1>. Update your payment method before then to keep your subscription."
msgstr "갱신 결제에 실패했지만 <0/>은 <1>{graceDate}</1>까지 계속 활성 상태입니다. 구독을 유지하려면 그 전에 결제 수단을 업데이트하세요."
#. Video settings note shown when the saved screen share quality is above what this account can send. Resolutions are short labels such as 1440p or Source and rates are whole numbers. FPS is a technical token.
#: src/features/user/components/modals/tabs/UserVideoTab.tsx:92
msgid "Your saved {savedResolution} at {savedFrameRate} FPS needs {premiumProductName}, so shares use {resolution} at {frameRate} FPS."
@@ -40252,7 +40257,7 @@ msgstr "회원님의 스트림은 계속 라이브 상태입니다"
msgid "Your subscription can't move to the new price right now."
msgstr "지금은 구독을 새 가격으로 변경할 수 없습니다."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:470
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:486
msgid "Your subscription ended but <0/> stay active until <1>{graceDate}</1>. Resubscribe before then to keep your subscriber history."
msgstr "구독이 종료되었지만 <0/>은 <1>{graceDate}</1>까지 계속 활성 상태입니다. 구독 기록을 유지하려면 그 전에 다시 구독하세요."
@@ -40281,7 +40286,7 @@ msgstr "구독이 월간 결제로 전환되었습니다."
msgid "Your subscription has been switched to yearly billing."
msgstr "구독이 연간 결제로 전환되었습니다."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:512
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:528
msgid "Your subscription is active but perks are temporarily paused."
msgstr "구독은 활성 상태이지만 혜택이 일시적으로 중지되었습니다."
@@ -40301,7 +40306,7 @@ msgid "Your subscription moves to the new price on {effectiveDate}."
msgstr "구독이 {effectiveDate}에 새로운 가격으로 변경됩니다."
#. Plutonium subscription card line shown to a subscriber on a legacy price whose subscription is already set to cancel. {cancelDate} is a date and {listPriceNewLabel} is a currency amount, both already formatted and localized by code; never write a date or an amount into the translation.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:666
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:682
msgid "Your subscription still ends on <0>{cancelDate}</0>. The current price is now {listPriceNewLabel}. If you reactivate, you can switch to it from here."
msgstr "구독은 <0>{cancelDate}</0>에 종료됩니다. 현재 가격은 {listPriceNewLabel}입니다. 다시 활성화하면 여기서 전환할 수 있습니다."
@@ -2471,7 +2471,7 @@ msgid "A Linux desktop update is available. Choose the package format for this s
msgstr "Prieinamas „Linux“ darbalaukio atnaujinimas. Pasirinkite šios sistemos paketų formatą, o programa „{productName}“ išsaugos jį jūsų įrenginyje."
#. Plutonium subscription card line offering a move to a lower price. {listPriceEffectiveDate} is a date already formatted and localized by code; never write a date into the translation.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:684
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:700
msgid "A lower price is available. Switching takes effect on <0>{listPriceEffectiveDate}</0> and changes nothing else."
msgstr "Galima rinktis mažesnę kainą. Pakeitimai įsigalios <0>{listPriceEffectiveDate}</0>, ir niekas kitas nesikeis."
@@ -3487,19 +3487,19 @@ msgstr "Lygiavimo valdikliai pasiekiami tik platesniuose ekranuose"
msgid "All"
msgstr "Visi"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:524
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:540
msgid "All <0/> for <1>{effectiveMonthlyPrice}/month</1>."
msgstr "Viskas <0/> už <1>{effectiveMonthlyPrice}/mėn.</1>."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:546
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:562
msgid "All <0/> for <1>{effectiveYearlyPrice}/year</1>."
msgstr "Viskas <0/> už <1>{effectiveYearlyPrice}/metus</1>."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:567
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:583
msgid "All <0/> included with your subscription."
msgstr "Viskas <0/> įskaičiuota į jūsų prenumeratą."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:514
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:530
msgid "All <0/>, forever. No billing, no renewals."
msgstr "Viskas <0/>, amžinai. Jokių sąskaitų, jokių atnaujinimų."
@@ -6469,7 +6469,7 @@ msgid "Cancel import"
msgstr "Atšaukti importavimą"
#. Billing button that cancels a scheduled move to a lower subscription price.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:821
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:837
msgid "Cancel price change"
msgstr "Atšaukti kainos pakeitimą"
@@ -6484,14 +6484,14 @@ msgid "Cancel request"
msgstr "Atšaukti užklausą"
#. Billing button that cancels a scheduled billing-cycle change.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:829
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:845
msgid "Cancel scheduled switch"
msgstr "Atšaukti suplanuotą keitimą"
#. Billing button that starts subscription cancellation.
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:844
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:142
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:860
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:141
#: src/features/user/components/settings_utils/search_index/PlutoniumIndex.ts:31
msgid "Cancel subscription"
msgstr "Atšaukti prenumeratą"
@@ -6501,7 +6501,7 @@ msgid "Cancel subscription?"
msgstr "Atšaukti prenumeratą?"
#. Plutonium subscription card hint shown to a subscriber who could move to a lower price but has another billing change already scheduled.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:647
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:663
msgid "Cancel the scheduled change to move to the current price instead."
msgstr "Atšaukti suplanuotą pakeitimą ir pereiti prie dabartinės kainos."
@@ -6511,7 +6511,7 @@ msgid "Cancel upload"
msgstr "Atšaukti įkėlimą"
#. Billing button that cancels a scheduled yearly upgrade.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:825
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:841
msgid "Cancel yearly upgrade"
msgstr "Atšaukti metinį atnaujinimą"
@@ -6530,7 +6530,7 @@ msgstr "Atšaukiama"
msgid "Cancellation"
msgstr "Aido slopinimas"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:501
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:517
msgid "Cancels on <0>{cancelDate}</0>. <1/> remain active until then."
msgstr "Atšaukiama <0>{cancelDate}</0>. <1/> liks aktyvios iki tol."
@@ -10872,7 +10872,7 @@ msgstr "Pasirinktinis…"
#. Billing button that opens the external customer portal.
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:750
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:766
#: src/features/user/components/settings_utils/search_index/PlutoniumIndex.ts:39
msgid "Customer portal"
msgstr "Klientų portalas"
@@ -13877,15 +13877,15 @@ msgid "End date"
msgstr "Pabaigos data"
#. Billing button that ends premium grace period immediately.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:856
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:872
msgid "End grace now"
msgstr "Baigti lengvatinį laikotarpį dabar"
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:164
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:163
msgid "End grace period"
msgstr "Baigti lengvatinį laikotarpį"
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:157
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:156
msgid "End grace period now?"
msgstr "Baigti lengvatinį laikotarpį dabar?"
@@ -16347,7 +16347,7 @@ msgstr "Dovana: galiojimas baigsis netrukus"
msgid "Gift: grace period (still have access)"
msgstr "Dovana: lengvatinis laikotarpis (vis dar turite prieigą)"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:486
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:502
msgid "Gifted <0/> until <1>{giftEndDate}</1>. Does not renew automatically. Redeem more gift codes to extend."
msgstr "Dovanota <0/> iki <1>{giftEndDate}</1>. Automatiškai nepratęsiama. Norėdami pratęsti, išpirkite daugiau dovanų kodų."
@@ -16826,7 +16826,7 @@ msgid "Hate speech"
msgstr "Neapykantos kalba"
#. Premium page text shown on an instance where the premium tier cannot be bought, only redeemed. {PREMIUM_PRODUCT_NAME} is the premium tier name.
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:297
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:296
msgid "Have a gift code? Redeem it to unlock {PREMIUM_PRODUCT_NAME}."
msgstr "Turite dovanų kodą? Aktyvuokite jį, kad atrakintumėte {PREMIUM_PRODUCT_NAME}."
@@ -16920,7 +16920,8 @@ msgstr "Pagalbos centras"
#. Settings search entry description. One-line summary of what the setting controls.
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:102
msgid "Help center button in the sidebar"
msgstr "My suggestion:\nPagalbos centro mygtukas šoninėje juostoje"
msgstr "My suggestion:\n"
"Pagalbos centro mygtukas šoninėje juostoje"
#: src/features/user/components/modals/tabs/LanguageTab.tsx:348
msgid "Help translate {PRODUCT_NAME} into your language on <0>{I18N_WEBLATE_DOMAIN}</0>."
@@ -18926,7 +18927,7 @@ msgstr "Išsaugoti priedus išvalius redagavimą"
msgid "Keep free and premium tiers. You can customize the tiers, sell premium through Stripe, or hand out gift codes later from the admin panel."
msgstr "Pasilikite nemokamą ir mokamą lygius. Vėliau galėsite tinkinti lygius, parduoti mokamą turinį per „Stripe“ arba dalyti dovanų kodus iš administratoriaus skydelio."
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:166
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:165
msgid "Keep grace period"
msgstr "Palikti lengvatinį laikotarpį"
@@ -18940,7 +18941,7 @@ msgstr "Neleisti Neko judėti"
msgid "Keep running"
msgstr "Palikti veikti"
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:144
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:143
msgid "Keep subscription"
msgstr "Palikti prenumeratą"
@@ -19297,8 +19298,8 @@ msgstr "Kairysis pelės mygtukas"
msgid "Left tooltip"
msgstr "Kairysis patarimas"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:539
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:561
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:555
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:577
msgid "Legacy rate"
msgstr "Senasis tarifas"
@@ -21339,11 +21340,11 @@ msgstr "Mėnesinis"
msgid "Monthly {monthlyPrice}"
msgstr "Mėnesiui {monthlyPrice}"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:631
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:647
msgid "Monthly billing starts on <0>{pendingChangeDate}</0>."
msgstr "Mėnesinis atsiskaitymas prasidės <0>{pendingChangeDate}</0>."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:624
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:640
msgid "Monthly billing starts on <0>{pendingChangeDate}</0>. First monthly charge: {pendingInitialPriceLabel}. Future monthly renewals: {pendingRecurringPriceLabel}/month."
msgstr "Mėnesinis atsiskaitymas prasidės <0>{pendingChangeDate}</0>. Pirmasis mėnesinis mokestis: {pendingInitialPriceLabel}. Būsimi mėnesiniai atnaujinimai: {pendingRecurringPriceLabel}/mėn."
@@ -22269,12 +22270,12 @@ msgid "New password"
msgstr "Naujas slaptažodis"
#. Plutonium subscription card line shown when a move to a lower price is scheduled but the new amount is unknown. {pendingChangeDate} is a date already formatted and localized by code; never write a date into the translation.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:595
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:611
msgid "New price scheduled for <0>{pendingChangeDate}</0>."
msgstr "Nauja kaina numatyta <0>{pendingChangeDate}</0>."
#. Plutonium subscription card line shown when a move to a lower price is scheduled. {pendingChangeDate} is a date and {pendingTargetPriceLabel} is a currency amount, both already formatted and localized by code; never write a date or an amount into the translation.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:589
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:605
msgid "New price scheduled for <0>{pendingChangeDate}</0>. Renewals will be {pendingTargetPriceLabel} from then on."
msgstr "Nauja kaina numatyta <0>{pendingChangeDate}</0>. Nuo tada atnaujinimai kainuos {pendingTargetPriceLabel}."
@@ -26152,7 +26153,7 @@ msgstr "Reakcijos"
#. Billing button that cancels a scheduled subscription cancellation.
#. Button label on the premium-expired nagbar. Opens billing so the user can reactivate their subscription.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:746
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:762
#: src/features/app/components/layout/app_layout/nagbars/PremiumExpiredNagbar.tsx:25
msgid "Reactivate"
msgstr "Suaktyvinti iš naujo"
@@ -26375,8 +26376,8 @@ msgstr "Išpirkti sau"
#. Billing button for entering a premium gift code.
#. Billing button for entering a premium gift code.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:719
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:307
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:735
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:306
msgid "Redeem gift code"
msgstr "Išpirkti dovanos kodą"
@@ -27147,7 +27148,7 @@ msgstr "Atnaujinimo riba (dienos)"
msgid "Renew window (days)"
msgstr "Atnaujinimo laikotarpis (dienos)"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:701
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:717
msgid "Renews on <0>{renewalDate}.</0>"
msgstr "Atnaujinama <0>{renewalDate}.</0>"
@@ -27896,8 +27897,8 @@ msgstr "Atkurti langą"
#. Billing button for restarting a subscription during the grace period.
#. Billing button for starting a new subscription after premium expired.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:738
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:742
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:754
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:758
msgid "Resubscribe"
msgstr "Prenumeruoti iš naujo"
@@ -32521,7 +32522,7 @@ msgid "Switch price"
msgstr "Keisti kainą"
#. Billing button that opens confirmation to move the subscription down to the current price. {listPriceNewLabel} is the localized new price.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:806
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:822
msgid "Switch to {listPriceNewLabel}"
msgstr "Pereiti prie {listPriceNewLabel}"
@@ -32546,7 +32547,7 @@ msgstr "Perjungti į tiesioginį įvedimą"
#. Billing button that opens confirmation to switch to monthly billing.
#. Button confirming a change to monthly subscription billing.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:57
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:789
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:805
msgid "Switch to monthly"
msgstr "Pereiti prie mėnesinio plano"
@@ -32615,7 +32616,7 @@ msgstr "Perjungti į du stulpelius"
#. Billing button that opens confirmation to switch to yearly billing.
#. Button confirming a change to yearly subscription billing.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:53
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:785
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:801
msgid "Switch to yearly"
msgstr "Pereiti prie metinio plano"
@@ -35865,7 +35866,7 @@ msgstr "Atrakinkite pasirinktinius jaustukus DM pokalbiuose su „{premiumProduc
msgid "Unlock HD screen share with {premiumProductName}"
msgstr "Atrakinkite HD ekrano bendrinimą su „{premiumProductName}“"
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:217
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:216
msgid "Unlock higher limits and exclusive features while supporting an independent communication platform."
msgstr "Atrakinkite didesnius limitus ir išskirtines funkcijas, kartu palaikydami nepriklausomą komunikacijos platformą."
@@ -39015,15 +39016,15 @@ msgstr "Metinis {yearlyPrice}"
msgid "Yearly gift"
msgstr "Metinė dovana"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:618
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:634
msgid "Yearly upgrade scheduled for <0>{pendingChangeDate}</0>."
msgstr "Metinis atnaujinimas suplanuotas <0>{pendingChangeDate}</0>."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:603
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:619
msgid "Yearly upgrade scheduled for <0>{pendingChangeDate}</0>. First yearly charge: {pendingInitialPriceLabel} after a {pendingCreditPriceLabel} credit. Future yearly renewals: {pendingRecurringPriceLabel}/year."
msgstr "Metinis atnaujinimas suplanuotas <0>{pendingChangeDate}</0>. Pirmasis metinis mokestis: {pendingInitialPriceLabel} po {pendingCreditPriceLabel} kredito. Būsimi metiniai atnaujinimai: {pendingRecurringPriceLabel} per metus."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:610
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:626
msgid "Yearly upgrade scheduled for <0>{pendingChangeDate}</0>. First yearly charge: {pendingInitialPriceLabel}. Future yearly renewals: {pendingRecurringPriceLabel}/year."
msgstr "Metinis atnaujinimas suplanuotas <0>{pendingChangeDate}</0>. Pirmasis metinis mokestis: {pendingInitialPriceLabel}. Būsimi metiniai atnaujinimai: {pendingRecurringPriceLabel} per metus."
@@ -39493,10 +39494,10 @@ msgid "You just pressed Tab. Keyboard mode is now on so you can navigate {produc
msgstr "Ką tik paspaudėte „Tab“. Įjungtas klaviatūros režimas, kad galėtumėte naršyti {productName} be pelės."
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:137
msgid "You keep your perks until your next renewal date, then have a 3-day grace period to resubscribe and keep your subscriber history."
msgstr "Privilegijas išsaugosite iki kito atnaujinimo datos, o tada turėsite 3 dienų pereinamąjį laikotarpį, kad vėl užsiprenumeruotumėte ir išsaugotumėte prenumeratos istoriją."
msgid "You keep your perks until your next renewal date. Reactivate before then to keep your subscriber history."
msgstr "Privilegijas išsaugosite iki kito atnaujinimo datos. Suaktyvinkite prenumeratą iš naujo iki tol, kad išsaugotumėte prenumeratos istoriją."
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:159
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:158
msgid "You lose all {PREMIUM_PRODUCT_NAME} perks immediately and your subscriber history resets. This cannot be undone."
msgstr "Iškart prarasite visas „{PREMIUM_PRODUCT_NAME}“ privilegijas, o jūsų prenumeratos istorija bus nustatyta iš naujo. Šio veiksmo anuliuoti negalima."
@@ -40231,6 +40232,11 @@ msgstr "jūsų regionas"
msgid "Your registration needs an extra anti-spam check before you can continue."
msgstr "Prieš tęsiant, jūsų registracijai reikalingas papildomas apsaugos nuo brukalų patikrinimas."
#. Plutonium subscription card text shown while a failed renewal payment is being retried. {graceDate} is a date already formatted and localized by code; never write a date into the translation.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:470
msgid "Your renewal payment failed but <0/> stay active until <1>{graceDate}</1>. Update your payment method before then to keep your subscription."
msgstr "Prenumeratos atnaujinimo mokėjimas nepavyko, bet <0/> liks aktyvios iki <1>{graceDate}</1>. Iki tol atnaujinkite mokėjimo būdą, kad išsaugotumėte prenumeratą."
#. Video settings note shown when the saved screen share quality is above what this account can send. Resolutions are short labels such as 1440p or Source and rates are whole numbers. FPS is a technical token.
#: src/features/user/components/modals/tabs/UserVideoTab.tsx:92
msgid "Your saved {savedResolution} at {savedFrameRate} FPS needs {premiumProductName}, so shares use {resolution} at {frameRate} FPS."
@@ -40252,7 +40258,7 @@ msgstr "Jūsų transliacija vis dar aktyvi"
msgid "Your subscription can't move to the new price right now."
msgstr "Jūsų prenumeratos šiuo metu negalima perkelti į naują kainą."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:470
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:486
msgid "Your subscription ended but <0/> stay active until <1>{graceDate}</1>. Resubscribe before then to keep your subscriber history."
msgstr "Jūsų prenumerata baigėsi, bet <0/> liks aktyvios iki <1>{graceDate}</1>. Prenumeruokite iš naujo iki tol, kad išsaugotumėte prenumeratoriaus istoriją."
@@ -40281,7 +40287,7 @@ msgstr "Jūsų prenumerata pakeista į mėnesinį atsiskaitymą."
msgid "Your subscription has been switched to yearly billing."
msgstr "Jūsų prenumerata pakeista į metinį atsiskaitymą."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:512
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:528
msgid "Your subscription is active but perks are temporarily paused."
msgstr "Jūsų prenumerata aktyvi, bet privilegijos laikinai pristabdytos."
@@ -40301,7 +40307,7 @@ msgid "Your subscription moves to the new price on {effectiveDate}."
msgstr "Jūsų prenumerata į naują kainą persikels {effectiveDate}."
#. Plutonium subscription card line shown to a subscriber on a legacy price whose subscription is already set to cancel. {cancelDate} is a date and {listPriceNewLabel} is a currency amount, both already formatted and localized by code; never write a date or an amount into the translation.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:666
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:682
msgid "Your subscription still ends on <0>{cancelDate}</0>. The current price is now {listPriceNewLabel}. If you reactivate, you can switch to it from here."
msgstr "Jūsų prenumerata vis tiek baigsis <0>{cancelDate}</0>. Dabartinė kaina yra {listPriceNewLabel}. Jei aktyvuosite iš naujo, čia galėsite prie jos pereiti."
@@ -2471,7 +2471,7 @@ msgid "A Linux desktop update is available. Choose the package format for this s
msgstr "Er is een Linux-desktopupdate beschikbaar. Kies het pakketformaat voor dit systeem, en {productName} zal het lokaal opslaan."
#. Plutonium subscription card line offering a move to a lower price. {listPriceEffectiveDate} is a date already formatted and localized by code; never write a date into the translation.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:684
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:700
msgid "A lower price is available. Switching takes effect on <0>{listPriceEffectiveDate}</0> and changes nothing else."
msgstr "Een lagere prijs is beschikbaar. De wijziging gaat in op <0>{listPriceEffectiveDate}</0> en verandert verder niets."
@@ -3487,19 +3487,19 @@ msgstr "Uitlijningsopties zijn alleen beschikbaar op bredere schermen"
msgid "All"
msgstr "Alles"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:524
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:540
msgid "All <0/> for <1>{effectiveMonthlyPrice}/month</1>."
msgstr "Alle <0/> voor <1>{effectiveMonthlyPrice}/maand</1>."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:546
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:562
msgid "All <0/> for <1>{effectiveYearlyPrice}/year</1>."
msgstr "Alle <0/> voor <1>{effectiveYearlyPrice}/jaar</1>."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:567
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:583
msgid "All <0/> included with your subscription."
msgstr "Alle <0/> inbegrepen bij je abonnement."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:514
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:530
msgid "All <0/>, forever. No billing, no renewals."
msgstr "Alle <0/>, voor altijd. Geen facturering, geen verlengingen."
@@ -6469,7 +6469,7 @@ msgid "Cancel import"
msgstr "Importeren annuleren"
#. Billing button that cancels a scheduled move to a lower subscription price.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:821
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:837
msgid "Cancel price change"
msgstr "Prijswijziging annuleren"
@@ -6484,14 +6484,14 @@ msgid "Cancel request"
msgstr "Verzoek annuleren"
#. Billing button that cancels a scheduled billing-cycle change.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:829
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:845
msgid "Cancel scheduled switch"
msgstr "Geplande wijziging annuleren"
#. Billing button that starts subscription cancellation.
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:844
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:142
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:860
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:141
#: src/features/user/components/settings_utils/search_index/PlutoniumIndex.ts:31
msgid "Cancel subscription"
msgstr "Abonnement opzeggen"
@@ -6501,7 +6501,7 @@ msgid "Cancel subscription?"
msgstr "Abonnement opzeggen?"
#. Plutonium subscription card hint shown to a subscriber who could move to a lower price but has another billing change already scheduled.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:647
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:663
msgid "Cancel the scheduled change to move to the current price instead."
msgstr "Annuleer de geplande wijziging om in plaats daarvan naar de huidige prijs te gaan."
@@ -6511,7 +6511,7 @@ msgid "Cancel upload"
msgstr "Upload annuleren"
#. Billing button that cancels a scheduled yearly upgrade.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:825
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:841
msgid "Cancel yearly upgrade"
msgstr "Upgrade naar jaarabonnement annuleren"
@@ -6530,7 +6530,7 @@ msgstr "Opzegging gepland"
msgid "Cancellation"
msgstr "Echo-onderdrukking"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:501
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:517
msgid "Cancels on <0>{cancelDate}</0>. <1/> remain active until then."
msgstr "Eindigt op <0>{cancelDate}</0>. <1/> blijven tot die tijd actief."
@@ -10872,7 +10872,7 @@ msgstr "Aangepast…"
#. Billing button that opens the external customer portal.
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:750
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:766
#: src/features/user/components/settings_utils/search_index/PlutoniumIndex.ts:39
msgid "Customer portal"
msgstr "Klantenportaal"
@@ -13877,15 +13877,15 @@ msgid "End date"
msgstr "Einddatum"
#. Billing button that ends premium grace period immediately.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:856
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:872
msgid "End grace now"
msgstr "Respijtperiode nu beëindigen"
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:164
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:163
msgid "End grace period"
msgstr "Respijtperiode beëindigen"
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:157
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:156
msgid "End grace period now?"
msgstr "Respijtperiode nu beëindigen?"
@@ -16347,7 +16347,7 @@ msgstr "Cadeau: verloopt binnenkort"
msgid "Gift: grace period (still have access)"
msgstr "Cadeau: respijtperiode (nog steeds toegang)"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:486
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:502
msgid "Gifted <0/> until <1>{giftEndDate}</1>. Does not renew automatically. Redeem more gift codes to extend."
msgstr "Je <0/> zijn dankzij een cadeau actief tot <1>{giftEndDate}</1>. Je abonnement wordt niet automatisch verlengd. Wissel meer cadeaucodes in om te verlengen."
@@ -16826,7 +16826,7 @@ msgid "Hate speech"
msgstr "Haatzaaierij"
#. Premium page text shown on an instance where the premium tier cannot be bought, only redeemed. {PREMIUM_PRODUCT_NAME} is the premium tier name.
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:297
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:296
msgid "Have a gift code? Redeem it to unlock {PREMIUM_PRODUCT_NAME}."
msgstr "Heb je een cadeaubon? Wissel deze in om {PREMIUM_PRODUCT_NAME} te ontgrendelen."
@@ -18926,7 +18926,7 @@ msgstr "Bijlagen behouden wanneer je de tekst van een bewerkt bericht wist"
msgid "Keep free and premium tiers. You can customize the tiers, sell premium through Stripe, or hand out gift codes later from the admin panel."
msgstr "Houd gratis en premium niveaus aan. Je kunt de niveaus aanpassen, premium verkopen via Stripe, of later cadeaucodes uitdelen vanuit het adminpaneel."
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:166
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:165
msgid "Keep grace period"
msgstr "Respijtperiode behouden"
@@ -18940,7 +18940,7 @@ msgstr "Neko stilhouden"
msgid "Keep running"
msgstr "Actief blijven"
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:144
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:143
msgid "Keep subscription"
msgstr "Abonnement behouden"
@@ -19297,8 +19297,8 @@ msgstr "Linkermuisknop"
msgid "Left tooltip"
msgstr "Tooltip links"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:539
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:561
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:555
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:577
msgid "Legacy rate"
msgstr "Oud tarief"
@@ -21339,11 +21339,11 @@ msgstr "Maandelijks"
msgid "Monthly {monthlyPrice}"
msgstr "Maandelijks {monthlyPrice}"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:631
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:647
msgid "Monthly billing starts on <0>{pendingChangeDate}</0>."
msgstr "Maandelijkse facturering start op <0>{pendingChangeDate}</0>."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:624
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:640
msgid "Monthly billing starts on <0>{pendingChangeDate}</0>. First monthly charge: {pendingInitialPriceLabel}. Future monthly renewals: {pendingRecurringPriceLabel}/month."
msgstr "Maandelijkse facturering start op <0>{pendingChangeDate}</0>. Eerste maandelijkse kosten: {pendingInitialPriceLabel}. Toekomstige maandelijkse verlengingen: {pendingRecurringPriceLabel}/maand."
@@ -22269,12 +22269,12 @@ msgid "New password"
msgstr "Nieuw wachtwoord"
#. Plutonium subscription card line shown when a move to a lower price is scheduled but the new amount is unknown. {pendingChangeDate} is a date already formatted and localized by code; never write a date into the translation.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:595
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:611
msgid "New price scheduled for <0>{pendingChangeDate}</0>."
msgstr "Nieuwe prijs gepland voor <0>{pendingChangeDate}</0>."
#. Plutonium subscription card line shown when a move to a lower price is scheduled. {pendingChangeDate} is a date and {pendingTargetPriceLabel} is a currency amount, both already formatted and localized by code; never write a date or an amount into the translation.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:589
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:605
msgid "New price scheduled for <0>{pendingChangeDate}</0>. Renewals will be {pendingTargetPriceLabel} from then on."
msgstr "Nieuwe prijs gepland voor <0>{pendingChangeDate}</0>. Verlengingen kosten vanaf dan {pendingTargetPriceLabel}."
@@ -26152,7 +26152,7 @@ msgstr "Reacties"
#. Billing button that cancels a scheduled subscription cancellation.
#. Button label on the premium-expired nagbar. Opens billing so the user can reactivate their subscription.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:746
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:762
#: src/features/app/components/layout/app_layout/nagbars/PremiumExpiredNagbar.tsx:25
msgid "Reactivate"
msgstr "Opnieuw activeren"
@@ -26375,8 +26375,8 @@ msgstr "Voor jezelf inwisselen"
#. Billing button for entering a premium gift code.
#. Billing button for entering a premium gift code.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:719
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:307
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:735
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:306
msgid "Redeem gift code"
msgstr "Cadeaucode inwisselen"
@@ -27147,7 +27147,7 @@ msgstr "Vernieuwingsdrempel (dagen)"
msgid "Renew window (days)"
msgstr "Vernieuwingsperiode (dagen)"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:701
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:717
msgid "Renews on <0>{renewalDate}.</0>"
msgstr "Wordt verlengd op <0>{renewalDate}.</0>"
@@ -27896,8 +27896,8 @@ msgstr "Venster herstellen"
#. Billing button for restarting a subscription during the grace period.
#. Billing button for starting a new subscription after premium expired.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:738
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:742
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:754
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:758
msgid "Resubscribe"
msgstr "Opnieuw abonneren"
@@ -32521,7 +32521,7 @@ msgid "Switch price"
msgstr "Prijs wijzigen"
#. Billing button that opens confirmation to move the subscription down to the current price. {listPriceNewLabel} is the localized new price.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:806
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:822
msgid "Switch to {listPriceNewLabel}"
msgstr "Overschakelen naar {listPriceNewLabel}"
@@ -32546,7 +32546,7 @@ msgstr "Overschakelen naar directe invoer"
#. Billing button that opens confirmation to switch to monthly billing.
#. Button confirming a change to monthly subscription billing.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:57
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:789
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:805
msgid "Switch to monthly"
msgstr "Overschakelen naar maandelijks"
@@ -32615,7 +32615,7 @@ msgstr "Naar twee kolommen wisselen"
#. Billing button that opens confirmation to switch to yearly billing.
#. Button confirming a change to yearly subscription billing.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:53
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:785
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:801
msgid "Switch to yearly"
msgstr "Overschakelen naar jaarlijks"
@@ -35865,7 +35865,7 @@ msgstr "Ontgrendel aangepaste emoji's in DM's met {premiumProductName}"
msgid "Unlock HD screen share with {premiumProductName}"
msgstr "Ontgrendel schermdelen in HD met {premiumProductName}"
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:217
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:216
msgid "Unlock higher limits and exclusive features while supporting an independent communication platform."
msgstr "Ontgrendel hogere limieten en exclusieve functies, en steun tegelijkertijd een onafhankelijk communicatieplatform."
@@ -39015,15 +39015,15 @@ msgstr "Jaarlijks {yearlyPrice}"
msgid "Yearly gift"
msgstr "Cadeau voor één jaar"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:618
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:634
msgid "Yearly upgrade scheduled for <0>{pendingChangeDate}</0>."
msgstr "Overstap naar een jaarabonnement gepland voor <0>{pendingChangeDate}</0>."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:603
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:619
msgid "Yearly upgrade scheduled for <0>{pendingChangeDate}</0>. First yearly charge: {pendingInitialPriceLabel} after a {pendingCreditPriceLabel} credit. Future yearly renewals: {pendingRecurringPriceLabel}/year."
msgstr "Overstap naar een jaarabonnement gepland voor <0>{pendingChangeDate}</0>. Eerste jaarbetaling: {pendingInitialPriceLabel} na verrekening van een tegoed van {pendingCreditPriceLabel}. Latere jaarlijkse verlengingen: {pendingRecurringPriceLabel}/jaar."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:610
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:626
msgid "Yearly upgrade scheduled for <0>{pendingChangeDate}</0>. First yearly charge: {pendingInitialPriceLabel}. Future yearly renewals: {pendingRecurringPriceLabel}/year."
msgstr "Overstap naar een jaarabonnement gepland voor <0>{pendingChangeDate}</0>. Eerste jaarbetaling: {pendingInitialPriceLabel}. Latere jaarlijkse verlengingen: {pendingRecurringPriceLabel}/jaar."
@@ -39493,10 +39493,10 @@ msgid "You just pressed Tab. Keyboard mode is now on so you can navigate {produc
msgstr "Je hebt zojuist op Tab gedrukt. De toetsenbordmodus is nu ingeschakeld, zodat je {productName} zonder muis kunt navigeren."
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:137
msgid "You keep your perks until your next renewal date, then have a 3-day grace period to resubscribe and keep your subscriber history."
msgstr "Je behoudt je voordelen tot je volgende verlengingsdatum, daarna heb je een respijtperiode van 3 dagen om je opnieuw te abonneren en je abonnementsgeschiedenis te behouden."
msgid "You keep your perks until your next renewal date. Reactivate before then to keep your subscriber history."
msgstr "Je behoudt je voordelen tot je volgende verlengingsdatum. Activeer je abonnement vóór die datum opnieuw om je abonnementsgeschiedenis te behouden."
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:159
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:158
msgid "You lose all {PREMIUM_PRODUCT_NAME} perks immediately and your subscriber history resets. This cannot be undone."
msgstr "Je verliest onmiddellijk alle {PREMIUM_PRODUCT_NAME}-voordelen en je abonnementsgeschiedenis wordt gereset. Dit kan niet ongedaan worden gemaakt."
@@ -40231,6 +40231,11 @@ msgstr "je regio"
msgid "Your registration needs an extra anti-spam check before you can continue."
msgstr "Je registratie heeft een extra antispamcontrole nodig voordat je verder kunt gaan."
#. Plutonium subscription card text shown while a failed renewal payment is being retried. {graceDate} is a date already formatted and localized by code; never write a date into the translation.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:470
msgid "Your renewal payment failed but <0/> stay active until <1>{graceDate}</1>. Update your payment method before then to keep your subscription."
msgstr "Je verlengingsbetaling is mislukt, maar je <0/> blijven actief tot <1>{graceDate}</1>. Werk je betaalmethode vóór die tijd bij om je abonnement te behouden."
#. Video settings note shown when the saved screen share quality is above what this account can send. Resolutions are short labels such as 1440p or Source and rates are whole numbers. FPS is a technical token.
#: src/features/user/components/modals/tabs/UserVideoTab.tsx:92
msgid "Your saved {savedResolution} at {savedFrameRate} FPS needs {premiumProductName}, so shares use {resolution} at {frameRate} FPS."
@@ -40252,7 +40257,7 @@ msgstr "Je stream is nog steeds live"
msgid "Your subscription can't move to the new price right now."
msgstr "Je abonnement kan nu niet naar de nieuwe prijs worden verplaatst."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:470
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:486
msgid "Your subscription ended but <0/> stay active until <1>{graceDate}</1>. Resubscribe before then to keep your subscriber history."
msgstr "Je abonnement is beëindigd, maar je <0/> blijven actief tot <1>{graceDate}</1>. Neem voor die tijd opnieuw een abonnement om je abonnementsgeschiedenis te behouden."
@@ -40281,7 +40286,7 @@ msgstr "Je abonnement is overgezet naar maandelijkse facturatie."
msgid "Your subscription has been switched to yearly billing."
msgstr "Je abonnement is overgezet naar jaarlijkse facturering."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:512
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:528
msgid "Your subscription is active but perks are temporarily paused."
msgstr "Je abonnement is actief, maar de voordelen zijn tijdelijk gepauzeerd."
@@ -40301,7 +40306,7 @@ msgid "Your subscription moves to the new price on {effectiveDate}."
msgstr "Je abonnement wordt op {effectiveDate} bijgewerkt naar de nieuwe prijs."
#. Plutonium subscription card line shown to a subscriber on a legacy price whose subscription is already set to cancel. {cancelDate} is a date and {listPriceNewLabel} is a currency amount, both already formatted and localized by code; never write a date or an amount into the translation.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:666
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:682
msgid "Your subscription still ends on <0>{cancelDate}</0>. The current price is now {listPriceNewLabel}. If you reactivate, you can switch to it from here."
msgstr "Je abonnement eindigt nog steeds op <0>{cancelDate}</0>. De huidige prijs is nu {listPriceNewLabel}. Als je opnieuw activeert, kun je hiernaartoe overschakelen."
@@ -2471,7 +2471,7 @@ msgid "A Linux desktop update is available. Choose the package format for this s
msgstr "En oppdatering av skrivebordsappen for Linux er tilgjengelig. Velg pakkeformatet for dette systemet, så lagrer {productName} det lokalt."
#. Plutonium subscription card line offering a move to a lower price. {listPriceEffectiveDate} is a date already formatted and localized by code; never write a date into the translation.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:684
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:700
msgid "A lower price is available. Switching takes effect on <0>{listPriceEffectiveDate}</0> and changes nothing else."
msgstr "En lavere pris er tilgjengelig. Byttet trer i kraft <0>{listPriceEffectiveDate}</0> og endrer ingenting annet."
@@ -3487,19 +3487,19 @@ msgstr "Kontroller for bildeplassering er bare tilgjengelige på bredere skjerme
msgid "All"
msgstr "Alle"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:524
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:540
msgid "All <0/> for <1>{effectiveMonthlyPrice}/month</1>."
msgstr "Alt <0/> for <1>{effectiveMonthlyPrice}/måned</1>."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:546
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:562
msgid "All <0/> for <1>{effectiveYearlyPrice}/year</1>."
msgstr "Alt <0/> for <1>{effectiveYearlyPrice}/år</1>."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:567
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:583
msgid "All <0/> included with your subscription."
msgstr "Alt <0/> er inkludert i abonnementet ditt."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:514
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:530
msgid "All <0/>, forever. No billing, no renewals."
msgstr "Alt <0/>, for alltid. Ingen fakturering, ingen fornyelser."
@@ -6469,7 +6469,7 @@ msgid "Cancel import"
msgstr "Avbryt import"
#. Billing button that cancels a scheduled move to a lower subscription price.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:821
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:837
msgid "Cancel price change"
msgstr "Avbryt prisendring"
@@ -6484,14 +6484,14 @@ msgid "Cancel request"
msgstr "Avbryt forespørsel"
#. Billing button that cancels a scheduled billing-cycle change.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:829
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:845
msgid "Cancel scheduled switch"
msgstr "Avbryt planlagt bytte"
#. Billing button that starts subscription cancellation.
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:844
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:142
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:860
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:141
#: src/features/user/components/settings_utils/search_index/PlutoniumIndex.ts:31
msgid "Cancel subscription"
msgstr "Si opp abonnement"
@@ -6501,7 +6501,7 @@ msgid "Cancel subscription?"
msgstr "Si opp abonnementet?"
#. Plutonium subscription card hint shown to a subscriber who could move to a lower price but has another billing change already scheduled.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:647
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:663
msgid "Cancel the scheduled change to move to the current price instead."
msgstr "Avbryt den planlagte endringen for å bytte til den gjeldende prisen i stedet."
@@ -6511,7 +6511,7 @@ msgid "Cancel upload"
msgstr "Avbryt opplasting"
#. Billing button that cancels a scheduled yearly upgrade.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:825
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:841
msgid "Cancel yearly upgrade"
msgstr "Avbryt oppgradering til årsabonnement"
@@ -6530,7 +6530,7 @@ msgstr "Avsluttes ved periodens slutt"
msgid "Cancellation"
msgstr "Ekkodemping"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:501
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:517
msgid "Cancels on <0>{cancelDate}</0>. <1/> remain active until then."
msgstr "Avsluttes <0>{cancelDate}</0>. <1/> forblir aktive frem til da."
@@ -10872,7 +10872,7 @@ msgstr "Egendefinert …"
#. Billing button that opens the external customer portal.
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:750
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:766
#: src/features/user/components/settings_utils/search_index/PlutoniumIndex.ts:39
msgid "Customer portal"
msgstr "Kundeportal"
@@ -13877,15 +13877,15 @@ msgid "End date"
msgstr "Sluttdato"
#. Billing button that ends premium grace period immediately.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:856
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:872
msgid "End grace now"
msgstr "Avslutt respittperiode nå"
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:164
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:163
msgid "End grace period"
msgstr "Avslutt respittperiode"
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:157
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:156
msgid "End grace period now?"
msgstr "Avslutte respittperioden nå?"
@@ -16347,7 +16347,7 @@ msgstr "Gave: utløper snart"
msgid "Gift: grace period (still have access)"
msgstr "Gave: respittperiode (har fortsatt tilgang)"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:486
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:502
msgid "Gifted <0/> until <1>{giftEndDate}</1>. Does not renew automatically. Redeem more gift codes to extend."
msgstr "<0/> i gave frem til <1>{giftEndDate}</1>. Fornyes ikke automatisk. Løs inn flere gavekoder for å forlenge."
@@ -16826,7 +16826,7 @@ msgid "Hate speech"
msgstr "Hatefulle ytringer"
#. Premium page text shown on an instance where the premium tier cannot be bought, only redeemed. {PREMIUM_PRODUCT_NAME} is the premium tier name.
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:297
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:296
msgid "Have a gift code? Redeem it to unlock {PREMIUM_PRODUCT_NAME}."
msgstr "Har du en gavekode? Løs den inn for å låse opp {PREMIUM_PRODUCT_NAME}."
@@ -18926,7 +18926,7 @@ msgstr "Behold vedlegg når meldingsteksten tømmes under redigering"
msgid "Keep free and premium tiers. You can customize the tiers, sell premium through Stripe, or hand out gift codes later from the admin panel."
msgstr "Behold gratis- og premiumnivåer. Du kan tilpasse nivåene, selge premium via Stripe, eller dele ut gavekoder senere fra administrasjonspanelet."
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:166
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:165
msgid "Keep grace period"
msgstr "Behold respittperioden"
@@ -18940,7 +18940,7 @@ msgstr "Hold Neko stille"
msgid "Keep running"
msgstr "Fortsett å kjøre"
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:144
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:143
msgid "Keep subscription"
msgstr "Behold abonnementet"
@@ -19297,8 +19297,8 @@ msgstr "Venstre museknapp"
msgid "Left tooltip"
msgstr "Venstre verktøytips"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:539
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:561
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:555
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:577
msgid "Legacy rate"
msgstr "Gammel pris"
@@ -21339,11 +21339,11 @@ msgstr "Månedlig"
msgid "Monthly {monthlyPrice}"
msgstr "Månedlig {monthlyPrice}"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:631
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:647
msgid "Monthly billing starts on <0>{pendingChangeDate}</0>."
msgstr "Månedlig fakturering starter den <0>{pendingChangeDate}</0>."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:624
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:640
msgid "Monthly billing starts on <0>{pendingChangeDate}</0>. First monthly charge: {pendingInitialPriceLabel}. Future monthly renewals: {pendingRecurringPriceLabel}/month."
msgstr "Månedlig fakturering starter den <0>{pendingChangeDate}</0>. Første månedlige kostnad: {pendingInitialPriceLabel}. Fremtidige månedlige fornyelser: {pendingRecurringPriceLabel}/måned."
@@ -22269,12 +22269,12 @@ msgid "New password"
msgstr "Nytt passord"
#. Plutonium subscription card line shown when a move to a lower price is scheduled but the new amount is unknown. {pendingChangeDate} is a date already formatted and localized by code; never write a date into the translation.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:595
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:611
msgid "New price scheduled for <0>{pendingChangeDate}</0>."
msgstr "Ny pris gjelder fra <0>{pendingChangeDate}</0>."
#. Plutonium subscription card line shown when a move to a lower price is scheduled. {pendingChangeDate} is a date and {pendingTargetPriceLabel} is a currency amount, both already formatted and localized by code; never write a date or an amount into the translation.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:589
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:605
msgid "New price scheduled for <0>{pendingChangeDate}</0>. Renewals will be {pendingTargetPriceLabel} from then on."
msgstr "Ny pris gjelder fra <0>{pendingChangeDate}</0>. Deretter vil fornyelser koste {pendingTargetPriceLabel}."
@@ -26152,7 +26152,7 @@ msgstr "Reaksjoner"
#. Billing button that cancels a scheduled subscription cancellation.
#. Button label on the premium-expired nagbar. Opens billing so the user can reactivate their subscription.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:746
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:762
#: src/features/app/components/layout/app_layout/nagbars/PremiumExpiredNagbar.tsx:25
msgid "Reactivate"
msgstr "Reaktiver"
@@ -26375,8 +26375,8 @@ msgstr "Løs inn på egen konto"
#. Billing button for entering a premium gift code.
#. Billing button for entering a premium gift code.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:719
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:307
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:735
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:306
msgid "Redeem gift code"
msgstr "Løs inn gavekode"
@@ -27147,7 +27147,7 @@ msgstr "Fornyelsesterskel (dager)"
msgid "Renew window (days)"
msgstr "Fornyelsesvindu (dager)"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:701
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:717
msgid "Renews on <0>{renewalDate}.</0>"
msgstr "Fornyes den <0>{renewalDate}.</0>"
@@ -27896,8 +27896,8 @@ msgstr "Gjenopprett vindu"
#. Billing button for restarting a subscription during the grace period.
#. Billing button for starting a new subscription after premium expired.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:738
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:742
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:754
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:758
msgid "Resubscribe"
msgstr "Abonner på nytt"
@@ -32521,7 +32521,7 @@ msgid "Switch price"
msgstr "Bytt pris"
#. Billing button that opens confirmation to move the subscription down to the current price. {listPriceNewLabel} is the localized new price.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:806
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:822
msgid "Switch to {listPriceNewLabel}"
msgstr "Bytt til {listPriceNewLabel}"
@@ -32546,7 +32546,7 @@ msgstr "Bytt til direkte inndata"
#. Billing button that opens confirmation to switch to monthly billing.
#. Button confirming a change to monthly subscription billing.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:57
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:789
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:805
msgid "Switch to monthly"
msgstr "Bytt til månedlig"
@@ -32615,7 +32615,7 @@ msgstr "Bytt til to kolonner"
#. Billing button that opens confirmation to switch to yearly billing.
#. Button confirming a change to yearly subscription billing.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:53
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:785
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:801
msgid "Switch to yearly"
msgstr "Bytt til årlig"
@@ -35865,7 +35865,7 @@ msgstr "Lås opp egendefinerte emojier i direktemeldinger med {premiumProductNam
msgid "Unlock HD screen share with {premiumProductName}"
msgstr "Lås opp HD-skjermdeling med {premiumProductName}"
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:217
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:216
msgid "Unlock higher limits and exclusive features while supporting an independent communication platform."
msgstr "Lås opp høyere grenser og eksklusive funksjoner, samtidig som du støtter en uavhengig kommunikasjonsplattform."
@@ -39015,15 +39015,15 @@ msgstr "Årlig {yearlyPrice}"
msgid "Yearly gift"
msgstr "Gaveabonnement på ett år"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:618
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:634
msgid "Yearly upgrade scheduled for <0>{pendingChangeDate}</0>."
msgstr "Årlig oppgradering er planlagt til <0>{pendingChangeDate}</0>."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:603
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:619
msgid "Yearly upgrade scheduled for <0>{pendingChangeDate}</0>. First yearly charge: {pendingInitialPriceLabel} after a {pendingCreditPriceLabel} credit. Future yearly renewals: {pendingRecurringPriceLabel}/year."
msgstr "Årlig oppgradering er planlagt til <0>{pendingChangeDate}</0>. Første årlige belastning: {pendingInitialPriceLabel} etter fratrekk av {pendingCreditPriceLabel} i kreditt. Fremtidige årlige fornyelser: {pendingRecurringPriceLabel}/år."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:610
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:626
msgid "Yearly upgrade scheduled for <0>{pendingChangeDate}</0>. First yearly charge: {pendingInitialPriceLabel}. Future yearly renewals: {pendingRecurringPriceLabel}/year."
msgstr "Årlig oppgradering er planlagt til <0>{pendingChangeDate}</0>. Første årlige belastning: {pendingInitialPriceLabel}. Fremtidige årlige fornyelser: {pendingRecurringPriceLabel}/år."
@@ -39493,10 +39493,10 @@ msgid "You just pressed Tab. Keyboard mode is now on so you can navigate {produc
msgstr "Du trykket nettopp på Tab. Tastaturmodus er nå på, slik at du kan navigere i {productName} uten mus."
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:137
msgid "You keep your perks until your next renewal date, then have a 3-day grace period to resubscribe and keep your subscriber history."
msgstr "Du beholder fordelene dine frem til neste fornyelsesdato, og har deretter en respittperiode på 3 dager til å abonnere på nytt og beholde abonnementshistorikken din."
msgid "You keep your perks until your next renewal date. Reactivate before then to keep your subscriber history."
msgstr "Du beholder fordelene dine frem til neste fornyelsesdato. Reaktiver før den tid for å beholde abonnementshistorikken din."
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:159
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:158
msgid "You lose all {PREMIUM_PRODUCT_NAME} perks immediately and your subscriber history resets. This cannot be undone."
msgstr "Du mister alle {PREMIUM_PRODUCT_NAME}-fordeler umiddelbart, og abonnementshistorikken din nullstilles. Dette kan ikke angres."
@@ -40231,6 +40231,11 @@ msgstr "din region"
msgid "Your registration needs an extra anti-spam check before you can continue."
msgstr "Registreringen din krever en ekstra antispam-sjekk før du kan fortsette."
#. Plutonium subscription card text shown while a failed renewal payment is being retried. {graceDate} is a date already formatted and localized by code; never write a date into the translation.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:470
msgid "Your renewal payment failed but <0/> stay active until <1>{graceDate}</1>. Update your payment method before then to keep your subscription."
msgstr "Betalingen for fornyelsen mislyktes, men <0/> forblir aktive frem til <1>{graceDate}</1>. Oppdater betalingsmåten din før den tid for å beholde abonnementet."
#. Video settings note shown when the saved screen share quality is above what this account can send. Resolutions are short labels such as 1440p or Source and rates are whole numbers. FPS is a technical token.
#: src/features/user/components/modals/tabs/UserVideoTab.tsx:92
msgid "Your saved {savedResolution} at {savedFrameRate} FPS needs {premiumProductName}, so shares use {resolution} at {frameRate} FPS."
@@ -40252,7 +40257,7 @@ msgstr "Strømmen din er fortsatt aktiv"
msgid "Your subscription can't move to the new price right now."
msgstr "Abonnementet ditt kan ikke flyttes til den nye prisen akkurat nå."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:470
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:486
msgid "Your subscription ended but <0/> stay active until <1>{graceDate}</1>. Resubscribe before then to keep your subscriber history."
msgstr "Abonnementet ditt er avsluttet, men <0/> forblir aktive frem til <1>{graceDate}</1>. Abonner på nytt før den tid for å beholde abonnementshistorikken din."
@@ -40281,7 +40286,7 @@ msgstr "Abonnementet ditt er nå byttet til månedlig fakturering."
msgid "Your subscription has been switched to yearly billing."
msgstr "Abonnementet ditt er nå byttet til årlig fakturering."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:512
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:528
msgid "Your subscription is active but perks are temporarily paused."
msgstr "Abonnementet ditt er aktivt, men fordelene er midlertidig satt på pause."
@@ -40301,7 +40306,7 @@ msgid "Your subscription moves to the new price on {effectiveDate}."
msgstr "Abonnementet ditt flyttes til den nye prisen den {effectiveDate}."
#. Plutonium subscription card line shown to a subscriber on a legacy price whose subscription is already set to cancel. {cancelDate} is a date and {listPriceNewLabel} is a currency amount, both already formatted and localized by code; never write a date or an amount into the translation.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:666
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:682
msgid "Your subscription still ends on <0>{cancelDate}</0>. The current price is now {listPriceNewLabel}. If you reactivate, you can switch to it from here."
msgstr "Abonnementet ditt avsluttes fortsatt den <0>{cancelDate}</0>. Den nåværende prisen er nå {listPriceNewLabel}. Hvis du reaktiverer, kan du bytte til den herfra."
@@ -2471,7 +2471,7 @@ msgid "A Linux desktop update is available. Choose the package format for this s
msgstr "Dostępna jest aktualizacja aplikacji komputerowej dla systemu Linux. Wybierz format pakietu dla tego systemu, a {productName} zapisze go lokalnie."
#. Plutonium subscription card line offering a move to a lower price. {listPriceEffectiveDate} is a date already formatted and localized by code; never write a date into the translation.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:684
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:700
msgid "A lower price is available. Switching takes effect on <0>{listPriceEffectiveDate}</0> and changes nothing else."
msgstr "Dostępna jest niższa cena. Zmiana zacznie obowiązywać od <0>{listPriceEffectiveDate}</0>, a nic innego się nie zmieni."
@@ -3487,19 +3487,19 @@ msgstr "Sterowanie wyrównaniem jest dostępne tylko na szerszych ekranach"
msgid "All"
msgstr "Wszystkie"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:524
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:540
msgid "All <0/> for <1>{effectiveMonthlyPrice}/month</1>."
msgstr "Wszystkie <0/> za <1>{effectiveMonthlyPrice}/miesiąc</1>."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:546
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:562
msgid "All <0/> for <1>{effectiveYearlyPrice}/year</1>."
msgstr "Wszystkie <0/> za <1>{effectiveYearlyPrice}/rok</1>."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:567
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:583
msgid "All <0/> included with your subscription."
msgstr "Wszystkie <0/> w cenie subskrypcji."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:514
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:530
msgid "All <0/>, forever. No billing, no renewals."
msgstr "Wszystkie <0/> na zawsze. Bez opłat i odnawiania."
@@ -6469,7 +6469,7 @@ msgid "Cancel import"
msgstr "Anuluj importowanie"
#. Billing button that cancels a scheduled move to a lower subscription price.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:821
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:837
msgid "Cancel price change"
msgstr "Anuluj zmianę ceny"
@@ -6484,14 +6484,14 @@ msgid "Cancel request"
msgstr "Anuluj zaproszenie"
#. Billing button that cancels a scheduled billing-cycle change.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:829
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:845
msgid "Cancel scheduled switch"
msgstr "Anuluj zaplanowaną zmianę"
#. Billing button that starts subscription cancellation.
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:844
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:142
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:860
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:141
#: src/features/user/components/settings_utils/search_index/PlutoniumIndex.ts:31
msgid "Cancel subscription"
msgstr "Anuluj subskrypcję"
@@ -6501,7 +6501,7 @@ msgid "Cancel subscription?"
msgstr "Anulować subskrypcję?"
#. Plutonium subscription card hint shown to a subscriber who could move to a lower price but has another billing change already scheduled.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:647
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:663
msgid "Cancel the scheduled change to move to the current price instead."
msgstr "Anuluj zaplanowaną zmianę, aby zamiast tego przejść na obecną cenę."
@@ -6511,7 +6511,7 @@ msgid "Cancel upload"
msgstr "Anuluj przesyłanie"
#. Billing button that cancels a scheduled yearly upgrade.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:825
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:841
msgid "Cancel yearly upgrade"
msgstr "Anuluj przejście na plan roczny"
@@ -6530,7 +6530,7 @@ msgstr "Anulowanie"
msgid "Cancellation"
msgstr "Redukcja echa"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:501
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:517
msgid "Cancels on <0>{cancelDate}</0>. <1/> remain active until then."
msgstr "Subskrypcja zakończy się <0>{cancelDate}</0>. Do tego czasu pozostaną aktywne <1/>."
@@ -10872,7 +10872,7 @@ msgstr "Niestandardowe…"
#. Billing button that opens the external customer portal.
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:750
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:766
#: src/features/user/components/settings_utils/search_index/PlutoniumIndex.ts:39
msgid "Customer portal"
msgstr "Portal klienta"
@@ -13877,15 +13877,15 @@ msgid "End date"
msgstr "Data końcowa"
#. Billing button that ends premium grace period immediately.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:856
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:872
msgid "End grace now"
msgstr "Zakończ okres karencji teraz"
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:164
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:163
msgid "End grace period"
msgstr "Zakończ okres karencji"
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:157
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:156
msgid "End grace period now?"
msgstr "Zakończyć okres karencji teraz?"
@@ -16347,7 +16347,7 @@ msgstr "Prezent: wkrótce wygasa"
msgid "Gift: grace period (still have access)"
msgstr "Prezent: okres karencji (nadal masz dostęp)"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:486
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:502
msgid "Gifted <0/> until <1>{giftEndDate}</1>. Does not renew automatically. Redeem more gift codes to extend."
msgstr "Otrzymane w prezencie <0/> są aktywne do <1>{giftEndDate}</1>. Nie odnawiają się automatycznie. Wykorzystaj kolejne kody podarunkowe, aby przedłużyć dostęp."
@@ -16826,7 +16826,7 @@ msgid "Hate speech"
msgstr "Mowa nienawiści"
#. Premium page text shown on an instance where the premium tier cannot be bought, only redeemed. {PREMIUM_PRODUCT_NAME} is the premium tier name.
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:297
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:296
msgid "Have a gift code? Redeem it to unlock {PREMIUM_PRODUCT_NAME}."
msgstr "Masz kod podarunkowy? Aktywuj go, aby odblokować {PREMIUM_PRODUCT_NAME}."
@@ -18926,7 +18926,7 @@ msgstr "Zachowaj załączniki po wyczyszczeniu edycji"
msgid "Keep free and premium tiers. You can customize the tiers, sell premium through Stripe, or hand out gift codes later from the admin panel."
msgstr "Zachowaj darmowe i premium poziomy. Poziomy możesz dostosować, sprzedawać premium przez Stripe lub później rozdawać kody podarunkowe z panelu administratora."
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:166
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:165
msgid "Keep grace period"
msgstr "Zachowaj okres karencji"
@@ -18940,7 +18940,7 @@ msgstr "Pozostaw Neko w bezruchu"
msgid "Keep running"
msgstr "Kontynuuj działanie"
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:144
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:143
msgid "Keep subscription"
msgstr "Zachowaj subskrypcję"
@@ -19297,8 +19297,8 @@ msgstr "Lewy przycisk myszy"
msgid "Left tooltip"
msgstr "Podpowiedź po lewej"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:539
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:561
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:555
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:577
msgid "Legacy rate"
msgstr "Stawka historyczna"
@@ -21339,11 +21339,11 @@ msgstr "Miesięcznie"
msgid "Monthly {monthlyPrice}"
msgstr "Miesięcznie {monthlyPrice}"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:631
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:647
msgid "Monthly billing starts on <0>{pendingChangeDate}</0>."
msgstr "Rozliczenia miesięczne rozpoczną się <0>{pendingChangeDate}</0>."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:624
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:640
msgid "Monthly billing starts on <0>{pendingChangeDate}</0>. First monthly charge: {pendingInitialPriceLabel}. Future monthly renewals: {pendingRecurringPriceLabel}/month."
msgstr "Rozliczenia miesięczne rozpoczną się <0>{pendingChangeDate}</0>. Pierwsza opłata miesięczna: {pendingInitialPriceLabel}. Kolejne odnowienia miesięczne: {pendingRecurringPriceLabel}/miesiąc."
@@ -22269,12 +22269,12 @@ msgid "New password"
msgstr "Nowe hasło"
#. Plutonium subscription card line shown when a move to a lower price is scheduled but the new amount is unknown. {pendingChangeDate} is a date already formatted and localized by code; never write a date into the translation.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:595
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:611
msgid "New price scheduled for <0>{pendingChangeDate}</0>."
msgstr "Nowa cena zaplanowana na <0>{pendingChangeDate}</0>."
#. Plutonium subscription card line shown when a move to a lower price is scheduled. {pendingChangeDate} is a date and {pendingTargetPriceLabel} is a currency amount, both already formatted and localized by code; never write a date or an amount into the translation.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:589
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:605
msgid "New price scheduled for <0>{pendingChangeDate}</0>. Renewals will be {pendingTargetPriceLabel} from then on."
msgstr "Nowa cena zaplanowana na <0>{pendingChangeDate}</0>. Odnowienia będą kosztować {pendingTargetPriceLabel} od tego momentu."
@@ -26152,7 +26152,7 @@ msgstr "Reakcje"
#. Billing button that cancels a scheduled subscription cancellation.
#. Button label on the premium-expired nagbar. Opens billing so the user can reactivate their subscription.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:746
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:762
#: src/features/app/components/layout/app_layout/nagbars/PremiumExpiredNagbar.tsx:25
msgid "Reactivate"
msgstr "Reaktywuj"
@@ -26375,8 +26375,8 @@ msgstr "Odbierz dla siebie"
#. Billing button for entering a premium gift code.
#. Billing button for entering a premium gift code.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:719
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:307
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:735
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:306
msgid "Redeem gift code"
msgstr "Wykorzystaj kod podarunkowy"
@@ -27147,7 +27147,7 @@ msgstr "Próg odnowienia (dni)"
msgid "Renew window (days)"
msgstr "Okno odnowienia (dni)"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:701
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:717
msgid "Renews on <0>{renewalDate}.</0>"
msgstr "Odnowi się <0>{renewalDate}.</0>"
@@ -27896,8 +27896,8 @@ msgstr "Przywróć okno"
#. Billing button for restarting a subscription during the grace period.
#. Billing button for starting a new subscription after premium expired.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:738
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:742
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:754
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:758
msgid "Resubscribe"
msgstr "Ponów subskrypcję"
@@ -32521,7 +32521,7 @@ msgid "Switch price"
msgstr "Zmień cenę"
#. Billing button that opens confirmation to move the subscription down to the current price. {listPriceNewLabel} is the localized new price.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:806
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:822
msgid "Switch to {listPriceNewLabel}"
msgstr "Przełącz na {listPriceNewLabel}"
@@ -32546,7 +32546,7 @@ msgstr "Przełącz na bezpośrednie wejście"
#. Billing button that opens confirmation to switch to monthly billing.
#. Button confirming a change to monthly subscription billing.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:57
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:789
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:805
msgid "Switch to monthly"
msgstr "Przejdź na płatność miesięczną"
@@ -32615,7 +32615,7 @@ msgstr "Przełącz na dwie kolumny"
#. Billing button that opens confirmation to switch to yearly billing.
#. Button confirming a change to yearly subscription billing.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:53
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:785
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:801
msgid "Switch to yearly"
msgstr "Przejdź na plan roczny"
@@ -35865,7 +35865,7 @@ msgstr "Odblokuj niestandardowe emoji w wiadomościach prywatnych dzięki {premi
msgid "Unlock HD screen share with {premiumProductName}"
msgstr "Odblokuj udostępnianie ekranu w jakości HD dzięki {premiumProductName}"
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:217
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:216
msgid "Unlock higher limits and exclusive features while supporting an independent communication platform."
msgstr "Odblokuj wyższe limity i ekskluzywne funkcje, wspierając jednocześnie niezależną platformę komunikacyjną."
@@ -39015,15 +39015,15 @@ msgstr "Rocznie {yearlyPrice}"
msgid "Yearly gift"
msgstr "Prezent roczny"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:618
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:634
msgid "Yearly upgrade scheduled for <0>{pendingChangeDate}</0>."
msgstr "Przejście na subskrypcję roczną zaplanowano na <0>{pendingChangeDate}</0>."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:603
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:619
msgid "Yearly upgrade scheduled for <0>{pendingChangeDate}</0>. First yearly charge: {pendingInitialPriceLabel} after a {pendingCreditPriceLabel} credit. Future yearly renewals: {pendingRecurringPriceLabel}/year."
msgstr "Przejście na subskrypcję roczną zaplanowano na <0>{pendingChangeDate}</0>. Pierwsza opłata roczna: {pendingInitialPriceLabel} po odliczeniu {pendingCreditPriceLabel}. Kolejne odnowienia roczne: {pendingRecurringPriceLabel}/rok."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:610
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:626
msgid "Yearly upgrade scheduled for <0>{pendingChangeDate}</0>. First yearly charge: {pendingInitialPriceLabel}. Future yearly renewals: {pendingRecurringPriceLabel}/year."
msgstr "Przejście na subskrypcję roczną zaplanowano na <0>{pendingChangeDate}</0>. Pierwsza opłata roczna: {pendingInitialPriceLabel}. Kolejne odnowienia roczne: {pendingRecurringPriceLabel}/rok."
@@ -39493,10 +39493,10 @@ msgid "You just pressed Tab. Keyboard mode is now on so you can navigate {produc
msgstr "Właśnie naciśnięto klawisz Tab. Tryb klawiatury jest teraz włączony, więc możesz nawigować po {productName} bez myszy."
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:137
msgid "You keep your perks until your next renewal date, then have a 3-day grace period to resubscribe and keep your subscriber history."
msgstr "Zachowasz korzyści do następnej daty odnowienia. Potem masz 3-dniowy okres karencji na ponowne wykupienie subskrypcji i zachowanie historii subskrypcji."
msgid "You keep your perks until your next renewal date. Reactivate before then to keep your subscriber history."
msgstr "Zachowasz korzyści do następnej daty odnowienia. Reaktywuj subskrypcję przed tym terminem, aby zachować historię subskrypcji."
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:159
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:158
msgid "You lose all {PREMIUM_PRODUCT_NAME} perks immediately and your subscriber history resets. This cannot be undone."
msgstr "Natychmiast tracisz wszystkie korzyści {PREMIUM_PRODUCT_NAME}, a historia subskrypcji zostaje zresetowana. Tej operacji nie można cofnąć."
@@ -40231,6 +40231,11 @@ msgstr "Twój region"
msgid "Your registration needs an extra anti-spam check before you can continue."
msgstr "Zanim przejdziesz dalej, musimy przeprowadzić dodatkową weryfikację antyspamową Twojej rejestracji."
#. Plutonium subscription card text shown while a failed renewal payment is being retried. {graceDate} is a date already formatted and localized by code; never write a date into the translation.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:470
msgid "Your renewal payment failed but <0/> stay active until <1>{graceDate}</1>. Update your payment method before then to keep your subscription."
msgstr "Płatność za odnowienie nie powiodła się, ale <0/> pozostają aktywne do <1>{graceDate}</1>. Zaktualizuj metodę płatności przed tą datą, aby zachować subskrypcję."
#. Video settings note shown when the saved screen share quality is above what this account can send. Resolutions are short labels such as 1440p or Source and rates are whole numbers. FPS is a technical token.
#: src/features/user/components/modals/tabs/UserVideoTab.tsx:92
msgid "Your saved {savedResolution} at {savedFrameRate} FPS needs {premiumProductName}, so shares use {resolution} at {frameRate} FPS."
@@ -40252,7 +40257,7 @@ msgstr "Twoja transmisja nadal trwa"
msgid "Your subscription can't move to the new price right now."
msgstr "Twoja subskrypcja nie może w tej chwili zostać przeniesiona na nową cenę."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:470
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:486
msgid "Your subscription ended but <0/> stay active until <1>{graceDate}</1>. Resubscribe before then to keep your subscriber history."
msgstr "Twoja subskrypcja wygasła, ale <0/> pozostają aktywne do <1>{graceDate}</1>. Wykup subskrypcję ponownie przed tą datą, aby zachować historię subskrypcji."
@@ -40281,7 +40286,7 @@ msgstr "Twoja subskrypcja została zmieniona na rozliczenie miesięczne."
msgid "Your subscription has been switched to yearly billing."
msgstr "Twoja subskrypcja została zmieniona na rozliczenie roczne."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:512
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:528
msgid "Your subscription is active but perks are temporarily paused."
msgstr "Twoja subskrypcja jest aktywna, ale korzyści są tymczasowo wstrzymane."
@@ -40301,7 +40306,7 @@ msgid "Your subscription moves to the new price on {effectiveDate}."
msgstr "Twoja subskrypcja przejdzie na nową cenę {effectiveDate}."
#. Plutonium subscription card line shown to a subscriber on a legacy price whose subscription is already set to cancel. {cancelDate} is a date and {listPriceNewLabel} is a currency amount, both already formatted and localized by code; never write a date or an amount into the translation.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:666
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:682
msgid "Your subscription still ends on <0>{cancelDate}</0>. The current price is now {listPriceNewLabel}. If you reactivate, you can switch to it from here."
msgstr "Twoja subskrypcja nadal wygasa <0>{cancelDate}</0>. Obecna cena to {listPriceNewLabel}. Jeśli ponownie aktywujesz subskrypcję, możesz tutaj przejść na tę cenę."
@@ -2471,7 +2471,7 @@ msgid "A Linux desktop update is available. Choose the package format for this s
msgstr "Há uma atualização do aplicativo para Linux. Escolha o formato do pacote para este sistema e o {productName} salvará o arquivo localmente."
#. Plutonium subscription card line offering a move to a lower price. {listPriceEffectiveDate} is a date already formatted and localized by code; never write a date into the translation.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:684
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:700
msgid "A lower price is available. Switching takes effect on <0>{listPriceEffectiveDate}</0> and changes nothing else."
msgstr "Um preço menor está disponível. A alteração entra em vigor em <0>{listPriceEffectiveDate}</0> e não muda mais nada."
@@ -3487,19 +3487,19 @@ msgstr "Os controles de alinhamento estão disponíveis apenas em telas mais lar
msgid "All"
msgstr "Todos"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:524
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:540
msgid "All <0/> for <1>{effectiveMonthlyPrice}/month</1>."
msgstr "Todas as <0/> por <1>{effectiveMonthlyPrice}/mês</1>."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:546
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:562
msgid "All <0/> for <1>{effectiveYearlyPrice}/year</1>."
msgstr "Todas as <0/> por <1>{effectiveYearlyPrice}/ano</1>."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:567
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:583
msgid "All <0/> included with your subscription."
msgstr "Todas as <0/> incluídas na sua assinatura."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:514
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:530
msgid "All <0/>, forever. No billing, no renewals."
msgstr "Todas as <0/>, para sempre. Sem cobranças nem renovações."
@@ -6469,7 +6469,7 @@ msgid "Cancel import"
msgstr "Cancelar importação"
#. Billing button that cancels a scheduled move to a lower subscription price.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:821
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:837
msgid "Cancel price change"
msgstr "Cancelar alteração de preço"
@@ -6484,14 +6484,14 @@ msgid "Cancel request"
msgstr "Cancelar solicitação"
#. Billing button that cancels a scheduled billing-cycle change.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:829
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:845
msgid "Cancel scheduled switch"
msgstr "Cancelar mudança agendada"
#. Billing button that starts subscription cancellation.
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:844
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:142
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:860
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:141
#: src/features/user/components/settings_utils/search_index/PlutoniumIndex.ts:31
msgid "Cancel subscription"
msgstr "Cancelar assinatura"
@@ -6501,7 +6501,7 @@ msgid "Cancel subscription?"
msgstr "Cancelar assinatura?"
#. Plutonium subscription card hint shown to a subscriber who could move to a lower price but has another billing change already scheduled.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:647
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:663
msgid "Cancel the scheduled change to move to the current price instead."
msgstr "Cancele a alteração agendada para mudar para o preço atual."
@@ -6511,7 +6511,7 @@ msgid "Cancel upload"
msgstr "Cancelar envio"
#. Billing button that cancels a scheduled yearly upgrade.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:825
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:841
msgid "Cancel yearly upgrade"
msgstr "Cancelar upgrade anual"
@@ -6530,7 +6530,7 @@ msgstr "Cancelando"
msgid "Cancellation"
msgstr "Cancelamento de eco"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:501
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:517
msgid "Cancels on <0>{cancelDate}</0>. <1/> remain active until then."
msgstr "O cancelamento ocorrerá em <0>{cancelDate}</0>. As <1/> permanecerão ativas até lá."
@@ -10872,7 +10872,7 @@ msgstr "Personalizado…"
#. Billing button that opens the external customer portal.
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:750
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:766
#: src/features/user/components/settings_utils/search_index/PlutoniumIndex.ts:39
msgid "Customer portal"
msgstr "Portal do cliente"
@@ -13877,15 +13877,15 @@ msgid "End date"
msgstr "Data final"
#. Billing button that ends premium grace period immediately.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:856
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:872
msgid "End grace now"
msgstr "Encerrar período de carência agora"
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:164
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:163
msgid "End grace period"
msgstr "Encerrar período de carência"
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:157
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:156
msgid "End grace period now?"
msgstr "Encerrar período de carência agora?"
@@ -16347,7 +16347,7 @@ msgstr "Presente: expira em breve"
msgid "Gift: grace period (still have access)"
msgstr "Presente: período de carência (ainda tem acesso)"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:486
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:502
msgid "Gifted <0/> until <1>{giftEndDate}</1>. Does not renew automatically. Redeem more gift codes to extend."
msgstr "<0/> recebidas de presente até <1>{giftEndDate}</1>. Não há renovação automática. Resgate mais códigos de presente para estender o prazo."
@@ -16826,7 +16826,7 @@ msgid "Hate speech"
msgstr "Discurso de ódio"
#. Premium page text shown on an instance where the premium tier cannot be bought, only redeemed. {PREMIUM_PRODUCT_NAME} is the premium tier name.
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:297
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:296
msgid "Have a gift code? Redeem it to unlock {PREMIUM_PRODUCT_NAME}."
msgstr "Tem um código de presente? Resgate-o para desbloquear {PREMIUM_PRODUCT_NAME}."
@@ -18926,7 +18926,7 @@ msgstr "Manter anexos ao limpar uma edição"
msgid "Keep free and premium tiers. You can customize the tiers, sell premium through Stripe, or hand out gift codes later from the admin panel."
msgstr "Mantenha os níveis gratuito e premium. Você pode personalizar os níveis, vender o premium via Stripe ou distribuir códigos de presente mais tarde no painel de administração."
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:166
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:165
msgid "Keep grace period"
msgstr "Manter período de carência"
@@ -18940,7 +18940,7 @@ msgstr "Manter Neko parado"
msgid "Keep running"
msgstr "Continuar em execução"
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:144
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:143
msgid "Keep subscription"
msgstr "Manter assinatura"
@@ -19297,8 +19297,8 @@ msgstr "Botão esquerdo do mouse"
msgid "Left tooltip"
msgstr "Dica esquerda"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:539
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:561
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:555
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:577
msgid "Legacy rate"
msgstr "Preço antigo"
@@ -21339,11 +21339,11 @@ msgstr "Mensal"
msgid "Monthly {monthlyPrice}"
msgstr "Mensal {monthlyPrice}"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:631
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:647
msgid "Monthly billing starts on <0>{pendingChangeDate}</0>."
msgstr "A cobrança mensal começa em <0>{pendingChangeDate}</0>."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:624
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:640
msgid "Monthly billing starts on <0>{pendingChangeDate}</0>. First monthly charge: {pendingInitialPriceLabel}. Future monthly renewals: {pendingRecurringPriceLabel}/month."
msgstr "A cobrança mensal começa em <0>{pendingChangeDate}</0>. Primeira cobrança mensal: {pendingInitialPriceLabel}. Renovações mensais futuras: {pendingRecurringPriceLabel}/mês."
@@ -22269,12 +22269,12 @@ msgid "New password"
msgstr "Nova senha"
#. Plutonium subscription card line shown when a move to a lower price is scheduled but the new amount is unknown. {pendingChangeDate} is a date already formatted and localized by code; never write a date into the translation.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:595
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:611
msgid "New price scheduled for <0>{pendingChangeDate}</0>."
msgstr "Novo preço agendado para <0>{pendingChangeDate}</0>."
#. Plutonium subscription card line shown when a move to a lower price is scheduled. {pendingChangeDate} is a date and {pendingTargetPriceLabel} is a currency amount, both already formatted and localized by code; never write a date or an amount into the translation.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:589
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:605
msgid "New price scheduled for <0>{pendingChangeDate}</0>. Renewals will be {pendingTargetPriceLabel} from then on."
msgstr "Novo preço agendado para <0>{pendingChangeDate}</0>. As renovações serão {pendingTargetPriceLabel} a partir de então."
@@ -26152,7 +26152,7 @@ msgstr "Reações"
#. Billing button that cancels a scheduled subscription cancellation.
#. Button label on the premium-expired nagbar. Opens billing so the user can reactivate their subscription.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:746
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:762
#: src/features/app/components/layout/app_layout/nagbars/PremiumExpiredNagbar.tsx:25
msgid "Reactivate"
msgstr "Reativar"
@@ -26375,8 +26375,8 @@ msgstr "Resgatar para você"
#. Billing button for entering a premium gift code.
#. Billing button for entering a premium gift code.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:719
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:307
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:735
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:306
msgid "Redeem gift code"
msgstr "Resgatar código de presente"
@@ -27147,7 +27147,7 @@ msgstr "Limite para renovação (dias)"
msgid "Renew window (days)"
msgstr "Período de renovação (dias)"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:701
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:717
msgid "Renews on <0>{renewalDate}.</0>"
msgstr "Renova em <0>{renewalDate}.</0>"
@@ -27896,8 +27896,8 @@ msgstr "Restaurar janela"
#. Billing button for restarting a subscription during the grace period.
#. Billing button for starting a new subscription after premium expired.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:738
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:742
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:754
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:758
msgid "Resubscribe"
msgstr "Assinar novamente"
@@ -32521,7 +32521,7 @@ msgid "Switch price"
msgstr "Mudar preço"
#. Billing button that opens confirmation to move the subscription down to the current price. {listPriceNewLabel} is the localized new price.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:806
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:822
msgid "Switch to {listPriceNewLabel}"
msgstr "Mudar para {listPriceNewLabel}"
@@ -32546,7 +32546,7 @@ msgstr "Mudar para entrada direta"
#. Billing button that opens confirmation to switch to monthly billing.
#. Button confirming a change to monthly subscription billing.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:57
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:789
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:805
msgid "Switch to monthly"
msgstr "Mudar para o plano mensal"
@@ -32615,7 +32615,7 @@ msgstr "Mudar para duas colunas"
#. Billing button that opens confirmation to switch to yearly billing.
#. Button confirming a change to yearly subscription billing.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:53
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:785
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:801
msgid "Switch to yearly"
msgstr "Mudar para o plano anual"
@@ -35865,7 +35865,7 @@ msgstr "Desbloqueie emojis personalizados em mensagens diretas com o {premiumPro
msgid "Unlock HD screen share with {premiumProductName}"
msgstr "Desbloqueie o compartilhamento de tela HD com {premiumProductName}"
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:217
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:216
msgid "Unlock higher limits and exclusive features while supporting an independent communication platform."
msgstr "Desbloqueie limites maiores e recursos exclusivos enquanto apoia uma plataforma de comunicação independente."
@@ -39015,15 +39015,15 @@ msgstr "Anual {yearlyPrice}"
msgid "Yearly gift"
msgstr "Presente anual"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:618
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:634
msgid "Yearly upgrade scheduled for <0>{pendingChangeDate}</0>."
msgstr "Upgrade anual agendado para <0>{pendingChangeDate}</0>."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:603
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:619
msgid "Yearly upgrade scheduled for <0>{pendingChangeDate}</0>. First yearly charge: {pendingInitialPriceLabel} after a {pendingCreditPriceLabel} credit. Future yearly renewals: {pendingRecurringPriceLabel}/year."
msgstr "Upgrade anual agendado para <0>{pendingChangeDate}</0>. Primeira cobrança anual: {pendingInitialPriceLabel} após um crédito de {pendingCreditPriceLabel}. Renovações anuais futuras: {pendingRecurringPriceLabel}/ano."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:610
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:626
msgid "Yearly upgrade scheduled for <0>{pendingChangeDate}</0>. First yearly charge: {pendingInitialPriceLabel}. Future yearly renewals: {pendingRecurringPriceLabel}/year."
msgstr "Upgrade anual agendado para <0>{pendingChangeDate}</0>. Primeira cobrança anual: {pendingInitialPriceLabel}. Renovações anuais futuras: {pendingRecurringPriceLabel}/ano."
@@ -39493,10 +39493,10 @@ msgid "You just pressed Tab. Keyboard mode is now on so you can navigate {produc
msgstr "Você acabou de pressionar Tab. O modo de teclado está ativado para que você possa navegar no {productName} sem um mouse."
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:137
msgid "You keep your perks until your next renewal date, then have a 3-day grace period to resubscribe and keep your subscriber history."
msgstr "Você mantém seus benefícios até a próxima data de renovação e, em seguida, tem um período de carência de 3 dias para assinar novamente e manter seu histórico de assinante."
msgid "You keep your perks until your next renewal date. Reactivate before then to keep your subscriber history."
msgstr "Você mantém seus benefícios até a próxima data de renovação. Reative sua assinatura antes disso para manter seu histórico de assinante."
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:159
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:158
msgid "You lose all {PREMIUM_PRODUCT_NAME} perks immediately and your subscriber history resets. This cannot be undone."
msgstr "Você perde todos os benefícios do {PREMIUM_PRODUCT_NAME} imediatamente e seu histórico de assinante é redefinido. Isso não pode ser desfeito."
@@ -40231,6 +40231,11 @@ msgstr "sua região"
msgid "Your registration needs an extra anti-spam check before you can continue."
msgstr "Seu cadastro precisa de uma verificação antispam extra antes de você continuar."
#. Plutonium subscription card text shown while a failed renewal payment is being retried. {graceDate} is a date already formatted and localized by code; never write a date into the translation.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:470
msgid "Your renewal payment failed but <0/> stay active until <1>{graceDate}</1>. Update your payment method before then to keep your subscription."
msgstr "O pagamento da renovação falhou, mas as <0/> continuam ativas até <1>{graceDate}</1>. Atualize sua forma de pagamento antes dessa data para manter sua assinatura."
#. Video settings note shown when the saved screen share quality is above what this account can send. Resolutions are short labels such as 1440p or Source and rates are whole numbers. FPS is a technical token.
#: src/features/user/components/modals/tabs/UserVideoTab.tsx:92
msgid "Your saved {savedResolution} at {savedFrameRate} FPS needs {premiumProductName}, so shares use {resolution} at {frameRate} FPS."
@@ -40252,7 +40257,7 @@ msgstr "Sua transmissão ainda está ativa"
msgid "Your subscription can't move to the new price right now."
msgstr "Sua assinatura não pode ser movida para o novo preço no momento."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:470
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:486
msgid "Your subscription ended but <0/> stay active until <1>{graceDate}</1>. Resubscribe before then to keep your subscriber history."
msgstr "Sua assinatura terminou, mas as <0/> continuam ativas até <1>{graceDate}</1>. Assine novamente antes dessa data para manter seu histórico de assinante."
@@ -40281,7 +40286,7 @@ msgstr "Sua assinatura foi alterada para cobrança mensal."
msgid "Your subscription has been switched to yearly billing."
msgstr "Sua assinatura foi alterada para cobrança anual."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:512
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:528
msgid "Your subscription is active but perks are temporarily paused."
msgstr "Sua assinatura está ativa, mas os benefícios estão temporariamente pausados."
@@ -40301,7 +40306,7 @@ msgid "Your subscription moves to the new price on {effectiveDate}."
msgstr "Sua assinatura muda para o novo preço em {effectiveDate}."
#. Plutonium subscription card line shown to a subscriber on a legacy price whose subscription is already set to cancel. {cancelDate} is a date and {listPriceNewLabel} is a currency amount, both already formatted and localized by code; never write a date or an amount into the translation.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:666
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:682
msgid "Your subscription still ends on <0>{cancelDate}</0>. The current price is now {listPriceNewLabel}. If you reactivate, you can switch to it from here."
msgstr "Sua assinatura ainda termina em <0>{cancelDate}</0>. O preço atual é {listPriceNewLabel}. Se você reativar, poderá mudar para ele a partir daqui."
@@ -2471,7 +2471,7 @@ msgid "A Linux desktop update is available. Choose the package format for this s
msgstr "Este disponibilă o actualizare desktop pentru Linux. Alege formatul de pachet pentru acest sistem, iar {productName} îl va salva local."
#. Plutonium subscription card line offering a move to a lower price. {listPriceEffectiveDate} is a date already formatted and localized by code; never write a date into the translation.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:684
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:700
msgid "A lower price is available. Switching takes effect on <0>{listPriceEffectiveDate}</0> and changes nothing else."
msgstr "Este disponibil un preț mai mic. Trecerea intră în vigoare pe <0>{listPriceEffectiveDate}</0> și nu schimbă nimic altceva."
@@ -3487,19 +3487,19 @@ msgstr "Comenzile de aliniere sunt disponibile doar pe ecrane mai late"
msgid "All"
msgstr "Toate"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:524
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:540
msgid "All <0/> for <1>{effectiveMonthlyPrice}/month</1>."
msgstr "Toate <0/> pentru <1>{effectiveMonthlyPrice}/lună</1>."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:546
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:562
msgid "All <0/> for <1>{effectiveYearlyPrice}/year</1>."
msgstr "Toate <0/> pentru <1>{effectiveYearlyPrice}/an</1>."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:567
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:583
msgid "All <0/> included with your subscription."
msgstr "Toate <0/> incluse în abonamentul tău."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:514
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:530
msgid "All <0/>, forever. No billing, no renewals."
msgstr "Toate <0/>, pentru totdeauna. Fără facturare, fără reînnoiri."
@@ -6469,7 +6469,7 @@ msgid "Cancel import"
msgstr "Anulează importul"
#. Billing button that cancels a scheduled move to a lower subscription price.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:821
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:837
msgid "Cancel price change"
msgstr "Anulează modificarea prețului"
@@ -6484,14 +6484,14 @@ msgid "Cancel request"
msgstr "Anulează cererea"
#. Billing button that cancels a scheduled billing-cycle change.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:829
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:845
msgid "Cancel scheduled switch"
msgstr "Anulează schimbarea programată"
#. Billing button that starts subscription cancellation.
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:844
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:142
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:860
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:141
#: src/features/user/components/settings_utils/search_index/PlutoniumIndex.ts:31
msgid "Cancel subscription"
msgstr "Anulează abonamentul"
@@ -6501,7 +6501,7 @@ msgid "Cancel subscription?"
msgstr "Anulezi abonamentul?"
#. Plutonium subscription card hint shown to a subscriber who could move to a lower price but has another billing change already scheduled.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:647
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:663
msgid "Cancel the scheduled change to move to the current price instead."
msgstr "Anulează modificarea programată pentru a trece la prețul curent."
@@ -6511,7 +6511,7 @@ msgid "Cancel upload"
msgstr "Anulează încărcarea"
#. Billing button that cancels a scheduled yearly upgrade.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:825
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:841
msgid "Cancel yearly upgrade"
msgstr "Anulează upgrade-ul anual"
@@ -6530,7 +6530,7 @@ msgstr "Se anulează"
msgid "Cancellation"
msgstr "Anulare ecou"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:501
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:517
msgid "Cancels on <0>{cancelDate}</0>. <1/> remain active until then."
msgstr "Se anulează pe <0>{cancelDate}</0>. <1/> rămân active până atunci."
@@ -10872,7 +10872,7 @@ msgstr "Personalizat…"
#. Billing button that opens the external customer portal.
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:750
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:766
#: src/features/user/components/settings_utils/search_index/PlutoniumIndex.ts:39
msgid "Customer portal"
msgstr "Portal pentru clienți"
@@ -13877,15 +13877,15 @@ msgid "End date"
msgstr "Data de încheiere"
#. Billing button that ends premium grace period immediately.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:856
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:872
msgid "End grace now"
msgstr "Încheie perioada de grație acum"
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:164
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:163
msgid "End grace period"
msgstr "Încheie perioada de grație"
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:157
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:156
msgid "End grace period now?"
msgstr "Închei perioada de grație acum?"
@@ -16347,7 +16347,7 @@ msgstr "Cadou: expiră în curând"
msgid "Gift: grace period (still have access)"
msgstr "Cadou: perioadă de grație (încă ai acces)"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:486
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:502
msgid "Gifted <0/> until <1>{giftEndDate}</1>. Does not renew automatically. Redeem more gift codes to extend."
msgstr "Ai primit cadou <0/> până la <1>{giftEndDate}</1>. Nu se reînnoiește automat. Valorifică mai multe coduri cadou pentru a prelungi."
@@ -16826,7 +16826,7 @@ msgid "Hate speech"
msgstr "Discurs instigator la ură"
#. Premium page text shown on an instance where the premium tier cannot be bought, only redeemed. {PREMIUM_PRODUCT_NAME} is the premium tier name.
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:297
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:296
msgid "Have a gift code? Redeem it to unlock {PREMIUM_PRODUCT_NAME}."
msgstr "Ai un cod cadou? Valorifică-l pentru a debloca {PREMIUM_PRODUCT_NAME}."
@@ -18926,7 +18926,7 @@ msgstr "Păstrează atașamentele la ștergerea unei editări"
msgid "Keep free and premium tiers. You can customize the tiers, sell premium through Stripe, or hand out gift codes later from the admin panel."
msgstr "Păstrează nivelurile gratuit și premium. Poți personaliza nivelurile, poți vinde premium prin Stripe sau poți oferi ulterior coduri cadou din panoul de administrare."
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:166
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:165
msgid "Keep grace period"
msgstr "Păstrează perioada de grație"
@@ -18940,7 +18940,7 @@ msgstr "Ține Neko nemișcat"
msgid "Keep running"
msgstr "Rulează în fundal"
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:144
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:143
msgid "Keep subscription"
msgstr "Păstrează abonamentul"
@@ -19297,8 +19297,8 @@ msgstr "Butonul stâng al mouse-ului"
msgid "Left tooltip"
msgstr "Sfat din stânga"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:539
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:561
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:555
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:577
msgid "Legacy rate"
msgstr "Tarif vechi"
@@ -21339,11 +21339,11 @@ msgstr "Lunar"
msgid "Monthly {monthlyPrice}"
msgstr "Lunar {monthlyPrice}"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:631
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:647
msgid "Monthly billing starts on <0>{pendingChangeDate}</0>."
msgstr "Facturarea lunară începe la <0>{pendingChangeDate}</0>."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:624
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:640
msgid "Monthly billing starts on <0>{pendingChangeDate}</0>. First monthly charge: {pendingInitialPriceLabel}. Future monthly renewals: {pendingRecurringPriceLabel}/month."
msgstr "Facturarea lunară începe la <0>{pendingChangeDate}</0>. Prima taxă lunară: {pendingInitialPriceLabel}. Reînnoiri lunare viitoare: {pendingRecurringPriceLabel}/lună."
@@ -22269,12 +22269,12 @@ msgid "New password"
msgstr "Parolă nouă"
#. Plutonium subscription card line shown when a move to a lower price is scheduled but the new amount is unknown. {pendingChangeDate} is a date already formatted and localized by code; never write a date into the translation.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:595
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:611
msgid "New price scheduled for <0>{pendingChangeDate}</0>."
msgstr "Preț nou programat pentru <0>{pendingChangeDate}</0>."
#. Plutonium subscription card line shown when a move to a lower price is scheduled. {pendingChangeDate} is a date and {pendingTargetPriceLabel} is a currency amount, both already formatted and localized by code; never write a date or an amount into the translation.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:589
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:605
msgid "New price scheduled for <0>{pendingChangeDate}</0>. Renewals will be {pendingTargetPriceLabel} from then on."
msgstr "Preț nou programat pentru <0>{pendingChangeDate}</0>. Reînnoirile vor fi {pendingTargetPriceLabel} de atunci înainte."
@@ -26152,7 +26152,7 @@ msgstr "Reacții"
#. Billing button that cancels a scheduled subscription cancellation.
#. Button label on the premium-expired nagbar. Opens billing so the user can reactivate their subscription.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:746
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:762
#: src/features/app/components/layout/app_layout/nagbars/PremiumExpiredNagbar.tsx:25
msgid "Reactivate"
msgstr "Reactivează"
@@ -26375,8 +26375,8 @@ msgstr "Valorifică pentru tine"
#. Billing button for entering a premium gift code.
#. Billing button for entering a premium gift code.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:719
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:307
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:735
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:306
msgid "Redeem gift code"
msgstr "Valorifică codul cadou"
@@ -27147,7 +27147,7 @@ msgstr "Prag de reînnoire (zile)"
msgid "Renew window (days)"
msgstr "Interval de reînnoire (zile)"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:701
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:717
msgid "Renews on <0>{renewalDate}.</0>"
msgstr "Se reînnoiește la <0>{renewalDate}.</0>"
@@ -27896,8 +27896,8 @@ msgstr "Restabilește fereastra"
#. Billing button for restarting a subscription during the grace period.
#. Billing button for starting a new subscription after premium expired.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:738
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:742
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:754
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:758
msgid "Resubscribe"
msgstr "Reabonează-te"
@@ -32521,7 +32521,7 @@ msgid "Switch price"
msgstr "Schimbă prețul"
#. Billing button that opens confirmation to move the subscription down to the current price. {listPriceNewLabel} is the localized new price.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:806
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:822
msgid "Switch to {listPriceNewLabel}"
msgstr "Treci la {listPriceNewLabel}"
@@ -32546,7 +32546,7 @@ msgstr "Treci la intrarea directă"
#. Billing button that opens confirmation to switch to monthly billing.
#. Button confirming a change to monthly subscription billing.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:57
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:789
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:805
msgid "Switch to monthly"
msgstr "Treci la abonamentul lunar"
@@ -32615,7 +32615,7 @@ msgstr "Treci la două coloane"
#. Billing button that opens confirmation to switch to yearly billing.
#. Button confirming a change to yearly subscription billing.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:53
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:785
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:801
msgid "Switch to yearly"
msgstr "Treci la abonamentul anual"
@@ -35865,7 +35865,7 @@ msgstr "Deblochează emoji-urile personalizate în DM-uri cu {premiumProductName
msgid "Unlock HD screen share with {premiumProductName}"
msgstr "Deblochează partajarea ecranului HD cu {premiumProductName}"
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:217
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:216
msgid "Unlock higher limits and exclusive features while supporting an independent communication platform."
msgstr "Deblochează limite mai mari și funcții exclusive, susținând în același timp o platformă de comunicare independentă."
@@ -39015,15 +39015,15 @@ msgstr "Anual {yearlyPrice}"
msgid "Yearly gift"
msgstr "Cadou anual"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:618
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:634
msgid "Yearly upgrade scheduled for <0>{pendingChangeDate}</0>."
msgstr "Upgrade anual programat pentru <0>{pendingChangeDate}</0>."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:603
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:619
msgid "Yearly upgrade scheduled for <0>{pendingChangeDate}</0>. First yearly charge: {pendingInitialPriceLabel} after a {pendingCreditPriceLabel} credit. Future yearly renewals: {pendingRecurringPriceLabel}/year."
msgstr "Upgrade anual programat pentru <0>{pendingChangeDate}</0>. Prima taxă anuală: {pendingInitialPriceLabel} după un credit de {pendingCreditPriceLabel}. Reînnoiri anuale viitoare: {pendingRecurringPriceLabel}/an."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:610
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:626
msgid "Yearly upgrade scheduled for <0>{pendingChangeDate}</0>. First yearly charge: {pendingInitialPriceLabel}. Future yearly renewals: {pendingRecurringPriceLabel}/year."
msgstr "Upgrade anual programat pentru <0>{pendingChangeDate}</0>. Prima taxă anuală: {pendingInitialPriceLabel}. Reînnoiri anuale viitoare: {pendingRecurringPriceLabel}/an."
@@ -39493,10 +39493,10 @@ msgid "You just pressed Tab. Keyboard mode is now on so you can navigate {produc
msgstr "Tocmai ai apăsat Tab. Modul tastatură este acum activ, ca să poți naviga în {productName} fără mouse."
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:137
msgid "You keep your perks until your next renewal date, then have a 3-day grace period to resubscribe and keep your subscriber history."
msgstr "Îți păstrezi beneficiile până la următoarea dată de reînnoire, apoi ai o perioadă de grație de 3 zile pentru a te reabona și a-ți păstra istoricul de abonat."
msgid "You keep your perks until your next renewal date. Reactivate before then to keep your subscriber history."
msgstr "Îți păstrezi beneficiile până la următoarea dată de reînnoire. Reactivează abonamentul înainte de această dată pentru a-ți păstra istoricul de abonat."
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:159
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:158
msgid "You lose all {PREMIUM_PRODUCT_NAME} perks immediately and your subscriber history resets. This cannot be undone."
msgstr "Pierzi imediat toate beneficiile {PREMIUM_PRODUCT_NAME}, iar istoricul tău de abonat se resetează. Această acțiune nu poate fi anulată."
@@ -40231,6 +40231,11 @@ msgstr "regiunea ta"
msgid "Your registration needs an extra anti-spam check before you can continue."
msgstr "Înregistrarea ta necesită o verificare anti-spam suplimentară înainte de a putea continua."
#. Plutonium subscription card text shown while a failed renewal payment is being retried. {graceDate} is a date already formatted and localized by code; never write a date into the translation.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:470
msgid "Your renewal payment failed but <0/> stay active until <1>{graceDate}</1>. Update your payment method before then to keep your subscription."
msgstr "Plata pentru reînnoire a eșuat, dar <0/> rămân active până la <1>{graceDate}</1>. Actualizează-ți metoda de plată înainte de această dată pentru a-ți păstra abonamentul."
#. Video settings note shown when the saved screen share quality is above what this account can send. Resolutions are short labels such as 1440p or Source and rates are whole numbers. FPS is a technical token.
#: src/features/user/components/modals/tabs/UserVideoTab.tsx:92
msgid "Your saved {savedResolution} at {savedFrameRate} FPS needs {premiumProductName}, so shares use {resolution} at {frameRate} FPS."
@@ -40252,7 +40257,7 @@ msgstr "Streamul tău este încă live"
msgid "Your subscription can't move to the new price right now."
msgstr "Abonamentul tău nu poate fi mutat la noul preț momentan."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:470
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:486
msgid "Your subscription ended but <0/> stay active until <1>{graceDate}</1>. Resubscribe before then to keep your subscriber history."
msgstr "Abonamentul tău s-a încheiat, dar <0/> rămân active până la <1>{graceDate}</1>. Reabonează-te înainte de această dată pentru a-ți păstra istoricul de abonat."
@@ -40281,7 +40286,7 @@ msgstr "Abonamentul tău a fost trecut la facturarea lunară."
msgid "Your subscription has been switched to yearly billing."
msgstr "Abonamentul tău a fost trecut la facturarea anuală."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:512
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:528
msgid "Your subscription is active but perks are temporarily paused."
msgstr "Abonamentul tău este activ, dar beneficiile sunt întrerupte temporar."
@@ -40301,7 +40306,7 @@ msgid "Your subscription moves to the new price on {effectiveDate}."
msgstr "Abonamentul tău trece la noul preț pe {effectiveDate}."
#. Plutonium subscription card line shown to a subscriber on a legacy price whose subscription is already set to cancel. {cancelDate} is a date and {listPriceNewLabel} is a currency amount, both already formatted and localized by code; never write a date or an amount into the translation.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:666
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:682
msgid "Your subscription still ends on <0>{cancelDate}</0>. The current price is now {listPriceNewLabel}. If you reactivate, you can switch to it from here."
msgstr "Abonamentul tău se încheie tot pe <0>{cancelDate}</0>. Prețul curent este acum {listPriceNewLabel}. Dacă reactivezi abonamentul, poți trece la el de aici."
@@ -2471,7 +2471,7 @@ msgid "A Linux desktop update is available. Choose the package format for this s
msgstr "Доступно обновление для Linux. Выберите формат пакета для этой системы, и {productName} сохранит его локально."
#. Plutonium subscription card line offering a move to a lower price. {listPriceEffectiveDate} is a date already formatted and localized by code; never write a date into the translation.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:684
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:700
msgid "A lower price is available. Switching takes effect on <0>{listPriceEffectiveDate}</0> and changes nothing else."
msgstr "Доступна более низкая цена. Переход вступит в силу <0>{listPriceEffectiveDate}</0>, и больше ничего не изменится."
@@ -3487,19 +3487,19 @@ msgstr "Настройки выравнивания доступны тольк
msgid "All"
msgstr "Все"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:524
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:540
msgid "All <0/> for <1>{effectiveMonthlyPrice}/month</1>."
msgstr "Все <0/> за <1>{effectiveMonthlyPrice}/месяц</1>."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:546
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:562
msgid "All <0/> for <1>{effectiveYearlyPrice}/year</1>."
msgstr "Все <0/> за <1>{effectiveYearlyPrice}/год</1>."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:567
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:583
msgid "All <0/> included with your subscription."
msgstr "Все <0/> включены в вашу подписку."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:514
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:530
msgid "All <0/>, forever. No billing, no renewals."
msgstr "Все <0/>, навсегда. Без платежей и продлений."
@@ -6469,7 +6469,7 @@ msgid "Cancel import"
msgstr "Отменить импорт"
#. Billing button that cancels a scheduled move to a lower subscription price.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:821
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:837
msgid "Cancel price change"
msgstr "Отменить изменение цены"
@@ -6484,14 +6484,14 @@ msgid "Cancel request"
msgstr "Отменить запрос"
#. Billing button that cancels a scheduled billing-cycle change.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:829
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:845
msgid "Cancel scheduled switch"
msgstr "Отменить запланированный переход"
#. Billing button that starts subscription cancellation.
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:844
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:142
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:860
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:141
#: src/features/user/components/settings_utils/search_index/PlutoniumIndex.ts:31
msgid "Cancel subscription"
msgstr "Отменить подписку"
@@ -6501,7 +6501,7 @@ msgid "Cancel subscription?"
msgstr "Отменить подписку?"
#. Plutonium subscription card hint shown to a subscriber who could move to a lower price but has another billing change already scheduled.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:647
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:663
msgid "Cancel the scheduled change to move to the current price instead."
msgstr "Отменить запланированное изменение и перейти на текущую цену."
@@ -6511,7 +6511,7 @@ msgid "Cancel upload"
msgstr "Отменить загрузку"
#. Billing button that cancels a scheduled yearly upgrade.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:825
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:841
msgid "Cancel yearly upgrade"
msgstr "Отменить переход на годовую подписку"
@@ -6530,7 +6530,7 @@ msgstr "Отмена подписки"
msgid "Cancellation"
msgstr "Эхоподавление"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:501
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:517
msgid "Cancels on <0>{cancelDate}</0>. <1/> remain active until then."
msgstr "Подписка отменяется <0>{cancelDate}</0>. <1/> остаются активными до этой даты."
@@ -10872,7 +10872,7 @@ msgstr "Другое…"
#. Billing button that opens the external customer portal.
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:750
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:766
#: src/features/user/components/settings_utils/search_index/PlutoniumIndex.ts:39
msgid "Customer portal"
msgstr "Личный кабинет клиента"
@@ -13877,15 +13877,15 @@ msgid "End date"
msgstr "Дата окончания"
#. Billing button that ends premium grace period immediately.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:856
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:872
msgid "End grace now"
msgstr "Завершить льготный период"
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:164
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:163
msgid "End grace period"
msgstr "Завершить льготный период"
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:157
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:156
msgid "End grace period now?"
msgstr "Завершить льготный период сейчас?"
@@ -16347,7 +16347,7 @@ msgstr "Подарок: срок действия скоро истекает"
msgid "Gift: grace period (still have access)"
msgstr "Подарок: льготный период (доступ сохранён)"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:486
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:502
msgid "Gifted <0/> until <1>{giftEndDate}</1>. Does not renew automatically. Redeem more gift codes to extend."
msgstr "Подарено <0/> до <1>{giftEndDate}</1>. Не продлевается автоматически. Активируйте больше подарочных кодов, чтобы продлить."
@@ -16826,7 +16826,7 @@ msgid "Hate speech"
msgstr "Разжигание ненависти"
#. Premium page text shown on an instance where the premium tier cannot be bought, only redeemed. {PREMIUM_PRODUCT_NAME} is the premium tier name.
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:297
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:296
msgid "Have a gift code? Redeem it to unlock {PREMIUM_PRODUCT_NAME}."
msgstr "Есть подарочный код? Активируйте его, чтобы разблокировать {PREMIUM_PRODUCT_NAME}."
@@ -18926,7 +18926,7 @@ msgstr "Сохранять вложения при очистке редакти
msgid "Keep free and premium tiers. You can customize the tiers, sell premium through Stripe, or hand out gift codes later from the admin panel."
msgstr "Сохраняйте бесплатные и премиум-уровни. Вы можете настроить уровни, продавать премиум через Stripe или позже раздавать подарочные коды из панели администратора."
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:166
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:165
msgid "Keep grace period"
msgstr "Сохранить льготный период"
@@ -18940,7 +18940,7 @@ msgstr "Остановить Неко"
msgid "Keep running"
msgstr "Работать в фоне"
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:144
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:143
msgid "Keep subscription"
msgstr "Оставить подписку"
@@ -19297,8 +19297,8 @@ msgstr "Левая кнопка мыши"
msgid "Left tooltip"
msgstr "Подсказка слева"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:539
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:561
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:555
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:577
msgid "Legacy rate"
msgstr "Старый тариф"
@@ -21339,11 +21339,11 @@ msgstr "Ежемесячно"
msgid "Monthly {monthlyPrice}"
msgstr "В месяц {monthlyPrice}"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:631
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:647
msgid "Monthly billing starts on <0>{pendingChangeDate}</0>."
msgstr "Ежемесячная оплата начнется <0>{pendingChangeDate}</0>."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:624
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:640
msgid "Monthly billing starts on <0>{pendingChangeDate}</0>. First monthly charge: {pendingInitialPriceLabel}. Future monthly renewals: {pendingRecurringPriceLabel}/month."
msgstr "Ежемесячная оплата начнется <0>{pendingChangeDate}</0>. Первый ежемесячный платеж: {pendingInitialPriceLabel}. Последующие ежемесячные продления: {pendingRecurringPriceLabel}/месяц."
@@ -22269,12 +22269,12 @@ msgid "New password"
msgstr "Новый пароль"
#. Plutonium subscription card line shown when a move to a lower price is scheduled but the new amount is unknown. {pendingChangeDate} is a date already formatted and localized by code; never write a date into the translation.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:595
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:611
msgid "New price scheduled for <0>{pendingChangeDate}</0>."
msgstr "Новая цена запланирована на <0>{pendingChangeDate}</0>."
#. Plutonium subscription card line shown when a move to a lower price is scheduled. {pendingChangeDate} is a date and {pendingTargetPriceLabel} is a currency amount, both already formatted and localized by code; never write a date or an amount into the translation.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:589
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:605
msgid "New price scheduled for <0>{pendingChangeDate}</0>. Renewals will be {pendingTargetPriceLabel} from then on."
msgstr "Новая цена запланирована на <0>{pendingChangeDate}</0>. С этого момента продление будет стоить {pendingTargetPriceLabel}."
@@ -26152,7 +26152,7 @@ msgstr "Реакции"
#. Billing button that cancels a scheduled subscription cancellation.
#. Button label on the premium-expired nagbar. Opens billing so the user can reactivate their subscription.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:746
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:762
#: src/features/app/components/layout/app_layout/nagbars/PremiumExpiredNagbar.tsx:25
msgid "Reactivate"
msgstr "Возобновить"
@@ -26375,8 +26375,8 @@ msgstr "Активировать для себя"
#. Billing button for entering a premium gift code.
#. Billing button for entering a premium gift code.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:719
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:307
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:735
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:306
msgid "Redeem gift code"
msgstr "Активировать подарочный код"
@@ -27147,7 +27147,7 @@ msgstr "Порог продления (дней)"
msgid "Renew window (days)"
msgstr "Период продления (дней)"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:701
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:717
msgid "Renews on <0>{renewalDate}.</0>"
msgstr "Продлевается <0>{renewalDate}.</0>"
@@ -27896,8 +27896,8 @@ msgstr "Восстановить окно"
#. Billing button for restarting a subscription during the grace period.
#. Billing button for starting a new subscription after premium expired.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:738
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:742
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:754
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:758
msgid "Resubscribe"
msgstr "Подписаться снова"
@@ -32521,7 +32521,7 @@ msgid "Switch price"
msgstr "Сменить цену"
#. Billing button that opens confirmation to move the subscription down to the current price. {listPriceNewLabel} is the localized new price.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:806
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:822
msgid "Switch to {listPriceNewLabel}"
msgstr "Переключиться на {listPriceNewLabel}"
@@ -32546,7 +32546,7 @@ msgstr "Переключиться на прямой ввод"
#. Billing button that opens confirmation to switch to monthly billing.
#. Button confirming a change to monthly subscription billing.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:57
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:789
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:805
msgid "Switch to monthly"
msgstr "Перейти на ежемесячную оплату"
@@ -32615,7 +32615,7 @@ msgstr "Переключиться на две колонки"
#. Billing button that opens confirmation to switch to yearly billing.
#. Button confirming a change to yearly subscription billing.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:53
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:785
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:801
msgid "Switch to yearly"
msgstr "Перейти на годовую оплату"
@@ -35865,7 +35865,7 @@ msgstr "Разблокируйте пользовательские эмодзи
msgid "Unlock HD screen share with {premiumProductName}"
msgstr "Разблокируйте демонстрацию экрана в HD с {premiumProductName}"
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:217
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:216
msgid "Unlock higher limits and exclusive features while supporting an independent communication platform."
msgstr "Откройте более высокие лимиты и эксклюзивные функции, поддерживая независимую платформу для общения."
@@ -39015,15 +39015,15 @@ msgstr "В год {yearlyPrice}"
msgid "Yearly gift"
msgstr "Ежегодный подарок"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:618
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:634
msgid "Yearly upgrade scheduled for <0>{pendingChangeDate}</0>."
msgstr "Переход на годовую подписку запланирован на <0>{pendingChangeDate}</0>."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:603
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:619
msgid "Yearly upgrade scheduled for <0>{pendingChangeDate}</0>. First yearly charge: {pendingInitialPriceLabel} after a {pendingCreditPriceLabel} credit. Future yearly renewals: {pendingRecurringPriceLabel}/year."
msgstr "Переход на годовую подписку запланирован на <0>{pendingChangeDate}</0>. Первая годовая плата: {pendingInitialPriceLabel} с учётом скидки {pendingCreditPriceLabel}. Последующие ежегодные продления: {pendingRecurringPriceLabel}/год."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:610
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:626
msgid "Yearly upgrade scheduled for <0>{pendingChangeDate}</0>. First yearly charge: {pendingInitialPriceLabel}. Future yearly renewals: {pendingRecurringPriceLabel}/year."
msgstr "Переход на годовую подписку запланирован на <0>{pendingChangeDate}</0>. Первая годовая плата: {pendingInitialPriceLabel}. Последующие ежегодные продления: {pendingRecurringPriceLabel}/год."
@@ -39493,10 +39493,10 @@ msgid "You just pressed Tab. Keyboard mode is now on so you can navigate {produc
msgstr "Вы только что нажали Tab. Режим клавиатуры включен, теперь вы можете перемещаться по {productName} без мыши."
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:137
msgid "You keep your perks until your next renewal date, then have a 3-day grace period to resubscribe and keep your subscriber history."
msgstr "Вы сохраните свои преимущества до следующей даты продления, а затем у вас будет 3 дня льготного периода, чтобы повторно подписаться и сохранить историю подписок."
msgid "You keep your perks until your next renewal date. Reactivate before then to keep your subscriber history."
msgstr "Вы сохраните свои преимущества до следующей даты продления. Возобновите подписку до этой даты, чтобы сохранить историю подписок."
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:159
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:158
msgid "You lose all {PREMIUM_PRODUCT_NAME} perks immediately and your subscriber history resets. This cannot be undone."
msgstr "Вы немедленно потеряете все преимущества {PREMIUM_PRODUCT_NAME}, а история вашей подписки будет сброшена. Это действие невозможно отменить."
@@ -40231,6 +40231,11 @@ msgstr "ваш регион"
msgid "Your registration needs an extra anti-spam check before you can continue."
msgstr "Чтобы продолжить, нужно пройти дополнительную антиспам-проверку."
#. Plutonium subscription card text shown while a failed renewal payment is being retried. {graceDate} is a date already formatted and localized by code; never write a date into the translation.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:470
msgid "Your renewal payment failed but <0/> stay active until <1>{graceDate}</1>. Update your payment method before then to keep your subscription."
msgstr "Платёж за продление не прошёл, но <0/> остаются активными до <1>{graceDate}</1>. Обновите способ оплаты до этой даты, чтобы сохранить подписку."
#. Video settings note shown when the saved screen share quality is above what this account can send. Resolutions are short labels such as 1440p or Source and rates are whole numbers. FPS is a technical token.
#: src/features/user/components/modals/tabs/UserVideoTab.tsx:92
msgid "Your saved {savedResolution} at {savedFrameRate} FPS needs {premiumProductName}, so shares use {resolution} at {frameRate} FPS."
@@ -40252,7 +40257,7 @@ msgstr "Ваша трансляция продолжается"
msgid "Your subscription can't move to the new price right now."
msgstr "Ваша подписка не может быть переведена на новую цену прямо сейчас."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:470
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:486
msgid "Your subscription ended but <0/> stay active until <1>{graceDate}</1>. Resubscribe before then to keep your subscriber history."
msgstr "Срок вашей подписки истёк, но <0/> остаются активными до <1>{graceDate}</1>. Оформите подписку повторно до этой даты, чтобы сохранить историю подписок."
@@ -40281,7 +40286,7 @@ msgstr "Ваша подписка переведена на ежемесячну
msgid "Your subscription has been switched to yearly billing."
msgstr "Ваша подписка переведена на годовую оплату."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:512
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:528
msgid "Your subscription is active but perks are temporarily paused."
msgstr "Ваша подписка активна, но привилегии временно приостановлены."
@@ -40301,7 +40306,7 @@ msgid "Your subscription moves to the new price on {effectiveDate}."
msgstr "Ваша подписка перейдет на новую цену {effectiveDate}."
#. Plutonium subscription card line shown to a subscriber on a legacy price whose subscription is already set to cancel. {cancelDate} is a date and {listPriceNewLabel} is a currency amount, both already formatted and localized by code; never write a date or an amount into the translation.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:666
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:682
msgid "Your subscription still ends on <0>{cancelDate}</0>. The current price is now {listPriceNewLabel}. If you reactivate, you can switch to it from here."
msgstr "Ваша подписка всё равно закончится <0>{cancelDate}</0>. Теперь текущая цена — {listPriceNewLabel}. Если вы возобновите подписку, вы сможете переключиться на неё здесь."

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