mirror of
https://github.com/HeyPuter/puter.git
synced 2026-11-13 20:12:57 -10:00
Compare commits
16
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5c406a5174 | ||
|
|
1b36805301 | ||
|
|
163dfd737c | ||
|
|
d1fc58c29a | ||
|
|
7ee0075186 | ||
|
|
bbeb984a91 | ||
|
|
fce5d2b08b | ||
|
|
3def512a9d | ||
|
|
a920b9782f | ||
|
|
454f94fc54 | ||
|
|
8b7d380de1 | ||
|
|
8052a4287e | ||
|
|
f114b13306 | ||
|
|
ce70728eeb | ||
|
|
8518023b0b | ||
|
|
33988ac84c |
No files matched your search
@@ -125,7 +125,6 @@ describe('core without a teams registration', () => {
|
||||
actor: { user: row },
|
||||
} as never,
|
||||
{ title: 'Puter' } as never,
|
||||
{} as never,
|
||||
);
|
||||
const params = JSON.parse(
|
||||
/gui\((\{.*?\})\);/s.exec(html)![1].replaceAll('\\u003c', '<'),
|
||||
|
||||
@@ -874,8 +874,11 @@ export type EventMap = {
|
||||
session_uids: string[];
|
||||
};
|
||||
|
||||
/** One access token was revoked; only its own connections should drop. */
|
||||
'auth.access-token.revoked': { token_uid: string };
|
||||
/**
|
||||
* One access token was revoked; only its own connections should drop.
|
||||
* `outer.*` for the same reason as `outer.auth.sessions.revoked`.
|
||||
*/
|
||||
'outer.auth.access-token.revoked': { token_uid: string };
|
||||
|
||||
/** Same-cluster eviction for raw realtime WebSockets. */
|
||||
'pubsub.realtime.auth-revoked': {
|
||||
|
||||
@@ -23,6 +23,7 @@ import { makeActor } from '../../core/actor.js';
|
||||
import { runWithContext } from '../../core/context.js';
|
||||
import { createSecret as otpCreateSecret } from '../../services/auth/OTPUtil.js';
|
||||
import { FULL_API_ACCESS } from '../../services/permission/consts.js';
|
||||
import { tokenClaimsDigest } from '../../../gui/src/helpers/guiToken.js';
|
||||
import {
|
||||
createTestUser,
|
||||
setupPuterTestEnv,
|
||||
@@ -714,4 +715,67 @@ describe('session token helpers over HTTP', () => {
|
||||
'puter_auth_token=',
|
||||
);
|
||||
});
|
||||
|
||||
describe("the shell's guiTokenDigest", () => {
|
||||
/** The session cookie `/session/sync-cookie` sets for `token`. */
|
||||
const sessionCookie = async (token: string) => {
|
||||
const sync = await get('/session/sync-cookie', token);
|
||||
expect(sync.status).toBe(204);
|
||||
const value = /puter_auth_token=([^;]+)/.exec(
|
||||
sync.headers.get('set-cookie') ?? '',
|
||||
)?.[1];
|
||||
expect(value).toBeTruthy();
|
||||
return `puter_auth_token=${value}`;
|
||||
};
|
||||
|
||||
/** What the shell at `path` renders for `guiTokenDigest`. */
|
||||
const shellDigest = async (path: string, cookie?: string) => {
|
||||
const res = await fetch(new URL(path, env.origin), {
|
||||
headers: cookie ? { cookie } : {},
|
||||
});
|
||||
expect(res.status).toBe(200);
|
||||
const html = await res.text();
|
||||
const match = /"guiTokenDigest":(null|"[0-9a-f]{32}")/.exec(html);
|
||||
if (!match) {
|
||||
expect(html).not.toContain('guiTokenDigest');
|
||||
return undefined;
|
||||
}
|
||||
return JSON.parse(match[1]) as string | null;
|
||||
};
|
||||
|
||||
it("names the token /get-gui-token hands over for the session cookie", async () => {
|
||||
const { token } = await signupTemp();
|
||||
const cookie = await sessionCookie(token);
|
||||
|
||||
const gui = await fetch(new URL('/get-gui-token', env.origin), {
|
||||
headers: { cookie },
|
||||
});
|
||||
expect(gui.status).toBe(200);
|
||||
const { token: guiToken } = (await gui.json()) as { token: string };
|
||||
|
||||
const digest = await shellDigest('/', cookie);
|
||||
expect(digest).toBe(await tokenClaimsDigest(guiToken));
|
||||
// The token the browser stored at sign-up is for the same session.
|
||||
expect(await tokenClaimsDigest(token)).toBe(digest);
|
||||
});
|
||||
|
||||
it('is null without a session cookie, even with a token in the URL', async () => {
|
||||
const { token } = await signupTemp();
|
||||
expect(await shellDigest('/')).toBe(null);
|
||||
expect(
|
||||
await shellDigest(`/?auth_token=${encodeURIComponent(token)}`),
|
||||
).toBe(null);
|
||||
});
|
||||
|
||||
it('is left out when the session cookie does not resolve to a session', async () => {
|
||||
const { token } = await signupTemp();
|
||||
const cookie = await sessionCookie(token);
|
||||
await env.server.services.auth.revokeSession(claims(token).session_uid);
|
||||
|
||||
expect(await shellDigest('/', cookie)).toBe(undefined);
|
||||
expect(await shellDigest('/', 'puter_auth_token=garbage')).toBe(
|
||||
undefined,
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -79,6 +79,7 @@ interface CapturedResponse {
|
||||
statusCode: number;
|
||||
body: unknown;
|
||||
contentType?: string;
|
||||
location?: string;
|
||||
}
|
||||
|
||||
const makeReq = (init: {
|
||||
@@ -87,6 +88,7 @@ const makeReq = (init: {
|
||||
actor?: Actor;
|
||||
hostname?: string;
|
||||
protocol?: string;
|
||||
originalUrl?: string;
|
||||
}): Request => {
|
||||
return {
|
||||
body: {},
|
||||
@@ -94,6 +96,7 @@ const makeReq = (init: {
|
||||
headers: {},
|
||||
params: init.params ?? {},
|
||||
path: init.path ?? '/',
|
||||
originalUrl: init.originalUrl ?? init.path ?? '/',
|
||||
hostname: init.hostname ?? 'test.local',
|
||||
protocol: init.protocol ?? 'http',
|
||||
actor: init.actor,
|
||||
@@ -131,6 +134,11 @@ const makeRes = () => {
|
||||
captured.contentType = value;
|
||||
return res;
|
||||
}),
|
||||
redirect: vi.fn((location: string) => {
|
||||
captured.statusCode = 302;
|
||||
captured.location = location;
|
||||
return res;
|
||||
}),
|
||||
};
|
||||
return { res: res as unknown as Response, captured };
|
||||
};
|
||||
@@ -214,23 +222,72 @@ describe('HomepageController shell routes', () => {
|
||||
expect(String(captured.body)).toMatch(/<!DOCTYPE html>/i);
|
||||
});
|
||||
|
||||
it('serves the shell on /settings, /dashboard, /desktop, /action, /@:username', async () => {
|
||||
for (const path of [
|
||||
'/settings',
|
||||
'/settings/*splat',
|
||||
'/dashboard',
|
||||
'/dashboard/',
|
||||
'/desktop',
|
||||
'/desktop/',
|
||||
'/action/*splat',
|
||||
'/@:username',
|
||||
]) {
|
||||
it('leaves guiTokenDigest out for a session cookie that is not a user session', async () => {
|
||||
const { actor } = await makeUser();
|
||||
const appActor = {
|
||||
...actor,
|
||||
app: { id: 1, uid: 'app-test' },
|
||||
session: { uid: uuidv4() },
|
||||
} as unknown as Actor;
|
||||
const req = Object.assign(makeReq({ path: '/', actor: appActor }), {
|
||||
tokenSource: 'cookie',
|
||||
cookies: { puter_token_v2: 'legacy' },
|
||||
});
|
||||
const { res, captured } = makeRes();
|
||||
await callRoute('get', '/', req, res);
|
||||
expect(String(captured.body)).not.toContain('guiTokenDigest');
|
||||
});
|
||||
|
||||
it('serves the shell on /dashboard and /action', async () => {
|
||||
for (const path of ['/dashboard', '/dashboard/', '/action/*splat']) {
|
||||
const { res, captured } = makeRes();
|
||||
await callRoute('get', path, makeReq({ path }), res);
|
||||
expect(typeof captured.body).toBe('string');
|
||||
expect(String(captured.body)).toMatch(/<!DOCTYPE html>/i);
|
||||
}
|
||||
});
|
||||
|
||||
it('redirects /desktop to the root, keeping the query', async () => {
|
||||
for (const path of ['/desktop', '/desktop/']) {
|
||||
const { res, captured } = makeRes();
|
||||
await callRoute(
|
||||
'get',
|
||||
path,
|
||||
makeReq({ path, originalUrl: `${path}?ref=abc&x=1` }),
|
||||
res,
|
||||
);
|
||||
expect(captured.statusCode).toBe(302);
|
||||
expect(captured.location).toBe('/?ref=abc&x=1');
|
||||
expect(captured.body).toBeUndefined();
|
||||
}
|
||||
|
||||
const { res, captured } = makeRes();
|
||||
await callRoute('get', '/desktop', makeReq({ path: '/desktop' }), res);
|
||||
expect(captured.location).toBe('/');
|
||||
});
|
||||
|
||||
it('redirects /settings to the dashboard Home tab', async () => {
|
||||
for (const path of ['/settings', '/settings/*splat']) {
|
||||
const { res, captured } = makeRes();
|
||||
await callRoute('get', path, makeReq({ path }), res);
|
||||
expect(captured.statusCode).toBe(302);
|
||||
expect(captured.location).toBe('/dashboard#home');
|
||||
expect(captured.body).toBeUndefined();
|
||||
}
|
||||
});
|
||||
|
||||
it('redirects /@:username to the dashboard', async () => {
|
||||
const { res, captured } = makeRes();
|
||||
await callRoute(
|
||||
'get',
|
||||
'/@:username',
|
||||
makeReq({ path: '/@alice', params: { username: 'alice' } }),
|
||||
res,
|
||||
);
|
||||
expect(captured.statusCode).toBe(302);
|
||||
expect(captured.location).toBe('/');
|
||||
expect(captured.body).toBeUndefined();
|
||||
});
|
||||
});
|
||||
|
||||
// ── /app/:name ──────────────────────────────────────────────────────
|
||||
@@ -360,47 +417,21 @@ describe('HomepageController GET /app/:name', () => {
|
||||
expect(html).not.toContain('owner_user_id');
|
||||
});
|
||||
|
||||
it('serves the same app shell under /desktop/app/:name', async () => {
|
||||
const { userId } = await makeUser();
|
||||
const name = `desk-${Math.random().toString(36).slice(2, 10)}`;
|
||||
await server.stores.app.create(
|
||||
{
|
||||
name,
|
||||
title: 'Desktop App',
|
||||
description: 'opens on the desktop instead of the dashboard',
|
||||
index_url: `https://example.com/${name}/`,
|
||||
approved_for_listing: 1,
|
||||
},
|
||||
{ ownerUserId: userId },
|
||||
);
|
||||
|
||||
const { res, captured } = makeRes();
|
||||
await callRoute(
|
||||
'get',
|
||||
'/desktop/app/:name',
|
||||
makeReq({ params: { name }, path: `/desktop/app/${name}` }),
|
||||
res,
|
||||
);
|
||||
|
||||
expect(captured.statusCode).toBe(200);
|
||||
const html = String(captured.body);
|
||||
expect(html).toMatch(/<!DOCTYPE html>/i);
|
||||
expect(html).toContain('Desktop App');
|
||||
});
|
||||
|
||||
it('returns 404 under /desktop/app/:name when the app is unknown', async () => {
|
||||
it('redirects /desktop/app/:name to /app/:name, keeping the query', async () => {
|
||||
const { res, captured } = makeRes();
|
||||
await callRoute(
|
||||
'get',
|
||||
'/desktop/app/:name',
|
||||
makeReq({
|
||||
params: { name: 'no-such-app' },
|
||||
path: '/desktop/app/no-such-app',
|
||||
params: { name: 'editor' },
|
||||
path: '/desktop/app/editor',
|
||||
originalUrl: '/desktop/app/editor?file=%2Falice%2Fa.txt&x=1',
|
||||
}),
|
||||
res,
|
||||
);
|
||||
expect(captured.statusCode).toBe(404);
|
||||
expect(String(captured.body)).toMatch(/<!DOCTYPE html>/i);
|
||||
expect(captured.statusCode).toBe(302);
|
||||
expect(captured.location).toBe('/app/editor?file=%2Falice%2Fa.txt&x=1');
|
||||
expect(captured.body).toBeUndefined();
|
||||
});
|
||||
|
||||
it('omits index_url even for a public app — the shell is not the launch authority', async () => {
|
||||
@@ -434,40 +465,39 @@ describe('HomepageController GET /app/:name', () => {
|
||||
// -- app landing rate limit --
|
||||
|
||||
describe('HomepageController app landing rate limit', () => {
|
||||
it('rate-limits /app/:name and /desktop/app/:name per network', () => {
|
||||
for (const path of ['/app/:name', '/desktop/app/:name']) {
|
||||
const route = router.routes.find(
|
||||
(r) => r.method === 'get' && r.path === path,
|
||||
);
|
||||
if (!route) throw new Error(`No GET ${path} route`);
|
||||
expect(route.options.rateLimit).toEqual({
|
||||
scope: 'app-landing',
|
||||
limit: 600,
|
||||
window: 60_000,
|
||||
key: 'ip',
|
||||
});
|
||||
}
|
||||
it('rate-limits /app/:name per network', () => {
|
||||
const route = router.routes.find(
|
||||
(r) => r.method === 'get' && r.path === '/app/:name',
|
||||
);
|
||||
if (!route) throw new Error('No GET /app/:name route');
|
||||
expect(route.options.rateLimit).toEqual({
|
||||
scope: 'app-landing',
|
||||
limit: 600,
|
||||
window: 60_000,
|
||||
key: 'ip',
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
// ── /show/* ─────────────────────────────────────────────────────────
|
||||
|
||||
describe('HomepageController GET /show/*splat', () => {
|
||||
it('emits a launch_app explorer call with the post-/show path', async () => {
|
||||
it('redirects to the path in the dashboard Files tab, keeping the query', async () => {
|
||||
const { res, captured } = makeRes();
|
||||
await callRoute(
|
||||
'get',
|
||||
'/show/*splat',
|
||||
makeReq({ path: '/show/alice/Documents' }),
|
||||
makeReq({
|
||||
path: '/show/alice/My%20Documents',
|
||||
originalUrl: '/show/alice/My%20Documents?ref=abc',
|
||||
}),
|
||||
res,
|
||||
);
|
||||
// The launch payload is JSON-serialized into the rendered HTML.
|
||||
// We assert the rendered shell included the explorer launch hint
|
||||
// pointing at the expected (slashed) path.
|
||||
const html = String(captured.body);
|
||||
expect(html).toContain('launch_app');
|
||||
expect(html).toContain('explorer');
|
||||
expect(html).toContain('/alice/Documents');
|
||||
expect(captured.statusCode).toBe(302);
|
||||
expect(captured.location).toBe(
|
||||
'/dashboard?ref=abc#files/alice/My%20Documents',
|
||||
);
|
||||
expect(captured.body).toBeUndefined();
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
import express from 'express';
|
||||
import path from 'node:path';
|
||||
import { PuterController } from '../types.js';
|
||||
import { isPlainUserActor } from '../../core/actor.js';
|
||||
import { toAppShellView } from '../../util/appShellView.js';
|
||||
import type { PuterRouter } from '../../core/http/PuterRouter';
|
||||
import {
|
||||
@@ -27,11 +28,12 @@ import {
|
||||
subdomainLabelOf,
|
||||
} from '../../core/http/middleware/hostRedirects.js';
|
||||
import type { IConfig } from '../../types';
|
||||
import type { UserRow } from '../../stores/user/UserStore';
|
||||
import type {
|
||||
PuterHomepageService,
|
||||
PageMeta,
|
||||
LaunchOptions,
|
||||
PopupFrame,
|
||||
ShellContext,
|
||||
} from '../../services/homepage/PuterHomepageService';
|
||||
|
||||
/**
|
||||
@@ -170,7 +172,6 @@ export class HomepageController extends PuterController {
|
||||
req: express.Request,
|
||||
res: express.Response,
|
||||
metaOverrides: Partial<PageMeta> = {},
|
||||
launch: LaunchOptions = {},
|
||||
popupFrame?: PopupFrame,
|
||||
) => {
|
||||
const meta = { ...defaultMeta(req), ...metaOverrides };
|
||||
@@ -180,7 +181,16 @@ export class HomepageController extends PuterController {
|
||||
actor?: Parameters<typeof homepage.send>[0]['actor'];
|
||||
}
|
||||
).actor ?? null;
|
||||
await homepage.send({ req, res, actor }, meta, launch, popupFrame);
|
||||
await homepage.send(
|
||||
{
|
||||
req,
|
||||
res,
|
||||
actor,
|
||||
guiTokenDigest: this.#guiTokenDigest(req, actor),
|
||||
},
|
||||
meta,
|
||||
popupFrame,
|
||||
);
|
||||
};
|
||||
|
||||
// -- Root + path-aliased shell routes ------------------------
|
||||
@@ -252,7 +262,6 @@ export class HomepageController extends PuterController {
|
||||
req,
|
||||
res,
|
||||
{},
|
||||
{},
|
||||
{
|
||||
hostOrigin: embedHostOrigin(
|
||||
this.config,
|
||||
@@ -263,23 +272,42 @@ export class HomepageController extends PuterController {
|
||||
});
|
||||
}
|
||||
|
||||
router.get('/settings', {}, (req, res) => sendShell(req, res));
|
||||
router.get('/settings/*splat', {}, (req, res) => sendShell(req, res));
|
||||
// Old settings links land on the dashboard's Home tab.
|
||||
router.get('/settings', {}, (_req, res) =>
|
||||
res.redirect('/dashboard#home'),
|
||||
);
|
||||
router.get('/settings/*splat', {}, (_req, res) =>
|
||||
res.redirect('/dashboard#home'),
|
||||
);
|
||||
|
||||
router.get('/dashboard', {}, (req, res) => sendShell(req, res));
|
||||
router.get('/dashboard/', {}, (req, res) => sendShell(req, res));
|
||||
|
||||
router.get('/desktop', {}, (req, res) => sendShell(req, res));
|
||||
router.get('/desktop/', {}, (req, res) => sendShell(req, res));
|
||||
const queryOf = (req: express.Request) => {
|
||||
const separator = req.originalUrl.indexOf('?');
|
||||
return separator === -1 ? '' : req.originalUrl.slice(separator);
|
||||
};
|
||||
|
||||
// Old desktop links land on the dashboard, query intact.
|
||||
router.get('/desktop', {}, (req, res) =>
|
||||
res.redirect(`/${queryOf(req)}`),
|
||||
);
|
||||
router.get('/desktop/', {}, (req, res) =>
|
||||
res.redirect(`/${queryOf(req)}`),
|
||||
);
|
||||
|
||||
router.get('/action/*splat', {}, (req, res) => sendShell(req, res));
|
||||
|
||||
router.get('/@:username', {}, (req, res) => sendShell(req, res));
|
||||
// Old links to a user's public folder land on the dashboard.
|
||||
router.get('/@:username', {}, (_req, res) => res.redirect('/'));
|
||||
|
||||
// Old desktop app links open the app in the dashboard, query intact.
|
||||
router.get('/desktop/app/:name', {}, (req, res) => {
|
||||
const name = encodeURIComponent(String(req.params.name ?? ''));
|
||||
res.redirect(`/app/${name}${queryOf(req)}`);
|
||||
});
|
||||
|
||||
// -- /app/:name - app metadata baked into the shell ----------
|
||||
// `/desktop/app/:name` is the same landing booted on the desktop
|
||||
// instead of the dashboard; the GUI strips the prefix and treats the
|
||||
// rest of the path identically, so both render the same shell.
|
||||
|
||||
const sendAppShell = async (
|
||||
req: express.Request,
|
||||
@@ -334,26 +362,11 @@ export class HomepageController extends PuterController {
|
||||
{ rateLimit: APP_LANDING_LIMIT },
|
||||
sendAppShell,
|
||||
);
|
||||
router.get(
|
||||
'/desktop/app/:name',
|
||||
{ rateLimit: APP_LANDING_LIMIT },
|
||||
sendAppShell,
|
||||
);
|
||||
|
||||
// -- /show/* - launch explorer with the requested file path --
|
||||
|
||||
// Old /show links open the path in the dashboard's Files tab, query intact.
|
||||
router.get('/show/*splat', {}, (req, res) => {
|
||||
const filePath = req.path.slice('/show'.length);
|
||||
const launch: LaunchOptions = {
|
||||
on_initialized: [
|
||||
{
|
||||
$: 'window-call',
|
||||
fn_name: 'launch_app',
|
||||
args: [{ name: 'explorer', path: filePath }],
|
||||
},
|
||||
],
|
||||
};
|
||||
return sendShell(req, res, {}, launch);
|
||||
res.redirect(`/dashboard${queryOf(req)}#files${filePath}`);
|
||||
});
|
||||
|
||||
// -- /sw.js - the service worker, scoped to the whole origin --
|
||||
@@ -382,6 +395,38 @@ export class HomepageController extends PuterController {
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Lets the GUI skip `/get-gui-token`, which reads the session cookie: the
|
||||
* digest of the token it would hand over, null when there is no session
|
||||
* cookie (either name the auth probe reads), and undefined (the GUI asks)
|
||||
* when a cookie didn't resolve to a session.
|
||||
*/
|
||||
#guiTokenDigest(
|
||||
req: express.Request,
|
||||
actor: ShellContext['actor'],
|
||||
): string | null | undefined {
|
||||
if (req.tokenSource === 'cookie') {
|
||||
if (!actor || !isPlainUserActor(actor) || !actor.session?.uid) {
|
||||
return undefined;
|
||||
}
|
||||
return this.services.auth.guiTokenDigest(
|
||||
actor.user as UserRow,
|
||||
actor.session.uid,
|
||||
);
|
||||
}
|
||||
const cookies = (req.cookies ?? {}) as Record<string, unknown>;
|
||||
const hasSessionCookie = [
|
||||
this.config.cookie_name,
|
||||
'puter_token_v2',
|
||||
].some(
|
||||
(name) =>
|
||||
!!name &&
|
||||
typeof cookies[name] === 'string' &&
|
||||
cookies[name] !== '',
|
||||
);
|
||||
return hasSessionCookie ? undefined : null;
|
||||
}
|
||||
}
|
||||
|
||||
const safeJsonParse = (s: string): Record<string, unknown> | null => {
|
||||
|
||||
@@ -372,26 +372,6 @@ describe('OIDCController GET /auth/oidc/:provider/start', () => {
|
||||
);
|
||||
});
|
||||
|
||||
it('bakes a whitelisted desktop app landing (/desktop/app/<name>) into the state redirect_uri', async () => {
|
||||
const { res, captured } = makeRes();
|
||||
await callRoute(
|
||||
'get',
|
||||
'/auth/oidc/:provider/start',
|
||||
makeReq({
|
||||
params: { provider: 'custom' },
|
||||
query: { return_to: '/desktop/app/my-App_2' },
|
||||
}),
|
||||
res,
|
||||
);
|
||||
const state = new URL(captured.redirectUrl ?? '').searchParams.get(
|
||||
'state',
|
||||
);
|
||||
const decoded = oidc().verifyState(state!);
|
||||
expect(String(decoded?.redirect_uri)).toBe(
|
||||
`${TEST_ORIGIN}/desktop/app/my-App_2`,
|
||||
);
|
||||
});
|
||||
|
||||
it('ignores a non-whitelisted return_to', async () => {
|
||||
const bad_values = [
|
||||
'/app/evil/extra',
|
||||
@@ -400,6 +380,8 @@ describe('OIDCController GET /auth/oidc/:provider/start', () => {
|
||||
'//evil.test',
|
||||
'/settings',
|
||||
`/app/${'a'.repeat(101)}`,
|
||||
'/desktop',
|
||||
'/desktop/app/my-App_2',
|
||||
'/desktop/app/evil/extra',
|
||||
'/desktop/app/',
|
||||
'/dashboard/app/name',
|
||||
@@ -476,11 +458,11 @@ describe('OIDCController GET /auth/oidc/:provider/start', () => {
|
||||
sharedPath('b.txt'),
|
||||
sharedPath('a.txt'),
|
||||
],
|
||||
'/desktop',
|
||||
'/dashboard',
|
||||
),
|
||||
);
|
||||
const url = new URL(uri);
|
||||
expect(url.origin + url.pathname).toBe(`${TEST_ORIGIN}/desktop`);
|
||||
expect(url.origin + url.pathname).toBe(`${TEST_ORIGIN}/dashboard`);
|
||||
expect(url.searchParams.getAll('shared')).toEqual([
|
||||
sharedPath('a.txt'),
|
||||
sharedPath('b.txt'),
|
||||
|
||||
@@ -102,16 +102,14 @@ function signupOptionsFromState(
|
||||
}
|
||||
|
||||
// GUI pages an OIDC flow may return to: the root (where a share email lands),
|
||||
// /desktop, /dashboard, and direct app landings (/app/<name> and its
|
||||
// desktop-booted twin /desktop/app/<name>, mirroring APP_NAME_REGEX in
|
||||
// AppDriver). Strict whitelist — never a client-supplied URL (no open
|
||||
// redirect).
|
||||
// /dashboard, and direct app landings (/app/<name>, mirroring
|
||||
// APP_NAME_REGEX in AppDriver). Strict whitelist — never a client-supplied URL
|
||||
// (no open redirect).
|
||||
function isWhitelistedReturnPath(path: string): boolean {
|
||||
return (
|
||||
path === '/' ||
|
||||
path === '/desktop' ||
|
||||
path === '/dashboard' ||
|
||||
/^(\/desktop)?\/app\/[a-zA-Z0-9_-]{1,100}$/.test(path)
|
||||
/^\/app\/[a-zA-Z0-9_-]{1,100}$/.test(path)
|
||||
);
|
||||
}
|
||||
|
||||
@@ -438,9 +436,8 @@ export class OIDCController extends PuterController {
|
||||
|
||||
let appRedirectUri = flowRedirects[flow] ?? (origin || '/');
|
||||
|
||||
// Optional GUI return path so login started from /desktop,
|
||||
// /dashboard, an /app/<name> landing, or a share link lands
|
||||
// back there.
|
||||
// Optional GUI return path so login started from /dashboard,
|
||||
// an /app/<name> landing, or a share link lands back there.
|
||||
const rawReturnTo = Array.isArray(req.query.return_to)
|
||||
? req.query.return_to[0]
|
||||
: req.query.return_to;
|
||||
|
||||
@@ -314,8 +314,8 @@ describe('OIDC account second-factor login', () => {
|
||||
|
||||
it('preserves ordinary OIDC login for accounts without 2FA', async () => {
|
||||
await account(false);
|
||||
const response = await callback('login', { return_to: '/desktop' });
|
||||
expect(response.headers.get('location')).toBe(`${env.origin}/desktop`);
|
||||
const response = await callback('login', { return_to: '/dashboard' });
|
||||
expect(response.headers.get('location')).toBe(`${env.origin}/dashboard`);
|
||||
expect(
|
||||
response.headers.get('set-cookie')?.includes('puter_auth_token='),
|
||||
).toBe(true);
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
*/
|
||||
|
||||
import type { Request } from 'express';
|
||||
import { afterAll, beforeAll, describe, expect, it } from 'vitest';
|
||||
import { afterAll, beforeAll, describe, expect, it, vi } from 'vitest';
|
||||
import { v4 as uuidv4 } from 'uuid';
|
||||
import { makeActor } from '../../actor';
|
||||
import {
|
||||
@@ -1132,14 +1132,150 @@ describe('resolvePublicHostedIdentity', () => {
|
||||
const reqOf = (init: {
|
||||
cookies?: Record<string, string>;
|
||||
actor?: unknown;
|
||||
headers?: Record<string, string>;
|
||||
query?: Record<string, string>;
|
||||
}): Request =>
|
||||
({
|
||||
cookies: init.cookies ?? {},
|
||||
actor: init.actor,
|
||||
headers: {},
|
||||
query: {},
|
||||
headers: init.headers ?? {},
|
||||
query: init.query ?? {},
|
||||
}) as unknown as Request;
|
||||
|
||||
describe('with the launch token in the Referer', () => {
|
||||
const host = 'launch.site.puter.localhost';
|
||||
const cookieName = HOSTED_ASSET_COOKIES.public.name;
|
||||
|
||||
const launch = async () => {
|
||||
const user = await makeUser();
|
||||
const sub = `launch-${uuidv4().slice(0, 8)}`;
|
||||
const app = await server.stores.app.create(
|
||||
{ name: sub, title: sub, index_url: `http://${host}/` },
|
||||
{ ownerUserId: user.id },
|
||||
);
|
||||
const token = await authService.getUserAppToken(
|
||||
{ user } as unknown as Parameters<
|
||||
typeof authService.getUserAppToken
|
||||
>[0],
|
||||
app.uid,
|
||||
);
|
||||
const actor = (await authService.authenticateFromToken(token))!;
|
||||
const cookie = await authService.createHostedAssetToken('public', {
|
||||
appUid: app.uid,
|
||||
userUid: user.uuid,
|
||||
sessionUuid: actor.session?.uid,
|
||||
subdomain: 'launch',
|
||||
host,
|
||||
});
|
||||
return { user, appUid: app.uid, token, cookie, actor };
|
||||
};
|
||||
|
||||
const resolve = (
|
||||
appUid: string,
|
||||
init: Parameters<typeof reqOf>[0],
|
||||
expectedHost = host,
|
||||
) =>
|
||||
resolvePublicHostedIdentity({
|
||||
req: reqOf(init),
|
||||
authService,
|
||||
sessionCookieName: 'puter_auth_token',
|
||||
expectedAppUid: appUid,
|
||||
expectedSubdomain: 'launch',
|
||||
expectedHost,
|
||||
});
|
||||
|
||||
const refererFor = (token: string) =>
|
||||
`http://${host}/?puter.auth.token=${encodeURIComponent(token)}`;
|
||||
|
||||
it('takes the cookie when the token names its user and session', async () => {
|
||||
const { user, appUid, token, cookie } = await launch();
|
||||
const authenticate = vi.spyOn(authService, 'authenticate');
|
||||
try {
|
||||
const out = await resolve(appUid, {
|
||||
cookies: { [cookieName]: cookie },
|
||||
headers: { referer: refererFor(token) },
|
||||
});
|
||||
expect(out).toMatchObject({
|
||||
source: 'public-cookie',
|
||||
userUid: user.uuid,
|
||||
hasValidPublicCookie: true,
|
||||
});
|
||||
expect(authenticate).not.toHaveBeenCalled();
|
||||
} finally {
|
||||
authenticate.mockRestore();
|
||||
}
|
||||
});
|
||||
|
||||
it('authenticates a query token even when it names the cookie identity', async () => {
|
||||
const { user, appUid, token, cookie } = await launch();
|
||||
const out = await resolve(appUid, {
|
||||
cookies: { [cookieName]: cookie },
|
||||
query: { 'puter.auth.token': token },
|
||||
});
|
||||
expect(out.source).toBe('query');
|
||||
expect(out.userUid).toBe(user.uuid);
|
||||
expect(
|
||||
(out as { hasValidPublicCookie?: boolean })
|
||||
.hasValidPublicCookie,
|
||||
).toBeUndefined();
|
||||
});
|
||||
|
||||
it('authenticates the token when the cookie was minted for another host', async () => {
|
||||
const { user, appUid, token, cookie } = await launch();
|
||||
const out = await resolve(
|
||||
appUid,
|
||||
{
|
||||
cookies: { [cookieName]: cookie },
|
||||
headers: { referer: refererFor(token) },
|
||||
},
|
||||
'other.site.puter.localhost',
|
||||
);
|
||||
expect(out.source).toBe('referrer');
|
||||
expect(out.userUid).toBe(user.uuid);
|
||||
});
|
||||
|
||||
it('authenticates a token that names another app under the same session', async () => {
|
||||
const { user, appUid, cookie, actor } = await launch();
|
||||
const otherAppToken = server.services.token.sign('auth', {
|
||||
type: 'app-under-user',
|
||||
version: '2',
|
||||
user_uid: user.uuid,
|
||||
app_uid: `app-${uuidv4()}`,
|
||||
session_uid: actor.session!.uid,
|
||||
});
|
||||
const authenticate = vi.spyOn(authService, 'authenticate');
|
||||
try {
|
||||
const out = await resolve(appUid, {
|
||||
cookies: { [cookieName]: cookie },
|
||||
headers: { referer: refererFor(otherAppToken) },
|
||||
});
|
||||
expect(authenticate).toHaveBeenCalledTimes(1);
|
||||
expect(out.source).toBe('public-cookie');
|
||||
} finally {
|
||||
authenticate.mockRestore();
|
||||
}
|
||||
});
|
||||
|
||||
it('never resolves a scoped access token, with or without the cookie', async () => {
|
||||
const { user, appUid, cookie } = await launch();
|
||||
const scoped = await authService.createAccessToken(
|
||||
makeActor({
|
||||
user: { id: user.id, uuid: user.uuid, username: user.username },
|
||||
}),
|
||||
[[`user:${user.uuid}:email:read`]],
|
||||
);
|
||||
const withCookie = await resolve(appUid, {
|
||||
cookies: { [cookieName]: cookie },
|
||||
headers: { referer: refererFor(scoped) },
|
||||
});
|
||||
expect(withCookie.source).toBe('public-cookie');
|
||||
const withoutCookie = await resolve(appUid, {
|
||||
headers: { referer: refererFor(scoped) },
|
||||
});
|
||||
expect(withoutCookie.source).toBe('none');
|
||||
});
|
||||
});
|
||||
|
||||
it('returns the cookie identity when present and valid', async () => {
|
||||
const user = await makeUser();
|
||||
const appUid = `app-${uuidv4()}`;
|
||||
|
||||
@@ -86,6 +86,10 @@ export interface PrivateIdentity {
|
||||
hasValidPrivateCookie?: boolean;
|
||||
}
|
||||
|
||||
type PublicCookieClaims = Awaited<
|
||||
ReturnType<AuthService['verifyHostedAssetToken']>
|
||||
>;
|
||||
|
||||
interface SubdomainLike {
|
||||
user_id?: number | null;
|
||||
}
|
||||
@@ -533,8 +537,63 @@ export async function resolvePublicHostedIdentity(opts: {
|
||||
}
|
||||
}
|
||||
|
||||
const { name: publicCookieNameV2, legacyName: publicCookieNameLegacy } =
|
||||
HOSTED_ASSET_COOKIES.public;
|
||||
const publicCookieToken =
|
||||
(typeof cookies?.[publicCookieNameV2] === 'string'
|
||||
? cookies[publicCookieNameV2]
|
||||
: null) ??
|
||||
(typeof cookies?.[publicCookieNameLegacy] === 'string'
|
||||
? cookies[publicCookieNameLegacy]
|
||||
: null);
|
||||
let publicCookieClaims: Promise<PublicCookieClaims | null> | undefined;
|
||||
const verifyPublicCookie = () =>
|
||||
(publicCookieClaims ??= (async () => {
|
||||
if (!publicCookieToken) return null;
|
||||
try {
|
||||
return await authService.verifyHostedAssetToken(
|
||||
'public',
|
||||
publicCookieToken,
|
||||
{
|
||||
appUid: expectedAppUid,
|
||||
subdomain: expectedSubdomain,
|
||||
host: expectedHost,
|
||||
},
|
||||
);
|
||||
} catch {
|
||||
// v1-signed cookies land here and get re-minted.
|
||||
return null;
|
||||
}
|
||||
})());
|
||||
const publicCookieIdentity = (claims: PublicCookieClaims) => ({
|
||||
source: 'public-cookie' as const,
|
||||
userUid: claims.userUid,
|
||||
sessionUuid: claims.sessionUuid,
|
||||
hasValidPublicCookie: true,
|
||||
});
|
||||
|
||||
const bootstrap = getBootstrapToken(req);
|
||||
if (bootstrap) {
|
||||
// A launched app's own assets carry its launch token in the Referer.
|
||||
// When that token names the cookie's user and session, the cookie
|
||||
// already stands for it and nothing needs re-authenticating or minting.
|
||||
if (
|
||||
bootstrap.source === 'referrer' &&
|
||||
publicCookieToken &&
|
||||
expectedAppUid
|
||||
) {
|
||||
const named = authService.signedSessionClaims(bootstrap.token);
|
||||
if (named && (!named.appUid || named.appUid === expectedAppUid)) {
|
||||
const claims = await verifyPublicCookie();
|
||||
if (
|
||||
claims &&
|
||||
claims.userUid === named.userUid &&
|
||||
claims.sessionUuid === named.sessionUuid
|
||||
) {
|
||||
return publicCookieIdentity(claims);
|
||||
}
|
||||
}
|
||||
}
|
||||
try {
|
||||
const actor = await authService.authenticateFromToken(
|
||||
bootstrap.token,
|
||||
@@ -554,36 +613,8 @@ export async function resolvePublicHostedIdentity(opts: {
|
||||
}
|
||||
}
|
||||
|
||||
const { name: publicCookieNameV2, legacyName: publicCookieNameLegacy } =
|
||||
HOSTED_ASSET_COOKIES.public;
|
||||
const publicCookieToken =
|
||||
(typeof cookies?.[publicCookieNameV2] === 'string'
|
||||
? cookies[publicCookieNameV2]
|
||||
: null) ??
|
||||
(typeof cookies?.[publicCookieNameLegacy] === 'string'
|
||||
? cookies[publicCookieNameLegacy]
|
||||
: null);
|
||||
if (publicCookieToken) {
|
||||
try {
|
||||
const claims = await authService.verifyHostedAssetToken(
|
||||
'public',
|
||||
publicCookieToken,
|
||||
{
|
||||
appUid: expectedAppUid,
|
||||
subdomain: expectedSubdomain,
|
||||
host: expectedHost,
|
||||
},
|
||||
);
|
||||
return {
|
||||
source: 'public-cookie',
|
||||
userUid: claims.userUid,
|
||||
sessionUuid: claims.sessionUuid,
|
||||
hasValidPublicCookie: true,
|
||||
};
|
||||
} catch {
|
||||
/* fall through — v1-signed cookies land here and get re-minted */
|
||||
}
|
||||
}
|
||||
const claims = await verifyPublicCookie();
|
||||
if (claims) return publicCookieIdentity(claims);
|
||||
|
||||
return { source: 'none' };
|
||||
}
|
||||
|
||||
@@ -2763,6 +2763,321 @@ describe('public hosted asset billing identity', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('public hosted assets requested with the launch token in the Referer', () => {
|
||||
const cookieName = HOSTED_ASSET_COOKIES.public.name;
|
||||
|
||||
const makeLaunchedApp = async () => {
|
||||
const owner = await makeUserWithHome();
|
||||
const home = (await server.stores.fsEntry.getEntryByPath(
|
||||
`/${owner.username}`,
|
||||
))!;
|
||||
const sub = `ref-${uuidv4().slice(0, 8)}`;
|
||||
const host = `${sub}.site.puter.localhost`;
|
||||
await server.stores.subdomain.create({
|
||||
userId: owner.id,
|
||||
subdomain: sub,
|
||||
rootDirId: home.id,
|
||||
});
|
||||
await writeFile(
|
||||
owner.id,
|
||||
`/${owner.username}/index.html`,
|
||||
Buffer.from('<html></html>'),
|
||||
);
|
||||
await writeFile(
|
||||
owner.id,
|
||||
`/${owner.username}/app.css`,
|
||||
Buffer.from('body{}'),
|
||||
);
|
||||
const app = await server.stores.app.create(
|
||||
{ name: sub, title: sub, index_url: `http://${host}/` },
|
||||
{ ownerUserId: owner.id },
|
||||
);
|
||||
return { owner, sub, host, appUid: app.uid };
|
||||
};
|
||||
|
||||
const cookieFor = async (
|
||||
token: string,
|
||||
site: { sub: string; host: string; appUid: string },
|
||||
) => {
|
||||
const actor = (await server.services.auth.authenticateFromToken(
|
||||
token,
|
||||
))!;
|
||||
return server.services.auth.createHostedAssetToken('public', {
|
||||
appUid: site.appUid,
|
||||
userUid: actor.user.uuid,
|
||||
sessionUuid: actor.session?.uid,
|
||||
subdomain: site.sub,
|
||||
host: site.host,
|
||||
});
|
||||
};
|
||||
|
||||
const refererFor = (host: string, token: string) =>
|
||||
`http://${host}/?puter.app_instance_id=x&puter.auth.token=${encodeURIComponent(token)}`;
|
||||
|
||||
const serve = async (
|
||||
host: string,
|
||||
init: {
|
||||
path?: string;
|
||||
cookies?: Record<string, string>;
|
||||
headers?: Record<string, string>;
|
||||
query?: Record<string, string>;
|
||||
} = {},
|
||||
) => {
|
||||
const req = makeReq({ hostname: host, path: '/app.css', ...init });
|
||||
const { res, out } = makeRes();
|
||||
await buildMiddleware()(req, res, vi.fn());
|
||||
await new Promise<void>((resolve) => setImmediate(resolve));
|
||||
expect(out.statusCode).toBe(200);
|
||||
return { req, out };
|
||||
};
|
||||
|
||||
const claimsOf = (cookie: string, appUid: string, host: string) =>
|
||||
server.services.auth.verifyHostedAssetToken('public', cookie, {
|
||||
appUid,
|
||||
host,
|
||||
});
|
||||
|
||||
const REDIS_METHODS = [
|
||||
'get',
|
||||
'mget',
|
||||
'exists',
|
||||
'hget',
|
||||
'hgetall',
|
||||
'smembers',
|
||||
'set',
|
||||
'del',
|
||||
'expire',
|
||||
'incr',
|
||||
'incrby',
|
||||
'hset',
|
||||
'sadd',
|
||||
'pipeline',
|
||||
'multi',
|
||||
];
|
||||
|
||||
/** Redis calls, JWT signs and full authentications made by `fn`. */
|
||||
const measure = async <T>(fn: () => Promise<T>) => {
|
||||
const redis = server.clients.redis as unknown as Record<
|
||||
string,
|
||||
unknown
|
||||
>;
|
||||
const redisSpies = REDIS_METHODS.filter(
|
||||
(m) => typeof redis[m] === 'function',
|
||||
).map((m) => [m, vi.spyOn(redis as never, m as never)] as const);
|
||||
const sign = vi.spyOn(server.services.token, 'sign');
|
||||
const authenticate = vi.spyOn(server.services.auth, 'authenticate');
|
||||
try {
|
||||
const result = await fn();
|
||||
const redisCalls: Record<string, number> = {};
|
||||
for (const [m, spy] of redisSpies) {
|
||||
const n = (spy as unknown as { mock: { calls: unknown[] } })
|
||||
.mock.calls.length;
|
||||
if (n) redisCalls[m] = n;
|
||||
}
|
||||
return {
|
||||
result,
|
||||
redisCalls,
|
||||
signs: sign.mock.calls.length,
|
||||
authentications: authenticate.mock.calls.length,
|
||||
};
|
||||
} finally {
|
||||
for (const [, spy] of redisSpies) spy.mockRestore();
|
||||
sign.mockRestore();
|
||||
authenticate.mockRestore();
|
||||
}
|
||||
};
|
||||
|
||||
it('costs the same as the cookie alone when the token names the cookie user and session', async () => {
|
||||
const site = await makeLaunchedApp();
|
||||
const visitor = await makeUser();
|
||||
const token = await server.services.auth.getUserAppToken(
|
||||
actorFor(visitor),
|
||||
site.appUid,
|
||||
);
|
||||
const cookies = { [cookieName]: await cookieFor(token, site) };
|
||||
const headers = { referer: refererFor(site.host, token) };
|
||||
|
||||
// Warm the caches both paths read.
|
||||
await serve(site.host, { cookies });
|
||||
await serve(site.host, { cookies, headers });
|
||||
|
||||
const cookieOnly = await measure(() => serve(site.host, { cookies }));
|
||||
const withReferer = await measure(() =>
|
||||
serve(site.host, { cookies, headers }),
|
||||
);
|
||||
|
||||
expect(withReferer.result.req.egressActor?.user?.uuid).toBe(
|
||||
visitor.uuid,
|
||||
);
|
||||
expect(withReferer.result.out.cookies).toEqual({});
|
||||
expect(withReferer.signs).toBe(0);
|
||||
expect(withReferer.authentications).toBe(0);
|
||||
expect(withReferer.redisCalls).toEqual(cookieOnly.redisCalls);
|
||||
expect(cookieOnly.signs).toBe(0);
|
||||
});
|
||||
|
||||
it('bills the token account when the launch could not replace an older cookie', async () => {
|
||||
const site = await makeLaunchedApp();
|
||||
const previous = await makeUser();
|
||||
const current = await makeUser();
|
||||
const previousToken = await server.services.auth.getUserAppToken(
|
||||
actorFor(previous),
|
||||
site.appUid,
|
||||
);
|
||||
const currentToken = await server.services.auth.getUserAppToken(
|
||||
actorFor(current),
|
||||
site.appUid,
|
||||
);
|
||||
const oldCookies = {
|
||||
[cookieName]: await cookieFor(previousToken, site),
|
||||
};
|
||||
|
||||
const mint = vi
|
||||
.spyOn(server.services.auth, 'createHostedAssetToken')
|
||||
.mockRejectedValueOnce(new Error('mint failed'));
|
||||
const warn = vi.spyOn(console, 'warn').mockImplementation(() => {});
|
||||
let launch;
|
||||
try {
|
||||
launch = await serve(site.host, {
|
||||
path: '/index.html',
|
||||
cookies: oldCookies,
|
||||
query: { 'puter.auth.token': currentToken },
|
||||
});
|
||||
} finally {
|
||||
mint.mockRestore();
|
||||
warn.mockRestore();
|
||||
}
|
||||
expect(launch.out.cookies).toEqual({});
|
||||
expect(launch.req.egressActor?.user?.uuid).toBe(current.uuid);
|
||||
|
||||
const asset = await serve(site.host, {
|
||||
cookies: oldCookies,
|
||||
headers: { referer: refererFor(site.host, currentToken) },
|
||||
});
|
||||
expect(asset.req.egressActor?.user?.uuid).toBe(current.uuid);
|
||||
const replaced = asset.out.cookies[cookieName];
|
||||
expect(replaced).toBeTruthy();
|
||||
expect((await claimsOf(replaced, site.appUid, site.host)).userUid).toBe(
|
||||
current.uuid,
|
||||
);
|
||||
});
|
||||
|
||||
it('bills the token account when a cached page of another account loads assets', async () => {
|
||||
// The document never reaches the server (served from an app's own
|
||||
// cache), so only the assets show which account launched it.
|
||||
const site = await makeLaunchedApp();
|
||||
const previous = await makeUser();
|
||||
const current = await makeUser();
|
||||
const previousToken = await server.services.auth.getUserAppToken(
|
||||
actorFor(previous),
|
||||
site.appUid,
|
||||
);
|
||||
const currentToken = await server.services.auth.getUserAppToken(
|
||||
actorFor(current),
|
||||
site.appUid,
|
||||
);
|
||||
const oldCookies = {
|
||||
[cookieName]: await cookieFor(previousToken, site),
|
||||
};
|
||||
|
||||
for (const path of ['/app.css', '/index.html']) {
|
||||
const asset = await serve(site.host, {
|
||||
path,
|
||||
cookies: oldCookies,
|
||||
headers: { referer: refererFor(site.host, currentToken) },
|
||||
});
|
||||
expect(asset.req.egressActor?.user?.uuid).toBe(current.uuid);
|
||||
const replaced = asset.out.cookies[cookieName];
|
||||
expect(
|
||||
(await claimsOf(replaced, site.appUid, site.host)).userUid,
|
||||
).toBe(current.uuid);
|
||||
}
|
||||
});
|
||||
|
||||
it('re-mints the cookie when the token names the same user under another session', async () => {
|
||||
const site = await makeLaunchedApp();
|
||||
const visitor = await makeUser();
|
||||
const appToken = await server.services.auth.getUserAppToken(
|
||||
actorFor(visitor),
|
||||
site.appUid,
|
||||
);
|
||||
const cookies = { [cookieName]: await cookieFor(appToken, site) };
|
||||
const { session, token: sessionToken } =
|
||||
await server.services.auth.createSessionToken(visitor as never);
|
||||
|
||||
const asset = await serve(site.host, {
|
||||
cookies,
|
||||
headers: { referer: refererFor(site.host, sessionToken) },
|
||||
});
|
||||
expect(asset.req.egressActor?.user?.uuid).toBe(visitor.uuid);
|
||||
const replaced = asset.out.cookies[cookieName];
|
||||
expect(replaced).toBeTruthy();
|
||||
expect(
|
||||
(await claimsOf(replaced, site.appUid, site.host)).sessionUuid,
|
||||
).toBe(session.uuid);
|
||||
});
|
||||
|
||||
it('falls back to the cookie when the Referer token does not verify', async () => {
|
||||
const site = await makeLaunchedApp();
|
||||
const visitor = await makeUser();
|
||||
const token = await server.services.auth.getUserAppToken(
|
||||
actorFor(visitor),
|
||||
site.appUid,
|
||||
);
|
||||
const cookies = { [cookieName]: await cookieFor(token, site) };
|
||||
const tampered = `${token.slice(0, -4)}AAAA`;
|
||||
|
||||
const asset = await serve(site.host, {
|
||||
cookies,
|
||||
headers: { referer: refererFor(site.host, tampered) },
|
||||
});
|
||||
expect(asset.req.egressActor?.user?.uuid).toBe(visitor.uuid);
|
||||
expect(asset.out.cookies).toEqual({});
|
||||
});
|
||||
|
||||
it('bills the site owner once the shared session is revoked', async () => {
|
||||
const site = await makeLaunchedApp();
|
||||
const visitor = await makeUser();
|
||||
const token = await server.services.auth.getUserAppToken(
|
||||
actorFor(visitor),
|
||||
site.appUid,
|
||||
);
|
||||
const cookies = { [cookieName]: await cookieFor(token, site) };
|
||||
await server.services.auth.revokeAllSessionsForUserId(visitor.id);
|
||||
|
||||
const asset = await serve(site.host, {
|
||||
cookies,
|
||||
headers: { referer: refererFor(site.host, token) },
|
||||
});
|
||||
expect(asset.req.egressActor?.user?.uuid).toBe(site.owner.uuid);
|
||||
expect(asset.out.cookies).toEqual({});
|
||||
});
|
||||
|
||||
it('keeps responses that set the cookie out of shared caches', async () => {
|
||||
const site = await makeLaunchedApp();
|
||||
const visitor = await makeUser();
|
||||
const token = await server.services.auth.getUserAppToken(
|
||||
actorFor(visitor),
|
||||
site.appUid,
|
||||
);
|
||||
|
||||
const launch = await serve(site.host, {
|
||||
path: '/index.html',
|
||||
query: { 'puter.auth.token': token },
|
||||
});
|
||||
const cookie = launch.out.cookies[cookieName];
|
||||
expect(cookie).toBeTruthy();
|
||||
expect(launch.out.headers['Cache-Control']).toBe('private');
|
||||
|
||||
const asset = await serve(site.host, {
|
||||
cookies: { [cookieName]: cookie },
|
||||
headers: { referer: refererFor(site.host, token) },
|
||||
});
|
||||
expect(asset.out.cookies).toEqual({});
|
||||
expect(asset.out.headers['Cache-Control']).toBeUndefined();
|
||||
});
|
||||
});
|
||||
|
||||
describe('site rooted in the owner tree, root moved to Trash', () => {
|
||||
it('stops serving a trashed folder and resumes when restored', async () => {
|
||||
const owner = await makeUserWithHome();
|
||||
|
||||
@@ -548,6 +548,8 @@ export const createPuterSiteMiddleware = (
|
||||
requestHostname: host,
|
||||
}),
|
||||
);
|
||||
// A shared cache must not hand this visitor's cookie to others.
|
||||
res.set('Cache-Control', 'private');
|
||||
}
|
||||
} catch (e) {
|
||||
// Best-effort — don't block the public file serve.
|
||||
|
||||
@@ -186,6 +186,96 @@ describe('AuthService (integration)', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('signedSessionClaims', () => {
|
||||
it('names the user and session of a session token', async () => {
|
||||
const user = await makeUser();
|
||||
const { token, session } = await authService.createSessionToken(
|
||||
user,
|
||||
{},
|
||||
);
|
||||
expect(authService.signedSessionClaims(token)).toEqual({
|
||||
userUid: user.uuid,
|
||||
sessionUuid: (session as { uuid: string }).uuid,
|
||||
});
|
||||
});
|
||||
|
||||
it('names the app too for an app token', async () => {
|
||||
const user = await makeUser();
|
||||
const appUid = `app-${uuidv4()}`;
|
||||
const sessionUuid = uuidv4();
|
||||
const token = server.services.token.sign('auth', {
|
||||
type: 'app-under-user',
|
||||
version: '2',
|
||||
user_uid: user.uuid,
|
||||
app_uid: appUid,
|
||||
session_uid: sessionUuid,
|
||||
});
|
||||
expect(authService.signedSessionClaims(token)).toEqual({
|
||||
userUid: user.uuid,
|
||||
sessionUuid,
|
||||
appUid,
|
||||
});
|
||||
});
|
||||
|
||||
it('reads the session from `uuid` on a token without `session_uid`', () => {
|
||||
const [userUid, sessionUuid] = [uuidv4(), uuidv4()];
|
||||
const token = server.services.token.sign('auth', {
|
||||
type: 'gui',
|
||||
version: '0.0.0',
|
||||
uuid: sessionUuid,
|
||||
user_uid: userUid,
|
||||
});
|
||||
expect(authService.signedSessionClaims(token)).toEqual({
|
||||
userUid,
|
||||
sessionUuid,
|
||||
});
|
||||
});
|
||||
|
||||
it('returns null for worker, access, expired, tampered and session-less tokens', async () => {
|
||||
const user = await makeUser();
|
||||
const accessToken = await authService.createAccessToken(
|
||||
{
|
||||
user: {
|
||||
id: user.id,
|
||||
uuid: user.uuid,
|
||||
username: user.username,
|
||||
},
|
||||
} as Actor,
|
||||
[[`user:${user.uuid}:email:read`]],
|
||||
);
|
||||
const sign = (claims: Record<string, unknown>, expiresIn?: number) =>
|
||||
server.services.token.sign(
|
||||
'auth',
|
||||
claims,
|
||||
expiresIn === undefined ? undefined : { expiresIn },
|
||||
);
|
||||
const sessionUuid = uuidv4();
|
||||
const session = {
|
||||
type: 'session',
|
||||
version: '2',
|
||||
uuid: sessionUuid,
|
||||
session_uid: sessionUuid,
|
||||
user_uid: user.uuid,
|
||||
};
|
||||
const valid = sign(session);
|
||||
for (const token of [
|
||||
accessToken,
|
||||
sign({ ...session, worker: true, worker_name: 'w' }),
|
||||
sign({
|
||||
type: 'app-under-user',
|
||||
version: '2',
|
||||
user_uid: user.uuid,
|
||||
app_uid: `app-${uuidv4()}`,
|
||||
}),
|
||||
sign(session, -120),
|
||||
`${valid.slice(0, -4)}AAAA`,
|
||||
'not-a-jwt',
|
||||
]) {
|
||||
expect(authService.signedSessionClaims(token)).toBeNull();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// ── Rich `authenticate()` result shape ──────────────────────────
|
||||
|
||||
describe('authenticate (reauth signal)', () => {
|
||||
@@ -3099,7 +3189,7 @@ describe('AuthService (integration)', () => {
|
||||
const emit = vi.spyOn(server.clients.event, 'emit');
|
||||
const announced = () =>
|
||||
emit.mock.calls.filter(
|
||||
(c) => c[0] === 'auth.access-token.revoked',
|
||||
(c) => c[0] === 'outer.auth.access-token.revoked',
|
||||
).length;
|
||||
|
||||
const scoped = await authService.createAccessToken(actor, [
|
||||
@@ -3117,6 +3207,35 @@ describe('AuthService (integration)', () => {
|
||||
emit.mockRestore();
|
||||
});
|
||||
|
||||
it('announces a desktop app token it replaces past its max age', async () => {
|
||||
const user = await makeUser();
|
||||
const { session } = await authService.createSessionToken(user);
|
||||
const actor = makeActor({
|
||||
user: { id: user.id, uuid: user.uuid, username: user.username },
|
||||
session: { uid: String(session.uuid), kind: 'web' },
|
||||
});
|
||||
const app = { uid: `app-${uuidv4()}`, title: 'Retire probe' };
|
||||
const { token } = await authService.getGodmodeAppToken(actor, app);
|
||||
const { token_uid } = server.services.token.verify<{
|
||||
token_uid: string;
|
||||
}>('auth', token);
|
||||
|
||||
const emit = vi.spyOn(server.clients.event, 'emit');
|
||||
const later = Date.now() + 8 * 24 * 60 * 60 * 1000;
|
||||
vi.spyOn(Date, 'now').mockReturnValue(later);
|
||||
try {
|
||||
await authService.getGodmodeAppToken(actor, app);
|
||||
expect(emit).toHaveBeenCalledWith(
|
||||
'outer.auth.access-token.revoked',
|
||||
{ token_uid },
|
||||
{},
|
||||
);
|
||||
} finally {
|
||||
vi.mocked(Date.now).mockRestore();
|
||||
emit.mockRestore();
|
||||
}
|
||||
});
|
||||
|
||||
it('revokeAccessToken rejects with 404 when the token belongs to another user', async () => {
|
||||
const u1 = await makeUser();
|
||||
const u2 = await makeUser();
|
||||
|
||||
@@ -106,6 +106,15 @@ const HOSTED_ASSET_LABELS = {
|
||||
|
||||
export type ReauthReason = 'session_revoked' | 'session_expired';
|
||||
|
||||
/** Worker claims a session/gui token can carry. */
|
||||
interface SessionTypeTokenOptions {
|
||||
worker?: boolean;
|
||||
workerName?: string;
|
||||
workerUid?: string;
|
||||
workerSiteUid?: string;
|
||||
workerSite?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Request metadata for `authenticate`. `touch: false` checks the token without
|
||||
* recording activity on its session, for re-checks no user made.
|
||||
@@ -367,6 +376,22 @@ export class AuthService extends PuterService {
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Digest of the claims `createGuiToken` signs for this session, which
|
||||
* differ between two of its tokens only in `iat`.
|
||||
*/
|
||||
guiTokenDigest(user: UserRow, sessionUuid: string): string {
|
||||
return this.services.token.claimsDigest(
|
||||
'auth',
|
||||
this.#sessionTypeClaims(
|
||||
'gui',
|
||||
user,
|
||||
sessionUuid,
|
||||
this.#authIdFor(user),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/** Sign a session token for an existing session (upgrade from GUI token). */
|
||||
createSessionTokenForSession(user: UserRow, sessionUuid: string): string {
|
||||
return this.#signSessionTypeToken(
|
||||
@@ -386,14 +411,21 @@ export class AuthService extends PuterService {
|
||||
user: UserRow,
|
||||
sessionUuid: string,
|
||||
authId: string,
|
||||
opts: {
|
||||
worker?: boolean;
|
||||
workerName?: string;
|
||||
workerUid?: string;
|
||||
workerSiteUid?: string;
|
||||
workerSite?: string;
|
||||
} = {},
|
||||
opts: SessionTypeTokenOptions = {},
|
||||
): string {
|
||||
return this.services.token.sign(
|
||||
'auth',
|
||||
this.#sessionTypeClaims(type, user, sessionUuid, authId, opts),
|
||||
);
|
||||
}
|
||||
|
||||
#sessionTypeClaims(
|
||||
type: 'session' | 'gui',
|
||||
user: UserRow,
|
||||
sessionUuid: string,
|
||||
authId: string,
|
||||
opts: SessionTypeTokenOptions = {},
|
||||
): Record<string, unknown> {
|
||||
const claims: Record<string, unknown> = {
|
||||
type,
|
||||
version: '2',
|
||||
@@ -410,7 +442,7 @@ export class AuthService extends PuterService {
|
||||
if (opts.workerUid) claims.worker_uid = opts.workerUid;
|
||||
if (opts.workerSiteUid) claims.workerSiteUid = opts.workerSiteUid;
|
||||
if (opts.workerSite) claims.workerSite = opts.workerSite;
|
||||
return this.services.token.sign('auth', claims);
|
||||
return claims;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1889,7 +1921,7 @@ export class AuthService extends PuterService {
|
||||
}
|
||||
if (row.access_token_uid) {
|
||||
this.clients.event?.emit(
|
||||
'auth.access-token.revoked',
|
||||
'outer.auth.access-token.revoked',
|
||||
{ token_uid: row.access_token_uid },
|
||||
{},
|
||||
);
|
||||
@@ -2051,6 +2083,43 @@ export class AuthService extends PuterService {
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* User, session and app a session, GUI or app token names, checked against
|
||||
* its signature and expiry only: nothing is read from the stores, so this
|
||||
* says nothing about whether the session or user is still live. Null for
|
||||
* worker and access tokens, and for anything that doesn't verify.
|
||||
*/
|
||||
signedSessionClaims(
|
||||
token: string,
|
||||
): { userUid: string; sessionUuid: string; appUid?: string } | null {
|
||||
let decoded: AnyTokenPayload;
|
||||
try {
|
||||
decoded = this.services.token.verify<AnyTokenPayload>(
|
||||
'auth',
|
||||
token,
|
||||
);
|
||||
} catch {
|
||||
return null;
|
||||
}
|
||||
if (decoded.type === 'session' || decoded.type === 'gui') {
|
||||
if (decoded.worker) return null;
|
||||
const sessionUuid = decoded.session_uid ?? decoded.uuid;
|
||||
if (!decoded.user_uid || !sessionUuid) return null;
|
||||
return { userUid: decoded.user_uid, sessionUuid };
|
||||
}
|
||||
if (decoded.type === 'app-under-user') {
|
||||
if (decoded.worker) return null;
|
||||
if (!decoded.user_uid || !decoded.session_uid || !decoded.app_uid)
|
||||
return null;
|
||||
return {
|
||||
userUid: decoded.user_uid,
|
||||
sessionUuid: decoded.session_uid,
|
||||
appUid: decoded.app_uid,
|
||||
};
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
#verifyHostedAssetToken(
|
||||
token: string,
|
||||
expectedKind: 'private' | 'public',
|
||||
@@ -2511,7 +2580,7 @@ export class AuthService extends PuterService {
|
||||
// Only a token the handshake admits has a socket to drop.
|
||||
if (mayBeFullAccess) {
|
||||
this.clients.event?.emit(
|
||||
'auth.access-token.revoked',
|
||||
'outer.auth.access-token.revoked',
|
||||
{ token_uid: tokenUid },
|
||||
{},
|
||||
);
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
import { createHmac } from 'node:crypto';
|
||||
import jwt from 'jsonwebtoken';
|
||||
import { describe, expect, it } from 'vitest';
|
||||
import { tokenClaimsDigest } from '../../../gui/src/helpers/guiToken.js';
|
||||
import { isTokenForAnotherUser } from '../../../gui/src/helpers/tokenUser.js';
|
||||
import { TokenService } from './TokenService.js';
|
||||
|
||||
@@ -403,3 +404,35 @@ describe('session token read by the desktop', () => {
|
||||
expect(isTokenForAnotherUser(token, { uuid: otherUid })).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
describe('TokenService.claimsDigest', () => {
|
||||
const claims = {
|
||||
type: 'gui',
|
||||
version: '2',
|
||||
uuid: '6f1e2d3c-0000-4000-8000-000000000001',
|
||||
session_uid: '6f1e2d3c-0000-4000-8000-000000000001',
|
||||
user_uid: '5d4adce0-a381-4982-9c02-6e2540026238',
|
||||
auth_id: '5d4adce0-a381-4982-9c02-6e2540026238',
|
||||
};
|
||||
|
||||
it('is what the desktop computes over a token signed with those claims', async () => {
|
||||
const svc = createTokenService();
|
||||
const digest = svc.claimsDigest('auth', claims);
|
||||
expect(digest).toMatch(/^[0-9a-f]{32}$/);
|
||||
expect(await tokenClaimsDigest(svc.sign('auth', claims))).toBe(digest);
|
||||
});
|
||||
|
||||
it('differs for another session or token type', () => {
|
||||
const svc = createTokenService();
|
||||
const digest = svc.claimsDigest('auth', claims);
|
||||
expect(
|
||||
svc.claimsDigest('auth', {
|
||||
...claims,
|
||||
session_uid: 'b0b0b0b0-0000-4000-8000-000000000002',
|
||||
}),
|
||||
).not.toBe(digest);
|
||||
expect(svc.claimsDigest('auth', { ...claims, type: 'session' })).not.toBe(
|
||||
digest,
|
||||
);
|
||||
});
|
||||
});
|
||||
@@ -17,6 +17,7 @@
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import { createHash } from 'node:crypto';
|
||||
import jwt, { type SignOptions } from 'jsonwebtoken';
|
||||
import { PuterService } from '../types';
|
||||
|
||||
@@ -268,6 +269,24 @@ export class TokenService extends PuterService {
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Digest of the claims `sign(scope, payload)` writes, minus `iat`: SHA-256
|
||||
* over the claims as key-sorted `[key, value]` pairs in JSON, first 32 hex
|
||||
* chars. The GUI computes the same over a stored token
|
||||
* (`gui/src/helpers/guiToken.js`), so the two must stay in step.
|
||||
*/
|
||||
claimsDigest(scope: string, payload: Record<string, unknown>): string {
|
||||
const claims = this.#compressPayload(COMPRESSION[scope], payload);
|
||||
const pairs = Object.keys(claims)
|
||||
.filter((key) => key !== 'iat')
|
||||
.sort()
|
||||
.map((key) => [key, claims[key]]);
|
||||
return createHash('sha256')
|
||||
.update(JSON.stringify(pairs))
|
||||
.digest('hex')
|
||||
.slice(0, 32);
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify and decompress. Only v2 tokens (`kid: 'v2'`) verify; any other
|
||||
* token — including the retired v1 format — is rejected as invalid, with no
|
||||
|
||||
@@ -137,7 +137,6 @@ const render = async (
|
||||
service: PuterHomepageService,
|
||||
req: Request = makeReq(),
|
||||
meta: Record<string, unknown> = { title: 'Puter' },
|
||||
launchOptions: Record<string, unknown> = {},
|
||||
actor: unknown = null,
|
||||
): Promise<string> => {
|
||||
let sent = '';
|
||||
@@ -149,7 +148,6 @@ const render = async (
|
||||
await service.send(
|
||||
{ req, res, actor } as never,
|
||||
meta as never,
|
||||
launchOptions as never,
|
||||
);
|
||||
return sent;
|
||||
};
|
||||
@@ -292,7 +290,6 @@ describe('PuterHomepageService — gui() parameters', () => {
|
||||
asset_dir: '/dist',
|
||||
title: 'Editor',
|
||||
app: { name: 'editor' },
|
||||
launch_options: {},
|
||||
});
|
||||
// No `config.origin`: fall back to the request's protocol + domain.
|
||||
expect(params.app_origin).toBe('http://puter.test');
|
||||
@@ -338,7 +335,7 @@ describe('PuterHomepageService — gui() parameters', () => {
|
||||
|
||||
const staff = { user: { id: 7, email: '[email protected]' } };
|
||||
expect(
|
||||
guiParamsOf(await render(service, makeReq(), undefined, {}, staff))
|
||||
guiParamsOf(await render(service, makeReq(), undefined, staff))
|
||||
.teams_ui,
|
||||
).toBe(true);
|
||||
expect(teamsAvailableTo).toHaveBeenCalledWith(7, '[email protected]');
|
||||
@@ -349,7 +346,7 @@ describe('PuterHomepageService — gui() parameters', () => {
|
||||
teamsAvailableTo.mockResolvedValueOnce(false);
|
||||
expect(
|
||||
guiParamsOf(
|
||||
await render(service, makeReq(), undefined, {}, {
|
||||
await render(service, makeReq(), undefined, {
|
||||
user: { id: 9, email: '[email protected]' },
|
||||
}),
|
||||
).teams_ui,
|
||||
@@ -420,22 +417,6 @@ describe('PuterHomepageService — gui() parameters', () => {
|
||||
expect(html).toContain('\\u003c/script>');
|
||||
expect(guiParamsOf(html).injected).toBe('</script><img src=x>');
|
||||
});
|
||||
|
||||
it('passes launch options straight through', async () => {
|
||||
const params = guiParamsOf(
|
||||
await render(
|
||||
makeService(),
|
||||
makeReq(),
|
||||
{ title: 'Puter' },
|
||||
{
|
||||
on_initialized: [{ do: 'thing' }],
|
||||
},
|
||||
),
|
||||
);
|
||||
expect(params.launch_options).toEqual({
|
||||
on_initialized: [{ do: 'thing' }],
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('PuterHomepageService — extension hooks', () => {
|
||||
|
||||
@@ -44,10 +44,6 @@ export interface PageMeta {
|
||||
app?: { name?: string; [k: string]: unknown } | null;
|
||||
}
|
||||
|
||||
export interface LaunchOptions {
|
||||
on_initialized?: Array<Record<string, unknown>>;
|
||||
}
|
||||
|
||||
/**
|
||||
* A GUI popup a first-party page frames at `/embed/<action>`. `hostOrigin` is
|
||||
* that page, read from the referrer and pinned with frame-ancestors; null when
|
||||
@@ -57,6 +53,17 @@ export interface PopupFrame {
|
||||
hostOrigin: string | null;
|
||||
}
|
||||
|
||||
export interface ShellContext {
|
||||
req: Request;
|
||||
res: Response;
|
||||
actor?: Actor | null;
|
||||
/**
|
||||
* `AuthService.guiTokenDigest` for the request's session cookie, or null
|
||||
* when it carries none. Omitted when the caller doesn't work it out.
|
||||
*/
|
||||
guiTokenDigest?: string | null;
|
||||
}
|
||||
|
||||
interface PuterGuiAddonsEvent {
|
||||
req: Request;
|
||||
path: string;
|
||||
@@ -309,12 +316,11 @@ export class PuterHomepageService extends PuterService {
|
||||
* called on the happy path.
|
||||
*/
|
||||
async send(
|
||||
ctx: { req: Request; res: Response; actor?: Actor | null },
|
||||
ctx: ShellContext,
|
||||
meta: PageMeta,
|
||||
launchOptions: LaunchOptions = {},
|
||||
popupFrame?: PopupFrame,
|
||||
): Promise<void> {
|
||||
const { req, res, actor } = ctx;
|
||||
const { req, res, actor, guiTokenDigest } = ctx;
|
||||
|
||||
// Easter egg: puter-in-puter detection → render error page instead.
|
||||
if (
|
||||
@@ -334,9 +340,8 @@ export class PuterHomepageService extends PuterService {
|
||||
}
|
||||
|
||||
const html = await this.#renderShell(
|
||||
{ req, actor: actor ?? null },
|
||||
{ req, actor: actor ?? null, guiTokenDigest },
|
||||
meta,
|
||||
launchOptions,
|
||||
popupFrame,
|
||||
);
|
||||
res.send(html);
|
||||
@@ -345,12 +350,13 @@ export class PuterHomepageService extends PuterService {
|
||||
// -- Internals ----------------------------------------------------
|
||||
|
||||
async #renderShell(
|
||||
ctx: { req: Request; actor: Actor | null },
|
||||
ctx: Pick<ShellContext, 'req' | 'guiTokenDigest'> & {
|
||||
actor: Actor | null;
|
||||
},
|
||||
meta: PageMeta,
|
||||
launchOptions: LaunchOptions,
|
||||
popupFrame?: PopupFrame,
|
||||
): Promise<string> {
|
||||
const { req, actor } = ctx;
|
||||
const { req, actor, guiTokenDigest } = ctx;
|
||||
const env = this.config.env ?? 'prod';
|
||||
const bundled = env !== 'dev' || this.config.use_bundled_gui === true;
|
||||
const assetDir = env === 'dev' ? '/src' : '/dist';
|
||||
@@ -393,10 +399,13 @@ export class PuterHomepageService extends PuterService {
|
||||
// instead of the socket wire.
|
||||
eventsNotifications: notificationsFoldInEnabled(this.config),
|
||||
...meta,
|
||||
launch_options: launchOptions,
|
||||
// After `meta`, so nothing page-specific can name the opener.
|
||||
...(popupFrame ? { embed_host_origin: popupFrame.hostOrigin } : {}),
|
||||
};
|
||||
// Only ever this request's; without one the GUI asks for its token as
|
||||
// it always has.
|
||||
if (guiTokenDigest === undefined) delete guiParams.guiTokenDigest;
|
||||
else guiParams.guiTokenDigest = guiTokenDigest;
|
||||
|
||||
const event: PuterGuiAddonsEvent = {
|
||||
req,
|
||||
|
||||
@@ -4579,6 +4579,209 @@ describe('MeteringService', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('settling when a balance read fails', () => {
|
||||
const monthKey = (a: Actor) =>
|
||||
`${METRICS_V2_PREFIX}:actor:${a.user!.uuid}:${currentMonthString()}`;
|
||||
|
||||
/** Rejects the next `times` reads `match` picks; the rest go through. */
|
||||
const failReads = (
|
||||
match: (args: {
|
||||
key: unknown;
|
||||
consistentRead?: boolean;
|
||||
}) => boolean,
|
||||
times = Infinity,
|
||||
) => {
|
||||
const kv = server.stores.kv;
|
||||
const realGet = kv.get.bind(kv);
|
||||
let left = times;
|
||||
return vi
|
||||
.spyOn(kv, 'get')
|
||||
.mockImplementation(
|
||||
async (...args: Parameters<typeof realGet>) => {
|
||||
if (left > 0 && match(args[0] as never)) {
|
||||
left--;
|
||||
throw new Error(
|
||||
'ProvisionedThroughputExceededException',
|
||||
);
|
||||
}
|
||||
return realGet(...args);
|
||||
},
|
||||
);
|
||||
};
|
||||
const isAddonsRead = ({ key }: { key: unknown }) =>
|
||||
typeof key === 'string' && key.endsWith(':addons');
|
||||
|
||||
const pools = async (a: Actor) => {
|
||||
await server.stores.meteringBuffer.flushCycle();
|
||||
const { usage } = await target.getActorCurrentMonthUsageDetails(a);
|
||||
const addons = await target.getActorAddons(a, {
|
||||
consistentRead: true,
|
||||
});
|
||||
return {
|
||||
total: usage.total,
|
||||
allowanceUsed: usage.allowanceUsed ?? 0,
|
||||
consumed: addons.consumedPurchaseCredits ?? 0,
|
||||
};
|
||||
};
|
||||
|
||||
it('charges the allowance when the purchased-credit read fails', async () => {
|
||||
await target.updateAddonCredit(actor.user.uuid!, 1_000_000);
|
||||
await target.incrementUsage(actor, 'ai:chat', 1, 1000);
|
||||
const before = await target.getAllowedUsage(actor);
|
||||
|
||||
const get = failReads(isAddonsRead);
|
||||
const result = await target.incrementUsage(
|
||||
actor,
|
||||
'ai:chat',
|
||||
1,
|
||||
5000,
|
||||
);
|
||||
get.mockRestore();
|
||||
|
||||
expect(result.total).toBe(6000);
|
||||
expect(await pools(actor)).toEqual({
|
||||
total: 6000,
|
||||
allowanceUsed: 6000,
|
||||
consumed: 0,
|
||||
});
|
||||
const after = await target.getAllowedUsage(actor);
|
||||
expect(before.remaining - after.remaining).toBe(5000);
|
||||
});
|
||||
|
||||
it('charges only the allowance share past the allowance, and nothing later charges the rest', async () => {
|
||||
const { monthUsageAllowance: allowance } =
|
||||
await target.getActorSubscription(actor);
|
||||
await target.updateAddonCredit(actor.user.uuid!, 1_000_000);
|
||||
await target.incrementUsage(actor, 'ai:chat', 1, allowance - 100);
|
||||
expect(await target.hasAnyUsageCached(actor)).toBe(true);
|
||||
|
||||
const alarm = vi.spyOn(server.clients.alarm, 'create');
|
||||
const emit = vi.spyOn(server.clients.event, 'emit');
|
||||
const get = failReads(isAddonsRead);
|
||||
await target.incrementUsage(actor, 'ai:chat', 1, 1000);
|
||||
get.mockRestore();
|
||||
|
||||
// 100 fits the allowance; the 900 credit would cover isn't drawn.
|
||||
expect(await pools(actor)).toEqual({
|
||||
total: allowance + 900,
|
||||
allowanceUsed: allowance,
|
||||
consumed: 0,
|
||||
});
|
||||
expect(alarm).toHaveBeenCalledWith(
|
||||
'metering_settle_read_failed',
|
||||
expect.any(String),
|
||||
expect.objectContaining({
|
||||
userId: actor.user.uuid,
|
||||
unchargedCost: 900,
|
||||
}),
|
||||
'info',
|
||||
);
|
||||
expect(
|
||||
alarm.mock.calls.some(([id]) =>
|
||||
String(id).startsWith('metering service error'),
|
||||
),
|
||||
).toBe(false);
|
||||
// The unread credit isn't taken as spent.
|
||||
expect(
|
||||
emit.mock.calls.some(
|
||||
([name]) => name === 'metering.credit-state',
|
||||
),
|
||||
).toBe(false);
|
||||
expect(await target.hasAnyUsageCached(actor)).toBe(true);
|
||||
alarm.mockRestore();
|
||||
emit.mockRestore();
|
||||
|
||||
// The next settle charges its own cost once, and only that.
|
||||
await target.incrementUsage(actor, 'ai:chat', 1, 700);
|
||||
expect(await pools(actor)).toEqual({
|
||||
total: allowance + 1600,
|
||||
allowanceUsed: allowance,
|
||||
consumed: 700,
|
||||
});
|
||||
});
|
||||
|
||||
it('charges the allowance from the buffered total when the exact read fails', async () => {
|
||||
const Service = target.constructor as typeof MeteringService;
|
||||
const interval = Service.EXACT_READ_MIN_INTERVAL_MS;
|
||||
Service.EXACT_READ_MIN_INTERVAL_MS = 0;
|
||||
try {
|
||||
const { monthUsageAllowance: allowance } =
|
||||
await target.getActorSubscription(actor);
|
||||
await target.incrementUsage(
|
||||
actor,
|
||||
'ai:chat',
|
||||
1,
|
||||
allowance - 3000,
|
||||
);
|
||||
await server.stores.meteringBuffer.flushCycle();
|
||||
|
||||
const key = monthKey(actor);
|
||||
const alarm = vi.spyOn(server.clients.alarm, 'create');
|
||||
const get = failReads(
|
||||
(args) => args.key === key && !!args.consistentRead,
|
||||
);
|
||||
const result = await target.incrementUsage(
|
||||
actor,
|
||||
'ai:chat',
|
||||
1,
|
||||
1000,
|
||||
);
|
||||
const failedReads = get.mock.calls.length;
|
||||
get.mockRestore();
|
||||
|
||||
expect(failedReads).toBeGreaterThan(0);
|
||||
expect(result.total).toBe(allowance - 2000);
|
||||
expect(await pools(actor)).toEqual({
|
||||
total: allowance - 2000,
|
||||
allowanceUsed: allowance - 2000,
|
||||
consumed: 0,
|
||||
});
|
||||
expect(alarm).toHaveBeenCalledWith(
|
||||
'metering_settle_read_failed',
|
||||
expect.any(String),
|
||||
expect.objectContaining({ unchargedCost: 0 }),
|
||||
'info',
|
||||
);
|
||||
alarm.mockRestore();
|
||||
} finally {
|
||||
Service.EXACT_READ_MIN_INTERVAL_MS = interval;
|
||||
}
|
||||
});
|
||||
|
||||
it('charges each of two racing calls once when one of their reads fails', async () => {
|
||||
await target.updateAddonCredit(actor.user.uuid!, 1_000_000);
|
||||
await target.incrementUsage(actor, 'ai:chat', 1, 1000);
|
||||
|
||||
const get = failReads(isAddonsRead, 1);
|
||||
await Promise.all([
|
||||
target.incrementUsage(actor, 'ai:chat', 1, 2000),
|
||||
target.incrementUsage(actor, 'ai:chat', 1, 3000),
|
||||
]);
|
||||
get.mockRestore();
|
||||
|
||||
expect(await pools(actor)).toEqual({
|
||||
total: 6000,
|
||||
allowanceUsed: 6000,
|
||||
consumed: 0,
|
||||
});
|
||||
});
|
||||
|
||||
it('charges a failed call and the calls after it exactly once each', async () => {
|
||||
await target.updateAddonCredit(actor.user.uuid!, 1_000_000);
|
||||
const costs = [1000, 2000, 3000, 4000];
|
||||
for (const [i, cost] of costs.entries()) {
|
||||
const get = failReads(isAddonsRead, i % 2 === 0 ? 1 : 0);
|
||||
await target.incrementUsage(actor, 'ai:chat', 1, cost);
|
||||
get.mockRestore();
|
||||
}
|
||||
expect(await pools(actor)).toEqual({
|
||||
total: 10_000,
|
||||
allowanceUsed: 10_000,
|
||||
consumed: 0,
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
// ── Resolver registration ────────────────────────────────────────
|
||||
|
||||
describe('resolver registration', () => {
|
||||
|
||||
@@ -342,6 +342,9 @@ export class MeteringService extends PuterService {
|
||||
/** Bumped on every drop, so a read that straddles one isn't cached. */
|
||||
#spentAddonsDrops = 0;
|
||||
|
||||
/** Running sum reported by `#alarmSettleReadFailed`. */
|
||||
#unchargedSinceStart = 0;
|
||||
|
||||
/**
|
||||
* Uuid → until when a near-allowance read bypasses the exact-read throttle.
|
||||
* Set on a credits change (a purchase, an admin correction): for a short
|
||||
@@ -675,49 +678,84 @@ export class MeteringService extends PuterService {
|
||||
appCallCount: usages.length,
|
||||
});
|
||||
|
||||
// The usage is already being recorded, so a failed balance read
|
||||
// must not skip settling it.
|
||||
let settleReadError: Error | null = null;
|
||||
const [usageResult, subscription, actorAddons] = await Promise.all([
|
||||
usageResultPromise,
|
||||
this.#actorSubscriptionWithStatus(actor),
|
||||
this.#addonsForSettle(actor),
|
||||
(async () => {
|
||||
try {
|
||||
return await this.#addonsForSettle(actor);
|
||||
} catch (e) {
|
||||
settleReadError = e as Error;
|
||||
return null;
|
||||
}
|
||||
})(),
|
||||
]);
|
||||
const { policy: actorSubscription, provisionalUntil } =
|
||||
subscription;
|
||||
|
||||
const actorUsages = await this.exactUsageNearAllowance(
|
||||
userId,
|
||||
actorUsageKey,
|
||||
usageResult,
|
||||
actorSubscription.monthUsageAllowance,
|
||||
);
|
||||
let actorUsages: UsageByType;
|
||||
try {
|
||||
actorUsages = await this.exactUsageNearAllowance(
|
||||
userId,
|
||||
actorUsageKey,
|
||||
usageResult,
|
||||
actorSubscription.monthUsageAllowance,
|
||||
);
|
||||
} catch (e) {
|
||||
settleReadError ??= e as Error;
|
||||
actorUsages = usageResult.res as unknown as UsageByType;
|
||||
}
|
||||
|
||||
// After a failed read only the allowance share is charged:
|
||||
// purchased credit is never drawn against an unread balance.
|
||||
const readAddons = settleReadError ? null : actorAddons;
|
||||
const settledAllowanceUsed = await this.settleIncrementCharges(
|
||||
userId,
|
||||
actorUsageKey,
|
||||
actorUsages,
|
||||
actorSubscription,
|
||||
actorAddons,
|
||||
readAddons ?? ({} as UsageAddons),
|
||||
totalBatchCost,
|
||||
);
|
||||
// Before any hold this usage stands for is released.
|
||||
await this.stores.creditHold.bump(userId);
|
||||
|
||||
this.maybeAlertOveruse({
|
||||
actor,
|
||||
userId,
|
||||
actorUsages,
|
||||
actorSubscription,
|
||||
actorAddons,
|
||||
incrementCost: totalBatchCost,
|
||||
batchUsages: usages,
|
||||
});
|
||||
if (!readAddons) {
|
||||
const usedBefore = MeteringService.allowanceUsedBefore(
|
||||
actorUsages,
|
||||
actorSubscription.monthUsageAllowance,
|
||||
totalBatchCost,
|
||||
);
|
||||
this.#alarmSettleReadFailed(
|
||||
actor,
|
||||
settleReadError,
|
||||
Math.max(
|
||||
0,
|
||||
totalBatchCost - (settledAllowanceUsed - usedBefore),
|
||||
),
|
||||
);
|
||||
} else {
|
||||
this.maybeAlertOveruse({
|
||||
actor,
|
||||
userId,
|
||||
actorUsages,
|
||||
actorSubscription,
|
||||
actorAddons,
|
||||
incrementCost: totalBatchCost,
|
||||
batchUsages: usages,
|
||||
});
|
||||
|
||||
this.rememberRemainingCredits(
|
||||
userId,
|
||||
settledAllowanceUsed,
|
||||
actorSubscription,
|
||||
actorAddons,
|
||||
provisionalUntil,
|
||||
);
|
||||
this.rememberRemainingCredits(
|
||||
userId,
|
||||
settledAllowanceUsed,
|
||||
actorSubscription,
|
||||
actorAddons,
|
||||
provisionalUntil,
|
||||
);
|
||||
}
|
||||
|
||||
const own = this.#withDetail(actorUsages, usageResult.detail);
|
||||
const charged = await this.applyMonthlyCharges(
|
||||
@@ -2957,6 +2995,31 @@ export class MeteringService extends PuterService {
|
||||
return usedBefore + allowanceCharge;
|
||||
}
|
||||
|
||||
/**
|
||||
* One alarm id for every actor, so a store brownout is a single alarm with
|
||||
* a count. `unchargedCost` is what credit would have covered, had any been
|
||||
* left; nothing charges it later.
|
||||
*/
|
||||
#alarmSettleReadFailed(
|
||||
actor: Actor,
|
||||
error: Error | null,
|
||||
unchargedCost: number,
|
||||
): void {
|
||||
this.#unchargedSinceStart += unchargedCost;
|
||||
this.clients.alarm.create(
|
||||
'metering_settle_read_failed',
|
||||
'Metering settled usage to the allowance only: a balance read failed',
|
||||
{
|
||||
userId: actor.user?.uuid,
|
||||
appId: actor.effectiveApp?.uid,
|
||||
unchargedCost,
|
||||
unchargedSinceStart: this.#unchargedSinceStart,
|
||||
error: error ?? undefined,
|
||||
},
|
||||
'info',
|
||||
);
|
||||
}
|
||||
|
||||
private maybeAlertOveruse(ctx: {
|
||||
actor: Actor;
|
||||
userId: string;
|
||||
|
||||
@@ -2354,6 +2354,35 @@ describe('OpenAIRealtimeRelayService relay', () => {
|
||||
b.ws.close();
|
||||
});
|
||||
|
||||
it('evicts an access token revoked on another node', async () => {
|
||||
const row = await server.stores.user.getByUsername(user.username);
|
||||
const actor = makeActor({ user: row! });
|
||||
const token = await server.services.auth.createAccessToken(actor, [
|
||||
[FULL_API_ACCESS],
|
||||
]);
|
||||
const { token_uid } = server.services.token.verify<{
|
||||
token_uid: string;
|
||||
}>('auth', token);
|
||||
const c = open(`${relayUrl}?auth_token=${token}`);
|
||||
await c.waitFor('session.created');
|
||||
|
||||
// As a peer cluster delivers it, after a malformed payload it ignores.
|
||||
server.clients.event.emit(
|
||||
'outer.auth.access-token.revoked',
|
||||
{ token_uid: 42 } as never,
|
||||
{ from_outside: true },
|
||||
);
|
||||
server.clients.event.emit(
|
||||
'outer.auth.access-token.revoked',
|
||||
{ token_uid },
|
||||
{ from_outside: true },
|
||||
);
|
||||
expect(await c.waitFor('error')).toMatchObject({
|
||||
error: { code: 'invalid_api_key' },
|
||||
});
|
||||
await c.closed;
|
||||
});
|
||||
|
||||
it('closes with a retryable error after a sustained verification outage', async () => {
|
||||
const c = open(`${relayUrl}?auth_token=${user.token}`);
|
||||
await c.waitFor('session.created');
|
||||
|
||||
@@ -838,13 +838,19 @@ export class OpenAIRealtimeRelayService extends PuterService {
|
||||
{},
|
||||
);
|
||||
});
|
||||
this.clients.event.on('auth.access-token.revoked', (_key, data) => {
|
||||
this.clients.event.emit(
|
||||
'pubsub.realtime.auth-revoked',
|
||||
{ tokenUid: data.token_uid },
|
||||
{},
|
||||
);
|
||||
});
|
||||
this.clients.event.on(
|
||||
'outer.auth.access-token.revoked',
|
||||
(_key, data) => {
|
||||
const tokenUid = (data as { token_uid?: unknown } | null)
|
||||
?.token_uid;
|
||||
if (typeof tokenUid !== 'string' || !tokenUid) return;
|
||||
this.clients.event.emit(
|
||||
'pubsub.realtime.auth-revoked',
|
||||
{ tokenUid },
|
||||
{},
|
||||
);
|
||||
},
|
||||
);
|
||||
// Raw WebSockets do not participate in socket.io's cluster adapter.
|
||||
this.clients.event.on('pubsub.realtime.auth-revoked', (_key, data) => {
|
||||
const revoked = data.sessionUids
|
||||
|
||||
@@ -428,6 +428,43 @@ describe('SocketService (live socket.io)', () => {
|
||||
sessionSocket.disconnect();
|
||||
});
|
||||
|
||||
it('drops a token`s socket on a revocation that reached it from elsewhere', async () => {
|
||||
const row = await server.stores.user.getByUsername(user.username);
|
||||
const actor = makeActor({ user: row as never });
|
||||
const doomed = await runWithContext({ actor }, () =>
|
||||
server.services.auth.createAccessToken(actor, [[FULL_API_ACCESS]], {
|
||||
label: 'revoke-fanout-probe',
|
||||
}),
|
||||
);
|
||||
const { token_uid } = server.services.token.verify<{
|
||||
token_uid: string;
|
||||
}>('auth', doomed);
|
||||
const tokenSocket = await connect({ auth_token: doomed });
|
||||
expect(tokenSocket.connected).toBe(true);
|
||||
|
||||
// A malformed peer payload is ignored.
|
||||
for (const data of [null, {}, { token_uid: 42 }]) {
|
||||
server.clients.event.emit(
|
||||
'outer.auth.access-token.revoked',
|
||||
data as never,
|
||||
{ from_outside: true },
|
||||
);
|
||||
}
|
||||
await new Promise((r) => setTimeout(r, 200));
|
||||
expect(tokenSocket.connected).toBe(true);
|
||||
|
||||
// As a peer cluster delivers it: the token was revoked on another node.
|
||||
server.clients.event.emit(
|
||||
'outer.auth.access-token.revoked',
|
||||
{ token_uid },
|
||||
{ from_outside: true },
|
||||
);
|
||||
|
||||
await vi.waitFor(() => expect(tokenSocket.connected).toBe(false), {
|
||||
timeout: 5000,
|
||||
});
|
||||
});
|
||||
|
||||
it('rejects an app-under-user token while events are off', async () => {
|
||||
const row = await server.stores.user.getByUsername(user.username);
|
||||
const appUid = `app-${uuidv4()}`;
|
||||
|
||||
@@ -1175,10 +1175,12 @@ export class SocketService extends PuterService {
|
||||
);
|
||||
|
||||
this.clients.event.on(
|
||||
'auth.access-token.revoked',
|
||||
'outer.auth.access-token.revoked',
|
||||
(_key: string, data: unknown) => {
|
||||
const { token_uid } = data as { token_uid: string };
|
||||
this.#evictAccessTokenSockets(token_uid).catch(
|
||||
const tokenUid = (data as { token_uid?: unknown } | null)
|
||||
?.token_uid;
|
||||
if (typeof tokenUid !== 'string') return;
|
||||
this.#evictAccessTokenSockets(tokenUid).catch(
|
||||
(err: unknown) => {
|
||||
console.error('[socket] token eviction failed', err);
|
||||
},
|
||||
|
||||
@@ -33,20 +33,6 @@ Sent on app startup, and whenever the user's locale on Puter is changed. The val
|
||||
}
|
||||
```
|
||||
|
||||
#### `themeChanged`
|
||||
Sent on app startup, and whenever the user's desktop theme on Puter is changed. The value passed to `handler` is:
|
||||
```js
|
||||
{
|
||||
palette: {
|
||||
primaryHue, // (Float) Hue of the theme color
|
||||
primarySaturation, // (String) Saturation of the theme color as a percentage, with % sign
|
||||
primaryLightness, // (String) Lightness of the theme color as a percentage, with % sign
|
||||
primaryAlpha, // (Float) Opacity of the theme color from 0 to 1
|
||||
primaryColor, // (String) CSS color value for text
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### `connection`
|
||||
Sent when another app requests a connection to your app. The value passed to `handler` is:
|
||||
```js
|
||||
|
||||
@@ -418,7 +418,7 @@ For long-lived mounts, sign in with a `-token` username and an API token as the
|
||||
| ------------------------------------------------------------------ | ------------------------------- | ----------- |
|
||||
| `nameAvailable` | 60/min | |
|
||||
| App icon | 12,000/min | Per network |
|
||||
| App landing page (`/app/<name>`, `/desktop/app/<name>`) | 600/min | Per network |
|
||||
| App landing page (`/app/<name>`) | 600/min | Per network |
|
||||
| Names per batch app lookup (`GET /apps/:names`, `POST /query/app`) | 200, up to 200 characters each | |
|
||||
| `metadata` | 16 KiB, measured as JSON | |
|
||||
| `filetypeAssociations` | 200 entries, 60 characters each | |
|
||||
|
||||
@@ -144,7 +144,7 @@ try {
|
||||
|
||||
startServer(1);
|
||||
|
||||
app.get(['/', '/app/*splat', '/action/*splat', '/desktop', '/desktop/app/*splat', '/dashboard'], (req, res) => {
|
||||
app.get(['/', '/app/*splat', '/action/*splat', '/dashboard'], (req, res) => {
|
||||
res.send(generateDevHtml({
|
||||
env: env,
|
||||
api_origin: apiOrigin,
|
||||
|
||||
@@ -424,15 +424,14 @@ export const authHeadHtml = (flow, title, { openerNotice = true } = {}) => {
|
||||
};
|
||||
|
||||
/**
|
||||
* On a cover page, the logo is a way out: desktop users stay on the desktop,
|
||||
* everyone else goes to the root dashboard.
|
||||
* On a cover page, the logo is a way out, to the root dashboard.
|
||||
*
|
||||
* @param {AuthFlow} flow
|
||||
* @returns {string} Empty where the logo leads nowhere.
|
||||
*/
|
||||
const logoHref = (flow) => {
|
||||
if ( ! flow.page || window.embedded_in_popup ) return '';
|
||||
return window.location.pathname === '/desktop' ? '/desktop' : '/';
|
||||
return '/';
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,61 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2024-present Puter Technologies Inc.
|
||||
*
|
||||
* This file is part of Puter.
|
||||
*
|
||||
* Puter is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published
|
||||
* by the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
const Component = use('util.Component');
|
||||
|
||||
/**
|
||||
* Allows a flex layout of composed components to be
|
||||
* treated as a component.
|
||||
*/
|
||||
export default def(class Flexer extends Component {
|
||||
static ID = 'ui.component.Flexer';
|
||||
|
||||
static PROPERTIES = {
|
||||
children: {},
|
||||
gap: { value: '20pt' },
|
||||
};
|
||||
|
||||
static CSS = `
|
||||
:host > div {
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
}
|
||||
`;
|
||||
|
||||
create_template ({ template }) {
|
||||
// TODO: The way we handle loading assets doesn't work well
|
||||
// with web components, so for now it goes in the template.
|
||||
$(template).html(`
|
||||
<div><slot name="inside"></slot></div>
|
||||
`);
|
||||
}
|
||||
|
||||
on_ready ({ listen }) {
|
||||
for ( const child of this.get('children') ) {
|
||||
child.setAttribute('slot', 'inside');
|
||||
child.attach(this);
|
||||
}
|
||||
|
||||
listen('gap', gap => {
|
||||
$(this.dom_).find('div').first().css('gap', gap);
|
||||
});
|
||||
}
|
||||
});
|
||||
@@ -1,47 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2024-present Puter Technologies Inc.
|
||||
*
|
||||
* This file is part of Puter.
|
||||
*
|
||||
* Puter is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published
|
||||
* by the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
import UIWindow from './UIWindow.js';
|
||||
import Placeholder from '../util/Placeholder.js';
|
||||
import JustHTML from './Components/JustHTML.js';
|
||||
|
||||
/**
|
||||
* @typedef {Object} UIComponentWindowOptions
|
||||
* @property {Component} [component] A component to render in the window
|
||||
* @property {string} [html] HTML string to render in the window (uses JustHTML component)
|
||||
*/
|
||||
|
||||
/**
|
||||
* Render a UIWindow that contains an instance of Component or HTML string
|
||||
* @param {UIComponentWindowOptions} options
|
||||
*/
|
||||
export default async function UIComponentWindow (options) {
|
||||
const component = options.component ?? new JustHTML({ html: options.html ?? '' });
|
||||
const placeholder = Placeholder();
|
||||
|
||||
const win = await UIWindow({
|
||||
...options,
|
||||
|
||||
body_content: placeholder.html,
|
||||
});
|
||||
|
||||
component.attach(placeholder);
|
||||
component.focus();
|
||||
|
||||
return win;
|
||||
}
|
||||
+13
-717
@@ -19,23 +19,16 @@
|
||||
|
||||
import path from '../lib/path.js';
|
||||
|
||||
import UIContextMenu from './UIContextMenu.js';
|
||||
import UIItem from './UIItem.js';
|
||||
import UIAlert from './UIAlert.js';
|
||||
import UIWindow from './UIWindow.js';
|
||||
import UIWindowSaveAccount from './UIWindowSaveAccount.js';
|
||||
import UIAuthLogin from './Auth/UIAuthLogin.js';
|
||||
|
||||
import UIWindowProgress from './UIWindowProgress.js';
|
||||
import new_context_menu_item from '../helpers/newContextMenuItem.js';
|
||||
import refresh_item_container from '../helpers/refreshItemContainer.js';
|
||||
import { atPath, retargetNavHistory, retargetPaths, underPath } from '../helpers/pathElements.js';
|
||||
import truncate_filename from '../helpers/truncateFilename.js';
|
||||
import UINotification from './UINotification.js';
|
||||
import launch_app from '../helpers/launchApp.js';
|
||||
import { urlFileLaunchOptions } from '../helpers/confirmUrlFileAccess.js';
|
||||
import item_icon from '../helpers/itemIcon.js';
|
||||
import { SHARED_PATH_PARAM, clear_shared_param } from '../helpers/parseSharedPath.js';
|
||||
import resolve_shared_item from '../helpers/resolveSharedItem.js';
|
||||
import {
|
||||
answerNotificationReceipts,
|
||||
@@ -62,7 +55,7 @@ import apply_item_added_to_containers from '../helpers/applyItemAddedToContainer
|
||||
import parse_item_metadata from '../helpers/parseItemMetadata.js';
|
||||
import { resolve_default_app } from '../helpers/defaultApp.js';
|
||||
|
||||
async function UIDesktop (options) {
|
||||
async function UIDesktop () {
|
||||
// start a transaction if we're not in embedded or fullpage mode
|
||||
let transaction;
|
||||
if ( !window.is_embedded && !window.is_fullpage_mode ) {
|
||||
@@ -72,58 +65,6 @@ async function UIDesktop (options) {
|
||||
|
||||
let h = '';
|
||||
|
||||
// Set up the desktop channel for communication between different tabs in the same browser
|
||||
window.channel = new BroadcastChannel('puter-desktop-channel');
|
||||
channel.onmessage = function (e) {
|
||||
};
|
||||
|
||||
// Initialize desktop icons visibility preference - move this earlier in the initialization
|
||||
// Add this near the very beginning of the UIDesktop function
|
||||
window.desktop_icons_hidden = false; // Set default value immediately
|
||||
|
||||
// Give Camera and Recorder write permissions to Desktop
|
||||
puter.kv.get('has_set_default_app_user_permissions').then(async (user_permissions) => {
|
||||
if ( ! user_permissions ) {
|
||||
// Camera
|
||||
try {
|
||||
await fetch(`${window.api_origin }/auth/grant-user-app`, {
|
||||
'headers': {
|
||||
'Content-Type': 'application/json',
|
||||
'Authorization': `Bearer ${ window.auth_token}`,
|
||||
},
|
||||
'body': JSON.stringify({
|
||||
app_uid: 'app-5584fbf7-ed69-41fc-99cd-85da21b1ef51',
|
||||
permission: `fs:${html_encode(window.desktop_path)}:write`,
|
||||
}),
|
||||
'method': 'POST',
|
||||
});
|
||||
} catch ( err ) {
|
||||
console.error(err);
|
||||
}
|
||||
|
||||
// Recorder
|
||||
try {
|
||||
await fetch(`${window.api_origin }/auth/grant-user-app`, {
|
||||
'headers': {
|
||||
'Content-Type': 'application/json',
|
||||
'Authorization': `Bearer ${ window.auth_token}`,
|
||||
},
|
||||
'body': JSON.stringify({
|
||||
app_uid: 'app-7bdca1a4-6373-4c98-ad97-03ff2d608ca1',
|
||||
permission: `fs:${html_encode(window.desktop_path)}:write`,
|
||||
}),
|
||||
'method': 'POST',
|
||||
});
|
||||
} catch ( err ) {
|
||||
console.error(err);
|
||||
}
|
||||
|
||||
// Set flag to true
|
||||
await puter.kv.set('has_set_default_app_user_permissions', true);
|
||||
}
|
||||
// Awaited above so a failed write reaches this: it leaves the flag unset
|
||||
// and the whole thing is retried next boot, which is what we want.
|
||||
}).catch(err => console.warn('Could not apply default app permissions:', err));
|
||||
// connect socket.
|
||||
window.socket = io(`${window.gui_origin }/`, {
|
||||
auth: {
|
||||
@@ -713,16 +654,8 @@ async function UIDesktop (options) {
|
||||
|
||||
h += '<div class="window-container"></div>';
|
||||
|
||||
// Desktop
|
||||
// If desktop is not in fullpage/embedded mode, we hide it until files and directories are loaded and then fade in the UI
|
||||
// This gives a calm and smooth experience for the user
|
||||
h += `<div class="desktop item-container disable-user-select"
|
||||
data-uid="${options.desktop_fsentry?.uid ?? ''}"
|
||||
data-sort_by="${!options.desktop_fsentry?.sort_by ? 'name' : options.desktop_fsentry.sort_by}"
|
||||
data-sort_order="${!options.desktop_fsentry?.sort_order ? 'asc' : options.desktop_fsentry.sort_order}"
|
||||
data-path="${html_encode(window.desktop_path)}"
|
||||
>`;
|
||||
h += '</div>';
|
||||
// The surface windows open on. It holds no items.
|
||||
h += '<div class="desktop disable-user-select"></div>';
|
||||
|
||||
// Get window sidebar width
|
||||
puter.kv.get('window_sidebar_width').catch(() => null).then(async (val) => {
|
||||
@@ -758,415 +691,25 @@ async function UIDesktop (options) {
|
||||
// Append to <body>
|
||||
$('body').append(h);
|
||||
|
||||
// Initialize the preference early
|
||||
puter.kv.get('desktop_icons_hidden').then(async (val) => {
|
||||
window.desktop_icons_hidden = (val === 'true' || val === true);
|
||||
|
||||
// Apply the setting immediately if needed
|
||||
if ( window.desktop_icons_hidden ) {
|
||||
hideDesktopIcons();
|
||||
}
|
||||
}).catch(err => console.warn('Could not load desktop_icons_hidden:', err));
|
||||
|
||||
const el_desktop = document.querySelector('.desktop');
|
||||
|
||||
window.active_element = el_desktop;
|
||||
window.active_item_container = el_desktop;
|
||||
|
||||
// --------------------------------------------------------
|
||||
// Dragster
|
||||
// Allow dragging of local files onto desktop.
|
||||
// --------------------------------------------------------
|
||||
$(el_desktop).dragster({
|
||||
enter: function (dragsterEvent, event) {
|
||||
$('.context-menu').remove();
|
||||
},
|
||||
leave: function (dragsterEvent, event) {
|
||||
},
|
||||
drop: async function (dragsterEvent, event) {
|
||||
const e = event.originalEvent;
|
||||
// no drop on item
|
||||
if ( $(event.target).hasClass('item') || $(event.target).parent('.item').length > 0 )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
// recursively create directories and upload files
|
||||
if ( e.dataTransfer?.items?.length > 0 ) {
|
||||
window.upload_items(e.dataTransfer.items, window.desktop_path);
|
||||
}
|
||||
|
||||
e.stopPropagation();
|
||||
e.preventDefault();
|
||||
return false;
|
||||
},
|
||||
// The desktop has no menu of its own, and the browser's doesn't belong here.
|
||||
$(el_desktop).on('contextmenu', function (event) {
|
||||
if ( event.target === el_desktop ) event.preventDefault();
|
||||
});
|
||||
|
||||
// --------------------------------------------------------
|
||||
// Droppable
|
||||
// --------------------------------------------------------
|
||||
$(el_desktop).droppable({
|
||||
accept: '.item',
|
||||
tolerance: 'intersect',
|
||||
drop: function (event, ui) {
|
||||
// Check if item was actually dropped on desktop and not a window
|
||||
if ( window.mouseover_window !== undefined )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Can't drop anything but UIItems on desktop
|
||||
if ( ! $(ui.draggable).hasClass('item') )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Don't move an item to its current directory
|
||||
if ( path.dirname($(ui.draggable).attr('data-path')) === window.desktop_path && !event.ctrlKey )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// If ctrl is pressed and source is Trashed, cancel whole operation
|
||||
if ( event.ctrlKey && path.dirname($(ui.draggable).attr('data-path')) === window.trash_path )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Unselect previously selected items
|
||||
$(el_desktop).children('.item-selected').removeClass('item-selected');
|
||||
|
||||
const items_to_move = [];
|
||||
// first item
|
||||
items_to_move.push(ui.draggable);
|
||||
|
||||
// all subsequent items
|
||||
const cloned_items = document.getElementsByClassName('item-selected-clone');
|
||||
for ( let i = 0; i < cloned_items.length; i++ ) {
|
||||
const source_item = document.getElementById(`item-${ $(cloned_items[i]).attr('data-id')}`);
|
||||
if ( source_item !== null )
|
||||
{
|
||||
items_to_move.push(source_item);
|
||||
}
|
||||
}
|
||||
|
||||
// if ctrl key is down, copy items
|
||||
if ( event.ctrlKey ) {
|
||||
// unless source is Trash
|
||||
if ( path.dirname($(ui.draggable).attr('data-path')) === window.trash_path )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
window.copy_items(items_to_move, window.desktop_path);
|
||||
}
|
||||
// otherwise, move items
|
||||
else {
|
||||
window.move_items(items_to_move, window.desktop_path);
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
//--------------------------------------------------
|
||||
// ContextMenu
|
||||
//--------------------------------------------------
|
||||
$(el_desktop).bind('contextmenu taphold', function (event) {
|
||||
// dismiss taphold on regular devices
|
||||
if ( event.type === 'taphold' && !isMobile.phone && !isMobile.tablet )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
const $target = $(event.target);
|
||||
|
||||
// elements that should retain native ctxmenu
|
||||
if ( $target.is('input') || $target.is('textarea') )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
// custom ctxmenu for all other elements
|
||||
if ( event.target === el_desktop ) {
|
||||
event.preventDefault();
|
||||
UIContextMenu({
|
||||
position: event.type === 'taphold' ? undefined : { left: event.pageX, top: event.pageY },
|
||||
items: [
|
||||
// -------------------------------------------
|
||||
// Sort by
|
||||
// -------------------------------------------
|
||||
{
|
||||
html: i18n('sort_by'),
|
||||
items: [
|
||||
{
|
||||
html: i18n('auto_arrange'),
|
||||
icon: window.is_auto_arrange_enabled ? '✓' : '',
|
||||
onClick: async function () {
|
||||
window.is_auto_arrange_enabled = !window.is_auto_arrange_enabled;
|
||||
window.store_auto_arrange_preference(window.is_auto_arrange_enabled);
|
||||
if ( window.is_auto_arrange_enabled ) {
|
||||
window.sort_items(el_desktop, $(el_desktop).attr('data-sort_by'), $(el_desktop).attr('data-sort_order'));
|
||||
window.set_sort_by(options.desktop_fsentry.uid, $(el_desktop).attr('data-sort_by'), $(el_desktop).attr('data-sort_order'));
|
||||
window.clear_desktop_item_positions(el_desktop);
|
||||
} else {
|
||||
window.set_desktop_item_positions(el_desktop);
|
||||
}
|
||||
},
|
||||
},
|
||||
// -------------------------------------------
|
||||
// -
|
||||
// -------------------------------------------
|
||||
'-',
|
||||
{
|
||||
html: i18n('name'),
|
||||
disabled: !window.is_auto_arrange_enabled,
|
||||
icon: $(el_desktop).attr('data-sort_by') === 'name' ? '✓' : '',
|
||||
onClick: async function () {
|
||||
window.sort_items(el_desktop, 'name', $(el_desktop).attr('data-sort_order'));
|
||||
window.set_sort_by(options.desktop_fsentry.uid, 'name', $(el_desktop).attr('data-sort_order'));
|
||||
},
|
||||
},
|
||||
{
|
||||
html: i18n('date_modified'),
|
||||
disabled: !window.is_auto_arrange_enabled,
|
||||
icon: $(el_desktop).attr('data-sort_by') === 'modified' ? '✓' : '',
|
||||
onClick: async function () {
|
||||
window.sort_items(el_desktop, 'modified', $(el_desktop).attr('data-sort_order'));
|
||||
window.set_sort_by(options.desktop_fsentry.uid, 'modified', $(el_desktop).attr('data-sort_order'));
|
||||
},
|
||||
},
|
||||
{
|
||||
html: i18n('type'),
|
||||
disabled: !window.is_auto_arrange_enabled,
|
||||
icon: $(el_desktop).attr('data-sort_by') === 'type' ? '✓' : '',
|
||||
onClick: async function () {
|
||||
window.sort_items(el_desktop, 'type', $(el_desktop).attr('data-sort_order'));
|
||||
window.set_sort_by(options.desktop_fsentry.uid, 'type', $(el_desktop).attr('data-sort_order'));
|
||||
},
|
||||
},
|
||||
{
|
||||
html: i18n('size'),
|
||||
disabled: !window.is_auto_arrange_enabled,
|
||||
icon: $(el_desktop).attr('data-sort_by') === 'size' ? '✓' : '',
|
||||
onClick: async function () {
|
||||
window.sort_items(el_desktop, 'size', $(el_desktop).attr('data-sort_order'));
|
||||
window.set_sort_by(options.desktop_fsentry.uid, 'size', $(el_desktop).attr('data-sort_order'));
|
||||
},
|
||||
},
|
||||
// -------------------------------------------
|
||||
// -
|
||||
// -------------------------------------------
|
||||
'-',
|
||||
{
|
||||
html: i18n('ascending'),
|
||||
disabled: !window.is_auto_arrange_enabled,
|
||||
icon: $(el_desktop).attr('data-sort_order') === 'asc' ? '✓' : '',
|
||||
onClick: async function () {
|
||||
const sort_by = $(el_desktop).attr('data-sort_by');
|
||||
window.sort_items(el_desktop, sort_by, 'asc');
|
||||
window.set_sort_by(options.desktop_fsentry.uid, sort_by, 'asc');
|
||||
},
|
||||
},
|
||||
{
|
||||
html: i18n('descending'),
|
||||
disabled: !window.is_auto_arrange_enabled,
|
||||
icon: $(el_desktop).attr('data-sort_order') === 'desc' ? '✓' : '',
|
||||
onClick: async function () {
|
||||
const sort_by = $(el_desktop).attr('data-sort_by');
|
||||
window.sort_items(el_desktop, sort_by, 'desc');
|
||||
window.set_sort_by(options.desktop_fsentry.uid, sort_by, 'desc');
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
// -------------------------------------------
|
||||
// Refresh
|
||||
// -------------------------------------------
|
||||
{
|
||||
html: i18n('refresh'),
|
||||
onClick: function () {
|
||||
refresh_item_container(el_desktop, { consistency: 'strong' });
|
||||
},
|
||||
},
|
||||
// -------------------------------------------
|
||||
// Show/Hide hidden files
|
||||
// -------------------------------------------
|
||||
{
|
||||
html: i18n('show_hidden'),
|
||||
icon: window.user_preferences.show_hidden_files ? '✓' : '',
|
||||
onClick: function () {
|
||||
window.mutate_user_preferences({
|
||||
show_hidden_files: !window.user_preferences.show_hidden_files,
|
||||
});
|
||||
window.show_or_hide_files(document.querySelectorAll('.item-container'));
|
||||
},
|
||||
},
|
||||
// -------------------------------------------
|
||||
// Hide Desktop Icons
|
||||
// -------------------------------------------
|
||||
{
|
||||
html: window.desktop_icons_hidden ? i18n('Show desktop icons') : i18n('Hide desktop icons'),
|
||||
onClick: function () {
|
||||
toggleDesktopIcons();
|
||||
},
|
||||
},
|
||||
// -------------------------------------------
|
||||
// -
|
||||
// -------------------------------------------
|
||||
'-',
|
||||
// -------------------------------------------
|
||||
// New File
|
||||
// -------------------------------------------
|
||||
new_context_menu_item(window.desktop_path, el_desktop),
|
||||
// -------------------------------------------
|
||||
// -
|
||||
// -------------------------------------------
|
||||
'-',
|
||||
// -------------------------------------------
|
||||
// Paste
|
||||
// -------------------------------------------
|
||||
{
|
||||
html: i18n('paste'),
|
||||
disabled: window.clipboard.length > 0 ? false : true,
|
||||
onClick: function () {
|
||||
if ( window.clipboard_op === 'copy' )
|
||||
{
|
||||
window.copy_clipboard_items(window.desktop_path, el_desktop);
|
||||
}
|
||||
else if ( window.clipboard_op === 'move' )
|
||||
{
|
||||
window.move_clipboard_items(el_desktop);
|
||||
}
|
||||
},
|
||||
},
|
||||
// -------------------------------------------
|
||||
// Undo
|
||||
// -------------------------------------------
|
||||
{
|
||||
html: i18n('undo'),
|
||||
disabled: window.actions_history.length > 0 ? false : true,
|
||||
onClick: function () {
|
||||
window.undo_last_action();
|
||||
},
|
||||
},
|
||||
// -------------------------------------------
|
||||
// Upload Here
|
||||
// -------------------------------------------
|
||||
{
|
||||
html: i18n('upload_here'),
|
||||
onClick: function () {
|
||||
window.init_upload_using_dialog(el_desktop);
|
||||
},
|
||||
},
|
||||
],
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
//-------------------------------------------
|
||||
// Desktop Files/Folders
|
||||
// we don't need to get the desktop items if we're in embedded or fullpage mode
|
||||
// because the items aren't visible anyway and we don't need to waste bandwidth/server resources
|
||||
//-------------------------------------------
|
||||
if ( !window.is_embedded && !window.is_fullpage_mode ) {
|
||||
refresh_item_container(el_desktop, {
|
||||
fadeInItems: true,
|
||||
onComplete: () => {
|
||||
// End transaction when desktop is fully ready for user interaction
|
||||
transaction.end();
|
||||
},
|
||||
});
|
||||
transaction.end();
|
||||
|
||||
// perform readdirs for caching purposes
|
||||
|
||||
// home directory
|
||||
// warm the home directory listing for the first Explorer window
|
||||
puter.fs.readdir({ path: window.home_path, consistency: 'strong' });
|
||||
}
|
||||
|
||||
// -------------------------------------------
|
||||
// Selectable
|
||||
// Only for desktop
|
||||
// -------------------------------------------
|
||||
if ( !isMobile.phone && !isMobile.tablet ) {
|
||||
let selected_ctrl_items = [];
|
||||
const selection = new SelectionArea({
|
||||
selectionContainerClass: '.selection-area-container',
|
||||
container: '.desktop',
|
||||
selectables: ['.desktop.item-container > .item'],
|
||||
startareas: ['.desktop'],
|
||||
boundaries: ['.desktop'],
|
||||
behaviour: {
|
||||
overlap: 'drop',
|
||||
intersect: 'touch',
|
||||
startThreshold: 10,
|
||||
scrolling: {
|
||||
speedDivider: 10,
|
||||
manualSpeed: 750,
|
||||
startScrollMargins: { x: 0, y: 0 },
|
||||
},
|
||||
},
|
||||
features: {
|
||||
touch: true,
|
||||
range: true,
|
||||
singleTap: {
|
||||
allow: true,
|
||||
intersect: 'native',
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
selection.on('beforestart', ({ event }) => {
|
||||
selected_ctrl_items = [];
|
||||
// Returning false prevents a selection
|
||||
return $(event.target).hasClass('item-container');
|
||||
})
|
||||
.on('beforedrag', evt => {
|
||||
})
|
||||
.on('start', ({ store, event }) => {
|
||||
if ( !event.ctrlKey && !event.metaKey ) {
|
||||
for ( const el of store.stored ) {
|
||||
el.classList.remove('item-selected');
|
||||
}
|
||||
|
||||
selection.clearSelection();
|
||||
}
|
||||
|
||||
// mark desktop as selectable active
|
||||
$('.desktop').addClass('desktop-selectable-active');
|
||||
})
|
||||
.on('move', ({ store: { changed: { added, removed } }, event }) => {
|
||||
window.desktop_selectable_is_active = true;
|
||||
|
||||
for ( const el of added ) {
|
||||
// if ctrl or meta key is pressed and the item is already selected, then unselect it
|
||||
if ( (event.ctrlKey || event.metaKey) && $(el).hasClass('item-selected') ) {
|
||||
el.classList.remove('item-selected');
|
||||
selected_ctrl_items.push(el);
|
||||
}
|
||||
// otherwise select it
|
||||
else {
|
||||
el.classList.add('item-selected');
|
||||
}
|
||||
}
|
||||
|
||||
for ( const el of removed ) {
|
||||
el.classList.remove('item-selected');
|
||||
// in case this item was selected by ctrl+click before, then reselect it again
|
||||
if ( selected_ctrl_items.includes(el) )
|
||||
{
|
||||
$(el).not('.item-disabled').addClass('item-selected');
|
||||
}
|
||||
}
|
||||
})
|
||||
.on('stop', evt => {
|
||||
window.desktop_selectable_is_active = false;
|
||||
$('.desktop').removeClass('desktop-selectable-active');
|
||||
});
|
||||
}
|
||||
// notification container
|
||||
$('body').append(`<div class="notification-container"><div class="notifications-close-all">${i18n('close_all')}</div></div>`);
|
||||
|
||||
// adjust window container to take into account the toolbar height
|
||||
$('.window-container').css('top', window.toolbar_height);
|
||||
|
||||
// track: checkpoint
|
||||
//-----------------------------
|
||||
// GUI is ready to launch apps!
|
||||
@@ -1200,41 +743,10 @@ async function UIDesktop (options) {
|
||||
}
|
||||
}
|
||||
}
|
||||
//--------------------------------------------------------------------------------------
|
||||
// /settings redirects to /dashboard
|
||||
//--------------------------------------------------------------------------------------
|
||||
else if ( window.url_paths[0]?.toLocaleLowerCase() === 'settings' ) {
|
||||
window.open('/dashboard/#home', '_blank');
|
||||
}
|
||||
// ---------------------------------------------
|
||||
// Run apps from insta-login URL
|
||||
// ---------------------------------------------
|
||||
if ( window.url_query_params.has('app') ) {
|
||||
let url_app_name = window.url_query_params.get('app');
|
||||
if ( url_app_name === 'explorer' ) {
|
||||
let predefined_path = window.home_path;
|
||||
if ( window.url_query_params.has('path') )
|
||||
{
|
||||
predefined_path = window.url_query_params.get('path');
|
||||
}
|
||||
// launch explorer
|
||||
UIWindow({
|
||||
path: predefined_path,
|
||||
title: path.basename(predefined_path),
|
||||
icon: await item_icon({ is_dir: true, path: predefined_path }),
|
||||
// todo
|
||||
// uid: $(el_item).attr('data-uid'),
|
||||
is_dir: true,
|
||||
// todo
|
||||
// sort_by: $(el_item).attr('data-sort_by'),
|
||||
app: 'explorer',
|
||||
});
|
||||
}
|
||||
}
|
||||
// ---------------------------------------------
|
||||
// load from direct app URLs: /app/app-name
|
||||
// ---------------------------------------------
|
||||
else if ( window.app_launched_from_url ) {
|
||||
if ( window.app_launched_from_url ) {
|
||||
if ( ! window.url_query_params.has('c') ) {
|
||||
let posargs = undefined;
|
||||
if ( window.app_query_params && window.app_query_params.posargs ) {
|
||||
@@ -1270,56 +782,17 @@ async function UIDesktop (options) {
|
||||
return;
|
||||
}
|
||||
|
||||
// disable pointer-events for all app iframes, this is to make sure selectable works
|
||||
$('.window-app-iframe').css('pointer-events', 'none');
|
||||
$('.window').find('.item-selected').addClass('item-blurred');
|
||||
$('.desktop').find('.item-blurred').removeClass('item-blurred');
|
||||
// Keyboard shortcuts act on the active container, and a click here leaves every window's.
|
||||
window.active_item_container = null;
|
||||
});
|
||||
|
||||
$(el_desktop).on('click', function (e) {
|
||||
$(el_desktop).on('click', function () {
|
||||
// blur all windows
|
||||
$('.window-active').removeClass('window-active');
|
||||
// hide all global menubars
|
||||
$('.window-menubar-global').hide();
|
||||
});
|
||||
|
||||
//--------------------------------------------------------------------------------------
|
||||
// Trying to view a user's public folder?
|
||||
// i.e. https://puter.com/@<username>
|
||||
//--------------------------------------------------------------------------------------
|
||||
const url_paths = window.location.pathname.split('/').filter(element => element);
|
||||
if ( window.url_paths[0]?.startsWith('@') ) {
|
||||
const username = window.url_paths[0].substring(1);
|
||||
let item_path = `/${ username }/Public`;
|
||||
if ( window.url_paths.length > 1 ) {
|
||||
item_path += `/${ window.url_paths.slice(1).join('/')}`;
|
||||
}
|
||||
|
||||
// GUARD: avoid invalid user directories
|
||||
{
|
||||
if ( ! username.match(/^[a-z0-9_]+$/i) ) {
|
||||
UIAlert({
|
||||
message: i18n('error_invalid_username'),
|
||||
});
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
let stat;
|
||||
try {
|
||||
stat = await puter.fs.stat({ path: item_path, consistency: 'eventual' });
|
||||
} catch ( e ) {
|
||||
window.history.replaceState(null, document.title, '/desktop');
|
||||
UIAlert({
|
||||
message: i18n('error_user_or_path_not_found'),
|
||||
type: 'error',
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
await open_path_target(item_path, stat);
|
||||
}
|
||||
|
||||
/**
|
||||
* Open a path as double-clicking would: the associated app for a file, an
|
||||
* explorer window for a directory.
|
||||
@@ -1374,7 +847,6 @@ async function UIDesktop (options) {
|
||||
file_path: item_path,
|
||||
app_obj: suggested_apps[0],
|
||||
window_title: path.basename(item_path),
|
||||
maximized: options.maximized,
|
||||
file_signature: open_item_meta.signature,
|
||||
custom_path: window.location.pathname,
|
||||
});
|
||||
@@ -1412,157 +884,6 @@ async function UIDesktop (options) {
|
||||
await open_path_target(stat.path ?? shared_path, stat);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Act on a share link. A share to a person only ever reaches a real
|
||||
* account, so for a temporary session the item is tried first — an item
|
||||
* open to anyone with the link resolves for it — and only a miss asks
|
||||
* for a sign-in, rather than burning the link on a "not found" as
|
||||
* somebody who can't see it. The link stays in the address bar across
|
||||
* the prompt because login reloads on success, which brings it back for
|
||||
* the account that can actually open it.
|
||||
*/
|
||||
async function handle_shared_link (shared_path) {
|
||||
if ( window.user?.is_temp ) {
|
||||
const stat = await resolve_shared_item(puter.fs, shared_path);
|
||||
if ( stat ) {
|
||||
clear_shared_param();
|
||||
await open_path_target(stat.path ?? shared_path, stat);
|
||||
return;
|
||||
}
|
||||
await UIAuthLogin({
|
||||
reload_on_success: true,
|
||||
page: true,
|
||||
});
|
||||
// Dismissed without signing in: drop the link rather than loop.
|
||||
if ( window.user?.is_temp ) clear_shared_param();
|
||||
return;
|
||||
}
|
||||
clear_shared_param();
|
||||
await open_shared_item(shared_path);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------
|
||||
// Opening an item someone shared, on the desktop
|
||||
// i.e. https://puter.com/desktop?shared=%2F<owner>%2F<uuid>%2F<name>
|
||||
// (the same link at the root lands in the dashboard's Shared view instead)
|
||||
//--------------------------------------------------------------------------------------
|
||||
if ( window.url_query_params.has(SHARED_PATH_PARAM) ) {
|
||||
await handle_shared_link(window.url_query_params.get(SHARED_PATH_PARAM));
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------
|
||||
// Direct download link
|
||||
// i.e. https://puter.com/?download=<file_url> or https://puter.com/desktop?download=<file_url>
|
||||
//--------------------------------------------------------------------------------------
|
||||
const is_bare_desktop_path = window.url_paths.length === 0
|
||||
|| (window.url_paths.length === 1 && window.url_paths[0]?.toLocaleLowerCase() === 'desktop');
|
||||
if ( is_bare_desktop_path && window.url_query_params.has('download') ) {
|
||||
const url = window.url_query_params.get('download');
|
||||
let file_name = url.split('/').pop().split('?')[0];
|
||||
|
||||
let response = await UIAlert({
|
||||
message: i18n('confirm_download_file_to_desktop', file_name),
|
||||
type: 'confirm',
|
||||
buttons: [
|
||||
{ label: i18n('alert_yes'), value: true, type: 'primary' },
|
||||
{ label: i18n('alert_no'), value: false, type: 'secondary' },
|
||||
],
|
||||
});
|
||||
|
||||
if ( ! response )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
let cancelled = false;
|
||||
let upload_xhr = null;
|
||||
const abort_controller = new AbortController();
|
||||
|
||||
// create progressbar dialog
|
||||
let progwin = await UIWindowProgress({
|
||||
title: i18n('downloading'),
|
||||
icon: window.icons['app-icon-uploader.svg'],
|
||||
operation_id: window.uuidv4(),
|
||||
show_progress: true,
|
||||
on_cancel: () => {
|
||||
cancelled = true;
|
||||
abort_controller.abort();
|
||||
if ( upload_xhr ) {
|
||||
upload_xhr.abort();
|
||||
}
|
||||
},
|
||||
});
|
||||
progwin?.set_status(i18n('downloading_file', file_name));
|
||||
|
||||
(async () => {
|
||||
try {
|
||||
// download the file
|
||||
const response = await puter.net.fetch(url, {
|
||||
signal: abort_controller.signal,
|
||||
});
|
||||
|
||||
const total = Number(response.headers.get('content-length'));
|
||||
const reader = response.body.getReader();
|
||||
|
||||
const chunks = [];
|
||||
let received = 0;
|
||||
|
||||
while ( true ) {
|
||||
const { done, value } = await reader.read();
|
||||
if ( done || cancelled ) break;
|
||||
|
||||
if ( value ) {
|
||||
// store the chunk
|
||||
chunks.push(value);
|
||||
received += value.length;
|
||||
// calculate progress
|
||||
const progress = Number.isFinite(total) && total > 0
|
||||
? received / total
|
||||
: 0;
|
||||
// update progressbar
|
||||
progwin?.set_progress(Math.floor(progress * 100));
|
||||
}
|
||||
}
|
||||
|
||||
if ( cancelled ) {
|
||||
progwin?.close();
|
||||
return;
|
||||
}
|
||||
|
||||
// combine chunks into a blob
|
||||
let blob = new Blob(chunks, {
|
||||
type: response.headers.get('content-type') ?? 'application/octet-stream',
|
||||
});
|
||||
|
||||
// reset progressbar
|
||||
progwin?.set_progress(0);
|
||||
progwin?.set_status(i18n('uploading_file', file_name));
|
||||
|
||||
// upload to user's desktop
|
||||
await puter.fs.write(`~/Desktop/${file_name}`, blob, {
|
||||
dedupeName: true,
|
||||
progress: (_, percent) => {
|
||||
// update progressbar
|
||||
progwin?.set_progress(percent);
|
||||
},
|
||||
init: (_, xhr) => {
|
||||
upload_xhr = xhr;
|
||||
},
|
||||
});
|
||||
} catch (e) {
|
||||
// alert the user if there's a genuine error
|
||||
if ( !cancelled && e.name !== 'AbortError' ) {
|
||||
await UIAlert({
|
||||
message: `${i18n('error_download_failed') }: ${ e.message}`,
|
||||
type: 'error',
|
||||
});
|
||||
}
|
||||
}
|
||||
// close progress window
|
||||
progwin?.close();
|
||||
})();
|
||||
}
|
||||
}
|
||||
|
||||
window.enter_fullpage_mode = (el_window) => {
|
||||
@@ -1571,7 +892,7 @@ window.enter_fullpage_mode = (el_window) => {
|
||||
$(el_window).css({
|
||||
width: '100%',
|
||||
height: '100%',
|
||||
top: `${window.toolbar_height }px`,
|
||||
top: 0,
|
||||
left: 0,
|
||||
'border-radius': 0,
|
||||
});
|
||||
@@ -1579,7 +900,6 @@ window.enter_fullpage_mode = (el_window) => {
|
||||
|
||||
window.exit_fullpage_mode = (el_window) => {
|
||||
$('body').removeClass('fullpage-mode');
|
||||
refresh_item_container($('.desktop.item-container'), { fadeInItems: true });
|
||||
$(el_window).removeAttr('data-is_fullpage');
|
||||
if ( el_window ) {
|
||||
window.reset_window_size_and_position(el_window);
|
||||
@@ -1597,28 +917,4 @@ window.reset_window_size_and_position = (el_window) => {
|
||||
});
|
||||
};
|
||||
|
||||
// Modify the hide/show functions to use CSS rules that will apply to all icons, including future ones
|
||||
window.hideDesktopIcons = function () {
|
||||
$('.desktop.item-container').addClass('desktop-icons-hidden');
|
||||
};
|
||||
|
||||
window.showDesktopIcons = function () {
|
||||
$('.desktop.item-container').removeClass('desktop-icons-hidden');
|
||||
};
|
||||
|
||||
// Add this function to the global scope
|
||||
window.toggleDesktopIcons = function () {
|
||||
window.desktop_icons_hidden = !window.desktop_icons_hidden;
|
||||
|
||||
if ( window.desktop_icons_hidden ) {
|
||||
hideDesktopIcons();
|
||||
} else {
|
||||
showDesktopIcons();
|
||||
}
|
||||
|
||||
// Save preference
|
||||
puter.kv.set('desktop_icons_hidden', window.desktop_icons_hidden.toString())
|
||||
.catch(err => console.warn('Could not save desktop_icons_hidden:', err));
|
||||
};
|
||||
|
||||
export default UIDesktop;
|
||||
@@ -25,7 +25,6 @@ import path from '../lib/path.js';
|
||||
import truncate_filename from '../helpers/truncateFilename.js';
|
||||
import launch_app from '../helpers/launchApp.js';
|
||||
import open_item from '../helpers/openItem.js';
|
||||
import publish_as_website from '../helpers/publishAsWebsite.js';
|
||||
import { isWeblinkName, weblinkChangeIconMenuItem } from '../helpers/weblink.js';
|
||||
import { is_owned_by_me } from '../helpers/pathOwner.js';
|
||||
import { can_rename, can_restructure, invalidate_shared_roots } from '../helpers/sharedAccess.js';
|
||||
@@ -235,17 +234,6 @@ async function UIItem (options) {
|
||||
window.update_explorer_footer_item_count(el_window);
|
||||
}
|
||||
|
||||
// manual positioning
|
||||
if ( !window.is_auto_arrange_enabled &&
|
||||
options.position &&
|
||||
// item is on the desktop (must be desktop itself and not a window, hence the '.desktop' class check)
|
||||
$(el_item).closest('.item-container.desktop').attr('data-path') === window.desktop_path
|
||||
) {
|
||||
el_item.style.position = 'absolute';
|
||||
el_item.style.left = `${options.position.left }px`;
|
||||
el_item.style.top = `${options.position.top }px`;
|
||||
}
|
||||
|
||||
// --------------------------------------------------------
|
||||
// Dragster
|
||||
// allow dragging of local files on this window, if it's is_dir
|
||||
@@ -330,8 +318,8 @@ async function UIItem (options) {
|
||||
// Constrain item within desktop bounds
|
||||
const minLeft = -50;
|
||||
const maxLeft = window.desktop_width - 50;
|
||||
const minTop = window.toolbar_height;
|
||||
const maxTop = window.desktop_height + window.toolbar_height;
|
||||
const minTop = 0;
|
||||
const maxTop = window.desktop_height;
|
||||
|
||||
// Apply constraints to ui.position
|
||||
ui.position.left = Math.max(minLeft, Math.min(maxLeft, ui.position.left));
|
||||
@@ -410,21 +398,6 @@ async function UIItem (options) {
|
||||
}
|
||||
},
|
||||
stop: function (event, ui) {
|
||||
// Allow rearranging only if item is on desktop, not trash container, auto arrange is disabled and item is not dropped into another item
|
||||
// the desktop itself, not a window showing the Desktop folder
|
||||
if ( $(el_item).closest('.item-container').hasClass('desktop') &&
|
||||
!window.is_auto_arrange_enabled && $(el_item).attr('data-path') !== window.trash_path && !ui.helper.data('dropped') &&
|
||||
// .desktop clips its overflow, so the whole item has to fit above the bottom edge
|
||||
window.mouseover_window === undefined && ui.position.top + $(el_item).outerHeight(true) <= window.desktop_height ) {
|
||||
|
||||
el_item.style.position = 'absolute';
|
||||
el_item.style.left = `${ui.position.left }px`;
|
||||
el_item.style.top = `${ui.position.top }px`;
|
||||
$('.ui-draggable-dragging').remove();
|
||||
window.desktop_item_positions[$(el_item).attr('data-uid')] = ui.position;
|
||||
window.save_desktop_item_positions();
|
||||
}
|
||||
|
||||
$('.item-selected-clone').remove();
|
||||
$('.draggable-count-badge').remove();
|
||||
// re-enable all droppable UIItems that are not a dir
|
||||
@@ -547,11 +520,6 @@ async function UIItem (options) {
|
||||
else if ( options.is_dir ) {
|
||||
// a selected folder can be the drop target of its own selection; it stays where it is
|
||||
const items_to_drop = items_to_move.filter(item => $(item).attr('data-uid') !== $(el_item).attr('data-uid'));
|
||||
if ( $(el_item).closest('.item-container').attr('data-path') === window.desktop_path ) {
|
||||
// the items leaving the desktop lose their saved positions, not the folder they land in
|
||||
items_to_drop.forEach(item => delete window.desktop_item_positions[$(item).attr('data-uid')]);
|
||||
window.save_desktop_item_positions();
|
||||
}
|
||||
window.move_items(items_to_drop, $(el_item).attr('data-shortcut_to_path') !== '' ? $(el_item).attr('data-shortcut_to_path') : $(el_item).attr('data-path'));
|
||||
}
|
||||
}
|
||||
@@ -1242,23 +1210,6 @@ async function UIItem (options) {
|
||||
}
|
||||
}
|
||||
// -------------------------------------------
|
||||
// Publish As Website
|
||||
// -------------------------------------------
|
||||
if ( !is_trashed && !is_trash && options.is_dir ) {
|
||||
menu_items.push({
|
||||
html: i18n('publish_as_website'),
|
||||
disabled: !options.is_dir,
|
||||
onClick: async function () {
|
||||
await publish_as_website({
|
||||
uid: options.uid,
|
||||
name: $(el_item).attr('data-name'),
|
||||
path: $(el_item).attr('data-path'),
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
}
|
||||
// -------------------------------------------
|
||||
// Deploy As App
|
||||
// -------------------------------------------
|
||||
if ( !is_trashed && !is_trash && options.is_dir ) {
|
||||
@@ -1554,7 +1505,7 @@ async function UIItem (options) {
|
||||
left = left > (window.innerWidth - window_width) ? (window.innerWidth - window_width) : left;
|
||||
|
||||
let top = $(el_item).position().top + $(el_item).height();
|
||||
top = top > (window.innerHeight - (window_height + window.toolbar_height)) ? (window.innerHeight - (window_height + window.toolbar_height)) : top;
|
||||
top = top > (window.innerHeight - window_height) ? (window.innerHeight - window_height) : top;
|
||||
|
||||
UIWindowItemProperties(
|
||||
$(el_item).attr('data-name'),
|
||||
@@ -1571,7 +1522,7 @@ async function UIItem (options) {
|
||||
|
||||
// Create ContextMenu
|
||||
UIContextMenu({
|
||||
parent_element: ($(options.appendTo).hasClass('desktop') ? undefined : options.appendTo),
|
||||
parent_element: options.appendTo,
|
||||
position: menu_position,
|
||||
items: menu_items,
|
||||
});
|
||||
|
||||
@@ -29,7 +29,6 @@ vi.mock('./UIContextMenu.js', () => ({ default: vi.fn() }));
|
||||
vi.mock('./UIAlert.js', () => ({ default: vi.fn() }));
|
||||
vi.mock('../helpers/launchApp.js', () => ({ default: vi.fn() }));
|
||||
vi.mock('../helpers/openItem.js', () => ({ default: vi.fn() }));
|
||||
vi.mock('../helpers/publishAsWebsite.js', () => ({ default: vi.fn() }));
|
||||
vi.mock('../helpers/openWithAI.js', () => ({ default: vi.fn() }));
|
||||
vi.mock('../helpers/refreshItemContainer.js', () => ({ default: vi.fn() }));
|
||||
|
||||
@@ -176,52 +175,23 @@ describe('UIItem Publish as Worker', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('UIItem dropped on the desktop', () => {
|
||||
let stop;
|
||||
describe('UIItem Publish as Website', () => {
|
||||
beforeEach(() => {
|
||||
window.user = { username: 'alice' };
|
||||
window.trash_path = '/alice/Trash';
|
||||
});
|
||||
|
||||
beforeEach(async () => {
|
||||
document.body.innerHTML = '<div class="item-container desktop"></div>';
|
||||
Object.assign(window, {
|
||||
user: { username: 'alice' },
|
||||
trash_path: '/alice/Trash',
|
||||
desktop_height: 800,
|
||||
is_auto_arrange_enabled: false,
|
||||
mouseover_window: undefined,
|
||||
desktop_item_positions: {},
|
||||
save_desktop_item_positions: vi.fn(),
|
||||
it('is not offered, even on a folder the user owns', async () => {
|
||||
const labels = await menuLabels({
|
||||
path: '/alice/Site',
|
||||
name: 'Site',
|
||||
is_dir: true,
|
||||
owner: 'alice',
|
||||
shared_with_me: false,
|
||||
share_mode: undefined,
|
||||
shared_by: undefined,
|
||||
});
|
||||
const draggable = jQuery.fn.draggable;
|
||||
jQuery.fn.draggable = function (options) {
|
||||
if ( typeof options === 'object' ) stop = options.stop;
|
||||
return this;
|
||||
};
|
||||
try {
|
||||
await UIItem({
|
||||
appendTo: $('.item-container'),
|
||||
uid: 'u-2',
|
||||
path: '/alice/Desktop/Notes',
|
||||
name: 'Notes',
|
||||
is_dir: true,
|
||||
icon: { image: '', type: 'icon' },
|
||||
});
|
||||
} finally {
|
||||
jQuery.fn.draggable = draggable;
|
||||
}
|
||||
// jsdom has no stylesheet, so give the item the size style.css does.
|
||||
$('.item').css({ height: '70px', margin: '15px 5px 30px 5px' });
|
||||
});
|
||||
|
||||
const dropAt = (top) => stop({}, { position: { top, left: 300 }, helper: $('<div>') });
|
||||
|
||||
it('moves there when the whole item fits on screen', () => {
|
||||
dropAt(685);
|
||||
expect($('.item')[0].style.top).toBe('685px');
|
||||
expect(window.save_desktop_item_positions).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
it('stays put when the item would hang off the bottom edge', () => {
|
||||
dropAt(735);
|
||||
expect($('.item')[0].style.top).toBe('');
|
||||
expect(window.save_desktop_item_positions).not.toHaveBeenCalled();
|
||||
expect(labels).not.toContain('publish_as_website');
|
||||
expect(labels).toContain('deploy_as_app');
|
||||
});
|
||||
});
|
||||
@@ -82,21 +82,6 @@ function UIQRCode (options) {
|
||||
}
|
||||
}
|
||||
|
||||
// Compatibility shim: Component-based containers (e.g. Flexer) call
|
||||
// `.attach(parent)` on their children. Returning a plain DOM element with
|
||||
// an `attach` method lets this work without making UIQRCode a Component.
|
||||
el.attach = function (destination) {
|
||||
if ( destination instanceof HTMLElement || destination instanceof ShadowRoot ) {
|
||||
destination.appendChild(el);
|
||||
return;
|
||||
}
|
||||
if ( destination && destination.$ === 'placeholder' ) {
|
||||
destination.replaceWith(el);
|
||||
return;
|
||||
}
|
||||
throw new Error(`Unknown destination type: ${destination}`);
|
||||
};
|
||||
|
||||
return el;
|
||||
}
|
||||
|
||||
|
||||
@@ -57,7 +57,6 @@ beforeEach(() => {
|
||||
window_counter: 0,
|
||||
last_window_zindex: 1,
|
||||
window_stack: [],
|
||||
toolbar_height: 0,
|
||||
icons: {},
|
||||
uuidv4: () => crypto.randomUUID(),
|
||||
is_dashboard_mode: false,
|
||||
|
||||
+26
-344
@@ -28,7 +28,6 @@ import { atPath } from '../helpers/pathElements.js';
|
||||
import { resolve_typed_path } from '../helpers/expandHomePath.js';
|
||||
import UIWindowAppFeedback from './UIWindowAppFeedback.js';
|
||||
import launch_app from '../helpers/launchApp.js';
|
||||
import publish_as_website from '../helpers/publishAsWebsite.js';
|
||||
|
||||
import item_icon from '../helpers/itemIcon.js';
|
||||
import { parent_path_for, shared_crumbs_for } from '../helpers/sharePaths.js';
|
||||
@@ -36,7 +35,6 @@ import { has_shared_roots } from '../helpers/sharedAccess.js';
|
||||
import { is_window_hidden, is_unseen_background_window, user_facing_windows } from '../helpers/windowVisibility.js';
|
||||
|
||||
const el_body = document.getElementsByTagName('body')[0];
|
||||
const SNAP_PLACEHOLDER_DELAY_MS = 600; // delay before showing placeholder in any snap zone
|
||||
// Above any z-index an ordinary desktop window reaches in practice.
|
||||
const DESKTOP_BACKDROP_MIN_ZINDEX = 99999;
|
||||
|
||||
@@ -178,9 +176,9 @@ async function UIWindow (options) {
|
||||
|
||||
if ( isMobile.phone && !options.center && !options.dominant ) {
|
||||
options.left = 0;
|
||||
options.top = `${window.toolbar_height }px`;
|
||||
options.top = 0;
|
||||
options.width = '100%';
|
||||
options.height = `calc(100% - ${ window.toolbar_height }px)`;
|
||||
options.height = '100%';
|
||||
} else {
|
||||
options.width += 'px';
|
||||
options.height += 'px';
|
||||
@@ -1671,12 +1669,6 @@ async function UIWindow (options) {
|
||||
});
|
||||
}
|
||||
|
||||
$(el_window_head).mousedown(function () {
|
||||
if ( window_is_snapped ) {
|
||||
$(el_window).draggable( 'option', 'cursorAt', { left: width_before_snap / 2 });
|
||||
}
|
||||
});
|
||||
|
||||
// --------------------------------------------------------
|
||||
// Click On The `Scale` Button
|
||||
// (the little rectangle in the window head)
|
||||
@@ -1772,147 +1764,10 @@ async function UIWindow (options) {
|
||||
// --------------------------------------------------------
|
||||
// Draggable
|
||||
// --------------------------------------------------------
|
||||
let width_before_snap = 0;
|
||||
let height_before_snap = 0;
|
||||
let window_is_snapped = false;
|
||||
let snap_placeholder_active = false;
|
||||
let snap_trigger_timeout;
|
||||
let last_snap_zone;
|
||||
|
||||
if ( options.is_draggable ) {
|
||||
let window_snap_placeholder = $(`<div class="window-snap-placeholder animate__animated animate__zoomIn animate__faster">
|
||||
<div class="window-snap-placeholder-inner"></div>
|
||||
</div>`);
|
||||
|
||||
const showSnapPlaceholder = (zone) => {
|
||||
if ( window_is_snapped || !zone ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const snapDims = getSnapDimensions();
|
||||
let css = null;
|
||||
|
||||
if ( zone === 'w' ) {
|
||||
css = {
|
||||
'display': 'block',
|
||||
'width': snapDims.available_width / 2,
|
||||
'height': snapDims.available_height,
|
||||
'top': snapDims.start_y,
|
||||
'left': snapDims.start_x,
|
||||
'z-index': window.last_window_zindex - 1,
|
||||
};
|
||||
} else if ( zone === 'nw' ) {
|
||||
css = {
|
||||
'display': 'block',
|
||||
'width': snapDims.available_width / 2,
|
||||
'height': snapDims.available_height / 2,
|
||||
'top': snapDims.start_y,
|
||||
'left': snapDims.start_x,
|
||||
'z-index': window.last_window_zindex - 1,
|
||||
};
|
||||
} else if ( zone === 'ne' ) {
|
||||
css = {
|
||||
'display': 'block',
|
||||
'width': snapDims.available_width / 2,
|
||||
'height': snapDims.available_height / 2,
|
||||
'top': snapDims.start_y,
|
||||
'left': snapDims.start_x + snapDims.available_width / 2,
|
||||
'z-index': window.last_window_zindex - 1,
|
||||
};
|
||||
} else if ( zone === 'e' ) {
|
||||
css = {
|
||||
'display': 'block',
|
||||
'width': snapDims.available_width / 2,
|
||||
'height': snapDims.available_height,
|
||||
'top': snapDims.start_y,
|
||||
'left': snapDims.start_x + snapDims.available_width / 2,
|
||||
'z-index': window.last_window_zindex - 1,
|
||||
};
|
||||
} else if ( zone === 'n' ) {
|
||||
css = {
|
||||
'display': 'block',
|
||||
'width': snapDims.available_width,
|
||||
'height': snapDims.available_height,
|
||||
'top': snapDims.start_y,
|
||||
'left': snapDims.start_x,
|
||||
'z-index': window.last_window_zindex - 1,
|
||||
};
|
||||
} else if ( zone === 'sw' ) {
|
||||
css = {
|
||||
'display': 'block',
|
||||
'top': snapDims.start_y + snapDims.available_height / 2,
|
||||
'left': snapDims.start_x,
|
||||
'width': snapDims.available_width / 2,
|
||||
'height': snapDims.available_height / 2,
|
||||
'z-index': window.last_window_zindex - 1,
|
||||
};
|
||||
} else if ( zone === 'se' ) {
|
||||
css = {
|
||||
'display': 'block',
|
||||
'top': snapDims.start_y + snapDims.available_height / 2,
|
||||
'left': snapDims.start_x + snapDims.available_width / 2,
|
||||
'width': snapDims.available_width / 2,
|
||||
'height': snapDims.available_height / 2,
|
||||
'z-index': window.last_window_zindex - 1,
|
||||
};
|
||||
}
|
||||
|
||||
if ( ! css ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
window_snap_placeholder.css(css);
|
||||
|
||||
if ( ! snap_placeholder_active ) {
|
||||
snap_placeholder_active = true;
|
||||
$(el_body).append(window_snap_placeholder);
|
||||
}
|
||||
|
||||
width_before_snap = $(el_window).width();
|
||||
height_before_snap = $(el_window).height();
|
||||
return true;
|
||||
};
|
||||
|
||||
const hideSnapPlaceholder = () => {
|
||||
if ( snap_placeholder_active ) {
|
||||
snap_placeholder_active = false;
|
||||
window_snap_placeholder.fadeOut(80);
|
||||
}
|
||||
};
|
||||
|
||||
$(el_window).draggable({
|
||||
start: function (e, ui) {
|
||||
window.a_window_is_being_dragged = true;
|
||||
last_snap_zone = undefined;
|
||||
if ( snap_trigger_timeout ) {
|
||||
clearTimeout(snap_trigger_timeout);
|
||||
snap_trigger_timeout = undefined;
|
||||
}
|
||||
hideSnapPlaceholder();
|
||||
// if window is snapped, unsnap it and reset its position to where it was before snapping
|
||||
if ( options.is_resizable && window_is_snapped ) {
|
||||
window_is_snapped = false;
|
||||
$(el_window).css({
|
||||
'width': width_before_snap,
|
||||
'height': `${height_before_snap }px`,
|
||||
});
|
||||
|
||||
// if at any point the window's width is "too small", hide the sidebar
|
||||
if ( $(el_window).width() < window.window_width_threshold_for_sidebar ) {
|
||||
if ( width_before_snap >= window.window_width_threshold_for_sidebar && !sidebar_hidden ) {
|
||||
$(el_window_sidebar).hide();
|
||||
}
|
||||
sidebar_hidden = true;
|
||||
}
|
||||
// if at any point the window's width is "big enough", show the sidebar
|
||||
else if ( $(el_window).width() >= window.window_width_threshold_for_sidebar ) {
|
||||
if ( sidebar_hidden ) {
|
||||
$(el_window_sidebar).show();
|
||||
}
|
||||
sidebar_hidden = false;
|
||||
}
|
||||
}
|
||||
|
||||
$(el_window).addClass('window-dragging');
|
||||
|
||||
// rm window from original_window_position
|
||||
@@ -1930,50 +1785,9 @@ async function UIWindow (options) {
|
||||
// maximize icon
|
||||
$(el_window_head_scale_btn).find('img').attr('src', window.icons['scale.svg']);
|
||||
}
|
||||
// --------------------------------------------------------
|
||||
// Snap to screen edges
|
||||
// --------------------------------------------------------
|
||||
if ( options.is_resizable ) {
|
||||
const activeZone = window.current_active_snap_zone;
|
||||
|
||||
if ( activeZone !== last_snap_zone ) {
|
||||
if ( snap_trigger_timeout ) {
|
||||
clearTimeout(snap_trigger_timeout);
|
||||
snap_trigger_timeout = undefined;
|
||||
}
|
||||
|
||||
hideSnapPlaceholder();
|
||||
last_snap_zone = activeZone;
|
||||
|
||||
if ( activeZone ) {
|
||||
const scheduledZone = activeZone;
|
||||
snap_trigger_timeout = setTimeout(function () {
|
||||
snap_trigger_timeout = undefined;
|
||||
if ( ! $(el_window).hasClass('window-dragging') ) {
|
||||
return;
|
||||
}
|
||||
if ( window.current_active_snap_zone !== scheduledZone ) {
|
||||
return;
|
||||
}
|
||||
showSnapPlaceholder(scheduledZone);
|
||||
}, SNAP_PLACEHOLDER_DELAY_MS);
|
||||
}
|
||||
}
|
||||
|
||||
if ( ! activeZone ) {
|
||||
hideSnapPlaceholder();
|
||||
}
|
||||
}
|
||||
},
|
||||
stop: function () {
|
||||
window.a_window_is_being_dragged = false;
|
||||
if ( snap_trigger_timeout ) {
|
||||
clearTimeout(snap_trigger_timeout);
|
||||
snap_trigger_timeout = undefined;
|
||||
}
|
||||
last_snap_zone = undefined;
|
||||
let window_will_snap = false;
|
||||
$(el_window).draggable( 'option', 'cursorAt', false);
|
||||
|
||||
$(el_window).removeClass('window-dragging');
|
||||
$(el_window).attr({
|
||||
@@ -1984,114 +1798,24 @@ async function UIWindow (options) {
|
||||
$(el_window_app_iframe).css('pointer-events', 'all');
|
||||
$('.window').css('pointer-events', 'initial');
|
||||
|
||||
if ( options.is_resizable && snap_placeholder_active && !window_is_snapped ) {
|
||||
window_will_snap = true;
|
||||
$(window_snap_placeholder).css('padding', 0);
|
||||
|
||||
setTimeout(function () {
|
||||
const snapDims = getSnapDimensions();
|
||||
|
||||
// snap to w
|
||||
if ( window.current_active_snap_zone === 'w' ) {
|
||||
$(el_window).css({
|
||||
'top': snapDims.start_y,
|
||||
'left': snapDims.start_x,
|
||||
'width': snapDims.available_width / 2,
|
||||
'height': snapDims.available_height - 6,
|
||||
});
|
||||
}
|
||||
// snap to nw
|
||||
else if ( window.current_active_snap_zone === 'nw' ) {
|
||||
$(el_window).css({
|
||||
'top': snapDims.start_y,
|
||||
'left': snapDims.start_x,
|
||||
'width': snapDims.available_width / 2,
|
||||
'height': snapDims.available_height / 2,
|
||||
});
|
||||
}
|
||||
// snap to ne
|
||||
else if ( window.current_active_snap_zone === 'ne' ) {
|
||||
$(el_window).css({
|
||||
'top': snapDims.start_y,
|
||||
'left': snapDims.start_x + snapDims.available_width / 2,
|
||||
'width': snapDims.available_width / 2,
|
||||
'height': snapDims.available_height / 2,
|
||||
});
|
||||
}
|
||||
// snap to sw
|
||||
else if ( window.current_active_snap_zone === 'sw' ) {
|
||||
$(el_window).css({
|
||||
'top': snapDims.start_y + snapDims.available_height / 2,
|
||||
'left': snapDims.start_x,
|
||||
'width': snapDims.available_width / 2,
|
||||
'height': snapDims.available_height / 2,
|
||||
});
|
||||
}
|
||||
// snap to se
|
||||
else if ( window.current_active_snap_zone === 'se' ) {
|
||||
$(el_window).css({
|
||||
'top': snapDims.start_y + snapDims.available_height / 2,
|
||||
'left': snapDims.start_x + snapDims.available_width / 2,
|
||||
'width': snapDims.available_width / 2,
|
||||
'height': snapDims.available_height / 2,
|
||||
});
|
||||
}
|
||||
// snap to e
|
||||
else if ( window.current_active_snap_zone === 'e' ) {
|
||||
$(el_window).css({
|
||||
'top': snapDims.start_y,
|
||||
'left': snapDims.start_x + snapDims.available_width / 2,
|
||||
'width': snapDims.available_width / 2,
|
||||
'height': snapDims.available_height - 6,
|
||||
});
|
||||
}
|
||||
// snap to n
|
||||
else if ( window.current_active_snap_zone === 'n' ) {
|
||||
window.scale_window(el_window);
|
||||
}
|
||||
// snap placeholder is no longer active
|
||||
snap_placeholder_active = false;
|
||||
// hide snap placeholder
|
||||
window_snap_placeholder.css('display', 'none');
|
||||
window_snap_placeholder.css('padding', '10px');
|
||||
// mark window as snapped
|
||||
window_is_snapped = true;
|
||||
|
||||
// if at any point the window's width is "too small", hide the sidebar
|
||||
if ( $(el_window).width() < window.window_width_threshold_for_sidebar ) {
|
||||
if ( width_before_snap >= window.window_width_threshold_for_sidebar && !sidebar_hidden ) {
|
||||
$(el_window_sidebar).hide();
|
||||
}
|
||||
sidebar_hidden = true;
|
||||
}
|
||||
// if at any point the window's width is "big enough", show the sidebar
|
||||
else if ( $(el_window).width() >= window.window_width_threshold_for_sidebar ) {
|
||||
if ( sidebar_hidden ) {
|
||||
$(el_window_sidebar).show();
|
||||
}
|
||||
sidebar_hidden = false;
|
||||
}
|
||||
}, 100);
|
||||
}
|
||||
|
||||
// if window is dropped outside the available area, move it back in
|
||||
// the '- 30' is to account for the window head
|
||||
const maxTop = window.innerHeight - 30;
|
||||
if ( $(el_window).position().top > maxTop && !window_will_snap ) {
|
||||
if ( $(el_window).position().top > maxTop ) {
|
||||
$(el_window).animate({
|
||||
top: maxTop - 30,
|
||||
}, 100);
|
||||
}
|
||||
// if window is dropped too far to the right, move it left
|
||||
const maxLeft = window.innerWidth - 50;
|
||||
if ( $(el_window).position().left > maxLeft && !window_will_snap ) {
|
||||
if ( $(el_window).position().left > maxLeft ) {
|
||||
$(el_window).animate({
|
||||
left: maxLeft,
|
||||
}, 100);
|
||||
}
|
||||
// if window is dropped too far to the left, move it right
|
||||
const minLeft = -$(el_window).width() + 150;
|
||||
if ( $(el_window).position().left < minLeft && !window_will_snap ) {
|
||||
if ( $(el_window).position().left < minLeft ) {
|
||||
$(el_window).animate({
|
||||
left: minLeft,
|
||||
}, 100);
|
||||
@@ -2146,10 +1870,10 @@ async function UIWindow (options) {
|
||||
}
|
||||
|
||||
// when resizing the top of the window, make sure the window head is not hidden behind the toolbar
|
||||
if ( $(el_window).position().top < window.toolbar_height ) {
|
||||
var difference = window.toolbar_height - $(el_window).position().top;
|
||||
if ( $(el_window).position().top < 0 ) {
|
||||
var difference = -$(el_window).position().top;
|
||||
$(el_window).css({
|
||||
'top': window.toolbar_height,
|
||||
'top': 0,
|
||||
'height': ui.size.height - difference, // Reduce the height by the difference
|
||||
});
|
||||
// don't resize
|
||||
@@ -2216,10 +1940,9 @@ async function UIWindow (options) {
|
||||
return;
|
||||
}
|
||||
|
||||
const snap_dims = getSnapDimensions();
|
||||
const head_height = options.has_head ? $(el_window_head).outerHeight() : 0;
|
||||
const max_body_width = snap_dims.available_width;
|
||||
const max_body_height = Math.max(0, snap_dims.available_height - head_height);
|
||||
const max_body_width = window.innerWidth;
|
||||
const max_body_height = Math.max(0, window.innerHeight - head_height);
|
||||
|
||||
if ( max_body_width <= 0 || max_body_height <= 0 ) {
|
||||
return;
|
||||
@@ -2238,8 +1961,8 @@ async function UIWindow (options) {
|
||||
|
||||
const window_width = Math.max(1, Math.floor(body_width));
|
||||
const window_height = Math.max(1, Math.floor(body_height + head_height));
|
||||
const left = snap_dims.start_x + Math.max(0, (snap_dims.available_width - window_width) / 2);
|
||||
const top = snap_dims.start_y + Math.max(0, (snap_dims.available_height - window_height) / 2);
|
||||
const left = Math.max(0, (window.innerWidth - window_width) / 2);
|
||||
const top = Math.max(0, (window.innerHeight - window_height) / 2);
|
||||
|
||||
$(el_window).css({
|
||||
width: `${window_width}px`,
|
||||
@@ -2268,7 +1991,6 @@ async function UIWindow (options) {
|
||||
'data-is_maximized': '0',
|
||||
});
|
||||
$(el_window_head_scale_btn).find('img').attr('src', window.icons['scale.svg']);
|
||||
window_is_snapped = false;
|
||||
};
|
||||
// --------------------------------------------------------
|
||||
// Head Context Menu
|
||||
@@ -2544,20 +2266,6 @@ async function UIWindow (options) {
|
||||
// -------------------------------------------
|
||||
menu_items.push('-');
|
||||
// -------------------------------------------
|
||||
// Publish As Website
|
||||
// -------------------------------------------
|
||||
menu_items.push({
|
||||
html: i18n('publish_as_website'),
|
||||
disabled: !options.is_dir,
|
||||
onClick: async function () {
|
||||
await publish_as_website({
|
||||
uid: $(el_window).attr('data-uid'),
|
||||
name: $(el_window).attr('data-name'),
|
||||
path: $(el_window).attr('data-path'),
|
||||
});
|
||||
},
|
||||
});
|
||||
// -------------------------------------------
|
||||
// Deploy as App
|
||||
// -------------------------------------------
|
||||
menu_items.push({
|
||||
@@ -2592,7 +2300,7 @@ async function UIWindow (options) {
|
||||
left = left > (window.innerWidth - window_width) ? (window.innerWidth - window_width) : left;
|
||||
|
||||
let top = window.mouseY;
|
||||
top = top > (window.innerHeight - (window_height + window.toolbar_height)) ? (window.innerHeight - (window_height + window.toolbar_height)) : top;
|
||||
top = top > (window.innerHeight - window_height) ? (window.innerHeight - window_height) : top;
|
||||
|
||||
UIWindowItemProperties(
|
||||
options.title,
|
||||
@@ -2894,10 +2602,10 @@ $(document).on('dblclick', '.window .ui-resizable-handle', function (e) {
|
||||
|
||||
// top
|
||||
else if ( $(this).hasClass('ui-resizable-n') ) {
|
||||
let height = $(el_window).height() + $(el_window).position().top - window.toolbar_height;
|
||||
let height = $(el_window).height() + $(el_window).position().top;
|
||||
$(el_window).css({
|
||||
height: height,
|
||||
top: window.toolbar_height,
|
||||
top: 0,
|
||||
});
|
||||
}
|
||||
// right
|
||||
@@ -2937,21 +2645,21 @@ $(document).on('dblclick', '.window .ui-resizable-handle', function (e) {
|
||||
// top right
|
||||
else if ( $(this).hasClass('ui-resizable-ne') ) {
|
||||
let width = window.innerWidth - $(el_window).position().left;
|
||||
let height = $(el_window).height() + $(el_window).position().top - window.toolbar_height;
|
||||
let height = $(el_window).height() + $(el_window).position().top;
|
||||
$(el_window).css({
|
||||
width: width,
|
||||
height: height,
|
||||
top: window.toolbar_height,
|
||||
top: 0,
|
||||
});
|
||||
}
|
||||
// top left
|
||||
else if ( $(this).hasClass('ui-resizable-nw') ) {
|
||||
let width = $(el_window).width() + $(el_window).position().left;
|
||||
let height = $(el_window).height() + $(el_window).position().top - window.toolbar_height;
|
||||
let height = $(el_window).height() + $(el_window).position().top;
|
||||
$(el_window).css({
|
||||
width: width,
|
||||
height: height,
|
||||
top: window.toolbar_height,
|
||||
top: 0,
|
||||
left: 0,
|
||||
});
|
||||
}
|
||||
@@ -3666,9 +3374,6 @@ $.fn.close = async function (options) {
|
||||
// remove backdrop
|
||||
$(this).closest('.window-backdrop').remove();
|
||||
|
||||
// remove global menubars
|
||||
$(`.window-menubar-global[data-window-id="${win_id}"]`).remove();
|
||||
|
||||
// remove DOM element
|
||||
if ( options?.shrink_to_target ) {
|
||||
// get target location
|
||||
@@ -3707,9 +3412,7 @@ $.fn.close = async function (options) {
|
||||
document.activeElement.blur();
|
||||
$('input').blur();
|
||||
}
|
||||
// focus back to desktop
|
||||
$('.desktop').find('.item-blurred').removeClass('item-blurred');
|
||||
window.active_item_container = $('.desktop.item-container').get(0);
|
||||
window.active_item_container = null;
|
||||
}
|
||||
});
|
||||
|
||||
@@ -3990,12 +3693,6 @@ $.fn.showWindow = async function (options) {
|
||||
};
|
||||
|
||||
window.toggle_empty_folder_message = function (el_item_container) {
|
||||
// if the item container is the desktop, don't show/hide the empty message
|
||||
if ( $(el_item_container).hasClass('desktop') )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// if the item container is empty, show the empty message
|
||||
if ( $(el_item_container).has('.item').length === 0 ) {
|
||||
$(el_item_container).find('.explorer-empty-message').show();
|
||||
@@ -4061,11 +3758,6 @@ $.fn.focusWindow = function (event) {
|
||||
});
|
||||
}
|
||||
|
||||
// hide other global menubars
|
||||
$('.window-menubar-global').not(`.window-menubar-global[data-window-id="${win_id}"]`).hide();
|
||||
// show this window's global menubar
|
||||
$(`.window-menubar-global[data-window-id="${win_id}"]`).show();
|
||||
|
||||
// if a menubar or any of its items are clicked, don't focus the iframe. This is important to preserve the focus on the menubar
|
||||
// and to enable keyboard navigation through the menubar items
|
||||
if ( $(event?.target).hasClass('window-menubar') || $(event?.target).closest('.window-menubar').length > 0 ) {
|
||||
@@ -4096,8 +3788,8 @@ $.fn.focusWindow = function (event) {
|
||||
// remove blurred class from items on this window
|
||||
$(window.active_item_container).find('.item-blurred').removeClass('item-blurred');
|
||||
// Update the tab title to the focused window. The URL itself is
|
||||
// deliberately NOT touched here: on the desktop it stays /desktop
|
||||
// (apps don't rewrite it), and in dashboard mode the open app owns
|
||||
// deliberately NOT touched here: on the desktop apps don't rewrite
|
||||
// it, and in dashboard mode the open app owns
|
||||
// it through real history entries (push_dashboard_app_url).
|
||||
if ( ! window.is_dashboard_mode ) {
|
||||
const update_window_url = $(this).attr('data-update_window_url');
|
||||
@@ -4107,7 +3799,6 @@ $.fn.focusWindow = function (event) {
|
||||
}
|
||||
} else {
|
||||
$('.window').find('.item-selected').addClass('item-blurred');
|
||||
$('.desktop').find('.item-blurred').removeClass('item-blurred');
|
||||
}
|
||||
|
||||
return this;
|
||||
@@ -5391,29 +5082,20 @@ async function saveSidebarOrder (order) {
|
||||
window.update_maximized_window = function (el_window) {
|
||||
if ( window.is_fullpage_mode ) {
|
||||
$(el_window).css({
|
||||
'top': `${window.toolbar_height }px`,
|
||||
'top': 0,
|
||||
'left': '0',
|
||||
'width': '100%',
|
||||
'height': `calc(100% - ${window.toolbar_height}px)`,
|
||||
'height': '100%',
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
$(el_window).css({
|
||||
'top': `${window.toolbar_height }px`,
|
||||
'top': 0,
|
||||
'left': '0',
|
||||
'width': '100%',
|
||||
'height': `${window.innerHeight - window.toolbar_height - 6 }px`,
|
||||
'height': `${window.innerHeight - 6 }px`,
|
||||
});
|
||||
};
|
||||
|
||||
function getSnapDimensions () {
|
||||
return {
|
||||
available_width: window.innerWidth,
|
||||
available_height: window.innerHeight - window.toolbar_height,
|
||||
start_x: 0,
|
||||
start_y: window.toolbar_height,
|
||||
};
|
||||
}
|
||||
|
||||
export default UIWindow;
|
||||
@@ -1,136 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2024-present Puter Technologies Inc.
|
||||
*
|
||||
* This file is part of Puter.
|
||||
*
|
||||
* Puter is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published
|
||||
* by the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import UIWindow from './UIWindow.js';
|
||||
import { underPath } from '../helpers/pathElements.js';
|
||||
|
||||
async function UIWindowPublishWebsite (target_dir_uid, target_dir_name, target_dir_path) {
|
||||
let h = '';
|
||||
h += '<div class="window-publishWebsite-content" style="padding: 20px; border-bottom: 1px solid #ced7e1;">';
|
||||
// success
|
||||
h += '<div class="window-publishWebsite-success">';
|
||||
h += `<img src="${html_encode(window.icons['c-check.svg'])}" style="width:80px; height:80px; display: block; margin:10px auto;">`;
|
||||
h += `<p style="text-align:center;">${i18n('dir_published_as_website', `<strong>${html_encode(target_dir_name)}</strong>`, false)}<p>`;
|
||||
h += `<p style="text-align:center;"><a class="publishWebsite-published-link" target="_blank"></a><img class="publishWebsite-published-link-icon" src="${html_encode(window.icons['launch.svg'])}"></p>`;
|
||||
h += `<button class="button button-normal button-block button-primary publish-window-ok-btn" style="margin-top:20px;">${i18n('ok')}</button>`;
|
||||
h += '</div>';
|
||||
// form
|
||||
h += '<form class="window-publishWebsite-form">';
|
||||
// error msg
|
||||
h += '<div class="publish-website-error-msg"></div>';
|
||||
|
||||
// Subdomain input
|
||||
h += '<div class="puter-subdomain-section" style="overflow: hidden; margin-bottom: 20px;">';
|
||||
h += `<label style="margin-bottom: 10px; display: block;">${i18n('pick_name_for_website')}</label>`;
|
||||
h += '<div style="font-family: monospace; display: flex; align-items: center; background: #f8f9fa; padding: 8px; border-radius: 6px; border: 1px solid #dee2e6;">';
|
||||
h += `<span style="color: #666;">${html_encode(window.extractProtocol(window.url))}://</span>`;
|
||||
h += '<input class="publish-website-subdomain" style="border: none; background: #ffffff; outline: none; padding: 7px !important; " type="text" autocomplete="subdomain" spellcheck="false" autocorrect="off" autocapitalize="off" data-gramm_editor="false"/>';
|
||||
h += `<span style="color: #666;">.${html_encode(window.hosting_domain)}</span>`;
|
||||
h += '</div>';
|
||||
h += '</div>';
|
||||
|
||||
// uid
|
||||
h += `<input class="publishWebsiteTargetDirUID" type="hidden" value="${html_encode(target_dir_uid)}"/>`;
|
||||
// Publish
|
||||
h += `<button class="publish-btn button button-action button-block button-normal">${i18n('publish')}</button>`;
|
||||
h += '</form>';
|
||||
h += '</div>';
|
||||
|
||||
const el_window = await UIWindow({
|
||||
title: i18n('window_title_publish_website'),
|
||||
icon: null,
|
||||
uid: null,
|
||||
is_dir: false,
|
||||
body_content: h,
|
||||
has_head: true,
|
||||
selectable_body: false,
|
||||
draggable_body: false,
|
||||
allow_context_menu: false,
|
||||
is_resizable: false,
|
||||
is_droppable: false,
|
||||
init_center: true,
|
||||
allow_native_ctxmenu: true,
|
||||
allow_user_select: true,
|
||||
width: 450,
|
||||
dominant: true,
|
||||
onAppend: function (this_window) {
|
||||
$(this_window).find('.publish-website-subdomain').val(window.generate_identifier());
|
||||
$(this_window).find('.publish-website-subdomain').get(0).focus({ preventScroll: true });
|
||||
},
|
||||
window_class: 'window-publishWebsite',
|
||||
window_css: {
|
||||
height: 'initial',
|
||||
},
|
||||
body_css: {
|
||||
width: 'initial',
|
||||
height: '100%',
|
||||
'background-color': 'rgb(245 247 249)',
|
||||
'backdrop-filter': 'blur(3px)',
|
||||
},
|
||||
});
|
||||
|
||||
$(el_window).find('.publish-btn').on('click', async function (e) {
|
||||
e.preventDefault();
|
||||
|
||||
// disable 'Publish' button
|
||||
$(el_window).find('.publish-btn').prop('disabled', true);
|
||||
|
||||
try {
|
||||
let subdomain = $(el_window).find('.publish-website-subdomain').val();
|
||||
|
||||
if ( ! subdomain.trim() ) {
|
||||
throw new Error('Please enter a subdomain name');
|
||||
}
|
||||
|
||||
const res = await puter.hosting.create(subdomain, target_dir_path);
|
||||
let url = `https://${ subdomain }.${ window.hosting_domain }/`;
|
||||
|
||||
// Show success
|
||||
$(el_window).find('.window-publishWebsite-form').hide(100, function () {
|
||||
$(el_window).find('.publishWebsite-published-link').attr('href', url);
|
||||
$(el_window).find('.publishWebsite-published-link').text(url);
|
||||
$(el_window).find('.window-publishWebsite-success').show(100);
|
||||
$(`.item[data-uid="${target_dir_uid}"] .item-has-website-badge`).show();
|
||||
});
|
||||
|
||||
// find all items whose path starts with target_dir_path
|
||||
underPath('.item', target_dir_path).each(function () {
|
||||
// show the link badge
|
||||
$(this).find('.item-has-website-url-badge').show();
|
||||
// update item's website_url attribute
|
||||
$(this).attr('data-website_url', url + $(this).attr('data-path').substring(target_dir_path.length));
|
||||
});
|
||||
|
||||
window.update_sites_cache();
|
||||
|
||||
} catch ( err ) {
|
||||
const errorMessage = err.message || (err.error && err.error.message) || 'An error occurred while publishing';
|
||||
$(el_window).find('.publish-website-error-msg').html(errorMessage);
|
||||
$(el_window).find('.publish-website-error-msg').fadeIn();
|
||||
// re-enable 'Publish' button
|
||||
$(el_window).find('.publish-btn').prop('disabled', false);
|
||||
}
|
||||
});
|
||||
|
||||
$(el_window).find('.publish-window-ok-btn').on('click', function () {
|
||||
$(el_window).close();
|
||||
});
|
||||
}
|
||||
|
||||
export default UIWindowPublishWebsite;
|
||||
+6
-1010
File diff suppressed because it is too large.
Load diff
+2
-17
@@ -25,12 +25,9 @@ window.window_nav_history_current_position = {};
|
||||
window.dashboard_nav_history = [];
|
||||
window.dashboard_nav_history_current_position = 0;
|
||||
window.progress_tracker = [];
|
||||
window.upload_item_global_id = 0;
|
||||
window.app_instance_ids = new Set();
|
||||
|
||||
window.menubars = [];
|
||||
window.download_progress = [];
|
||||
window.download_item_global_id = 0;
|
||||
|
||||
// This is the minimum width of the window for the sidebar to be shown
|
||||
window.window_width_threshold_for_sidebar = 500;
|
||||
@@ -113,7 +110,6 @@ if ( window.user_preferences === null ) {
|
||||
}
|
||||
|
||||
window.window_stack = [];
|
||||
window.toolbar_height = 0;
|
||||
window.upload_progress_hide_delay = 500;
|
||||
window.active_uploads = {};
|
||||
window.copy_progress_hide_delay = 1000;
|
||||
@@ -128,7 +124,6 @@ window.window_counter = 0;
|
||||
window.keypress_item_seach_term = '';
|
||||
window.keypress_item_seach_buffer_timeout = undefined;
|
||||
window.first_visit_animation = false;
|
||||
window.show_twitter_link = true;
|
||||
window.animate_window_opening = true;
|
||||
window.animate_window_closing = true;
|
||||
window.desktop_loading_fade_delay = (window.first_visit_ever && window.first_visit_animation ? 6000 : 1000);
|
||||
@@ -151,9 +146,6 @@ window.launch_apps = [];
|
||||
window.launch_apps.recent = [];
|
||||
window.launch_apps.recommended = [];
|
||||
|
||||
// Map of { child_instance_id -> { parent_instance_id, launch_msg_id } }
|
||||
window.child_launch_callbacks = {};
|
||||
|
||||
// Is puter being loaded inside an iframe?
|
||||
if ( window.location !== window.parent.location ) {
|
||||
window.is_embedded = true;
|
||||
@@ -162,7 +154,7 @@ if ( window.location !== window.parent.location ) {
|
||||
}
|
||||
|
||||
// calculate desktop height and width
|
||||
window.desktop_height = window.innerHeight - window.toolbar_height;
|
||||
window.desktop_height = window.innerHeight;
|
||||
window.desktop_width = window.innerWidth;
|
||||
|
||||
// {id: {left: 0, top: 0}}
|
||||
@@ -176,7 +168,7 @@ $(window).on( 'resize', function () {
|
||||
if ( window.a_window_is_resizing ) return;
|
||||
if ( window.a_window_sidebar_is_resizing ) return;
|
||||
|
||||
const new_desktop_height = window.innerHeight - window.toolbar_height;
|
||||
const new_desktop_height = window.innerHeight;
|
||||
const new_desktop_width = window.innerWidth;
|
||||
|
||||
window.desktop_height = new_desktop_height;
|
||||
@@ -196,10 +188,6 @@ window.active_element = null;
|
||||
// The number of recent apps to show in the launch menu
|
||||
window.launch_recent_apps_count = 10;
|
||||
|
||||
// indicated if the mouse is in one of the window snap zones or not
|
||||
// if yes, which one?
|
||||
window.current_active_snap_zone = undefined;
|
||||
|
||||
//
|
||||
window.is_fullpage_mode = false;
|
||||
|
||||
@@ -216,9 +204,6 @@ window.feature_flags = {
|
||||
download_directory: true,
|
||||
};
|
||||
|
||||
window.is_auto_arrange_enabled = true;
|
||||
window.desktop_item_positions = {};
|
||||
window.reset_item_positions = true; // The variable decides if the item positions should be reset when the user enabled auto arrange
|
||||
|
||||
window.file_templates = [];
|
||||
|
||||
|
||||
@@ -2819,10 +2819,6 @@ window.extractSubdomain = function (url) {
|
||||
return subdomain;
|
||||
};
|
||||
|
||||
window.extractProtocol = function (url) {
|
||||
var protocol = url.split('://')[0];
|
||||
return protocol;
|
||||
};
|
||||
window.sleep = function (ms) {
|
||||
return new Promise(resolve => setTimeout(resolve, ms));
|
||||
};
|
||||
@@ -3420,57 +3416,6 @@ window.undo_delete = async (items) => {
|
||||
}
|
||||
};
|
||||
|
||||
window.store_auto_arrange_preference = (preference) => {
|
||||
// localStorage still carries it for this device either way.
|
||||
puter.kv.set('user_preferences.auto_arrange_desktop', preference)
|
||||
.catch(err => console.warn('Could not save auto_arrange_desktop:', err));
|
||||
localStorage.setItem('auto_arrange', preference);
|
||||
};
|
||||
|
||||
window.get_auto_arrange_data = async () => {
|
||||
// Best-effort, like every other preference read: falling back to the
|
||||
// default keeps the desktop arranging itself rather than not appearing.
|
||||
const preferenceValue = await puter.kv.get('user_preferences.auto_arrange_desktop').catch(() => null);
|
||||
window.is_auto_arrange_enabled = preferenceValue === null ? true : preferenceValue;
|
||||
const positions = await puter.kv.get('desktop_item_positions').catch(() => null);
|
||||
window.desktop_item_positions = (!positions || typeof positions !== 'object' || Array.isArray(positions)) ? {} : positions;
|
||||
};
|
||||
|
||||
window.clear_desktop_item_positions = async (el_desktop) => {
|
||||
$(el_desktop).find('.item').each(function () {
|
||||
const el_item = $(this)[0];
|
||||
$(el_item).css('position', '');
|
||||
$(el_item).css('left', '');
|
||||
$(el_item).css('top', '');
|
||||
});
|
||||
if ( window.reset_item_positions ) {
|
||||
window.delete_desktop_item_positions();
|
||||
}
|
||||
};
|
||||
|
||||
window.set_desktop_item_positions = async (el_desktop) => {
|
||||
$(el_desktop).find('.item').each(async function () {
|
||||
const position = window.desktop_item_positions[$(this).attr('data-uid')];
|
||||
const el_item = $(this)[0];
|
||||
if ( position ) {
|
||||
$(el_item).css('position', 'absolute');
|
||||
$(el_item).css('left', `${position.left }px`);
|
||||
$(el_item).css('top', `${position.top }px`);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
window.save_desktop_item_positions = () => {
|
||||
puter.kv.set('desktop_item_positions', window.desktop_item_positions)
|
||||
.catch(err => console.warn('Could not save desktop_item_positions:', err));
|
||||
};
|
||||
|
||||
window.delete_desktop_item_positions = () => {
|
||||
window.desktop_item_positions = {};
|
||||
puter.kv.del('desktop_item_positions')
|
||||
.catch(err => console.warn('Could not clear desktop_item_positions:', err));
|
||||
};
|
||||
|
||||
// Finds the `.window` element for the given app instance ID
|
||||
window.window_for_app_instance = (instance_id) => {
|
||||
return $(`.window[data-element_uuid="${instance_id}"]`).get(0);
|
||||
@@ -3526,22 +3471,6 @@ window.set_menu_item_prop = (items, item_id, prop, val) => {
|
||||
}
|
||||
};
|
||||
|
||||
window.countSubstr = (str, substring) => {
|
||||
if ( substring.length === 0 ) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
let count = 0;
|
||||
let pos = str.indexOf(substring);
|
||||
|
||||
while ( pos !== -1 ) {
|
||||
count++;
|
||||
pos = str.indexOf(substring, pos + 1);
|
||||
}
|
||||
|
||||
return count;
|
||||
};
|
||||
|
||||
// Updates the signed-in user's profile; `username` is kept for callers that
|
||||
// still pass it.
|
||||
window.update_profile = function (username, key_vals) {
|
||||
@@ -3556,44 +3485,11 @@ window.update_profile = function (username, key_vals) {
|
||||
});
|
||||
};
|
||||
|
||||
window.blob2str = (blob) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
const reader = new FileReader();
|
||||
reader.onload = () => resolve(reader.result);
|
||||
reader.onerror = reject;
|
||||
reader.readAsText(blob);
|
||||
});
|
||||
};
|
||||
|
||||
// Another user's picture is only available while they are on a paid plan.
|
||||
window.get_profile_picture = async function (username) {
|
||||
return (await puter.auth.getProfilePicture(username)) ?? undefined;
|
||||
};
|
||||
|
||||
window.format_with_units = (num, { mulUnits, divUnits, precision = 3 }) => {
|
||||
if ( num === 0 ) return '0';
|
||||
|
||||
mulUnits = mulUnits ?? ['', 'K', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y'];
|
||||
divUnits = divUnits ?? ['m', 'µ', 'n', 'p', 'f', 'a', 'z', 'y'];
|
||||
|
||||
const abs = Math.abs(num);
|
||||
let exp = Math.floor(Math.log10(abs) / 3);
|
||||
let symbol = '';
|
||||
|
||||
symbol = exp >= 0
|
||||
? mulUnits[exp]
|
||||
: divUnits[-exp - 1] ;
|
||||
|
||||
if ( ! symbol ) {
|
||||
symbol = `e${exp * 3}`;
|
||||
}
|
||||
|
||||
const scaled = num / Math.pow(10, exp * 3);
|
||||
const rounded = Number.parseFloat(scaled.toPrecision(precision));
|
||||
|
||||
return `${rounded}${symbol}`;
|
||||
};
|
||||
|
||||
/**
|
||||
* General-purpose number formatting function with support for decimal places,
|
||||
* thousand separators, and various formatting options.
|
||||
|
||||
@@ -57,8 +57,8 @@ describe('authLogoHeader', () => {
|
||||
});
|
||||
|
||||
it('makes the logo a named link when it leads somewhere', () => {
|
||||
const h = authLogoHeader({ logoSrc: LOGO, logoHref: '/desktop' });
|
||||
expect(h).toContain('<a class="auth-logo-link" href="/desktop">');
|
||||
const h = authLogoHeader({ logoSrc: LOGO, logoHref: '/' });
|
||||
expect(h).toContain('<a class="auth-logo-link" href="/">');
|
||||
expect(h).toContain('alt="Puter"');
|
||||
});
|
||||
|
||||
|
||||
@@ -63,11 +63,11 @@ export const get_auth_redirect_url = () => {
|
||||
*/
|
||||
const oidc_return_path = () => {
|
||||
const pathname = window.location.pathname;
|
||||
if ( pathname === '/' || pathname === '/desktop' || pathname === '/dashboard' ) {
|
||||
if ( pathname === '/' || pathname === '/dashboard' ) {
|
||||
return pathname;
|
||||
}
|
||||
// app landing: normalize away a trailing slash to match the backend whitelist
|
||||
if ( /^(\/desktop)?\/app\/[^/]+\/?$/.test(pathname) ) {
|
||||
if ( /^\/app\/[^/]+\/?$/.test(pathname) ) {
|
||||
return pathname.replace(/\/$/, '');
|
||||
}
|
||||
return null;
|
||||
@@ -76,10 +76,9 @@ const oidc_return_path = () => {
|
||||
/**
|
||||
* The `return_to` to send along when starting an OIDC flow, or null if the
|
||||
* current page isn't one the backend will return to. The backend strictly
|
||||
* whitelists these (never a client-supplied URL): `/desktop`, `/dashboard`,
|
||||
* and direct app landings (`/app/<name>`, plus the desktop-booted
|
||||
* `/desktop/app/<name>`), so OIDC login started from an app landing comes back
|
||||
* to the app — and to the same interface it was opened in.
|
||||
* whitelists these (never a client-supplied URL): `/dashboard` and direct app
|
||||
* landings (`/app/<name>`), so OIDC login started from an app landing comes
|
||||
* back to the app.
|
||||
*
|
||||
* A share link (`?shared=`, from an email) is carried along with the path: the
|
||||
* recipient usually has to sign in before they can see what was shared, and an
|
||||
|
||||
@@ -42,7 +42,6 @@ afterEach(() => {
|
||||
|
||||
describe('get_oidc_return_to', () => {
|
||||
it('returns the interface pages the backend whitelists', () => {
|
||||
expect(at('/desktop')).toBe('/desktop');
|
||||
expect(at('/dashboard')).toBe('/dashboard');
|
||||
});
|
||||
|
||||
@@ -51,17 +50,12 @@ describe('get_oidc_return_to', () => {
|
||||
expect(at('/app/editor/')).toBe('/app/editor');
|
||||
});
|
||||
|
||||
it('keeps a desktop app landing on the desktop', () => {
|
||||
expect(at('/desktop/app/editor')).toBe('/desktop/app/editor');
|
||||
expect(at('/desktop/app/editor/')).toBe('/desktop/app/editor');
|
||||
});
|
||||
|
||||
it('carries a share link so the item survives the round trip', () => {
|
||||
expect(at('/', share_search(shared_path('Report.pdf')))).toBe(
|
||||
`/${share_search(shared_path('Report.pdf'))}`,
|
||||
);
|
||||
expect(at('/desktop', share_search(shared_path('Report.pdf')))).toBe(
|
||||
`/desktop${share_search(shared_path('Report.pdf'))}`,
|
||||
expect(at('/dashboard', share_search(shared_path('Report.pdf')))).toBe(
|
||||
`/dashboard${share_search(shared_path('Report.pdf'))}`,
|
||||
);
|
||||
expect(
|
||||
at('/', share_search(shared_path('a.txt'), shared_path('b.txt'))),
|
||||
@@ -83,10 +77,10 @@ describe('get_oidc_return_to', () => {
|
||||
expect(at('/', share_search('/alice/Documents/Report.pdf'))).toBe(null);
|
||||
expect(at('/', '?shared=')).toBe(null);
|
||||
// other parameters are not ours to carry
|
||||
expect(at('/desktop', '?app=editor')).toBe('/desktop');
|
||||
expect(at('/dashboard', '?app=editor')).toBe('/dashboard');
|
||||
expect(
|
||||
at('/desktop', `${share_search(shared_path('a.txt'))}&app=editor`),
|
||||
).toBe(`/desktop${share_search(shared_path('a.txt'))}`);
|
||||
at('/dashboard', `${share_search(shared_path('a.txt'))}&app=editor`),
|
||||
).toBe(`/dashboard${share_search(shared_path('a.txt'))}`);
|
||||
});
|
||||
|
||||
it('returns null for anything the backend would reject', () => {
|
||||
@@ -94,6 +88,8 @@ describe('get_oidc_return_to', () => {
|
||||
expect(at('/settings')).toBe(null);
|
||||
expect(at('/action/login')).toBe(null);
|
||||
expect(at('/app/editor/extra')).toBe(null);
|
||||
expect(at('/desktop')).toBe(null);
|
||||
expect(at('/desktop/app/editor')).toBe(null);
|
||||
expect(at('/desktop/app/editor/extra')).toBe(null);
|
||||
expect(at('/dashboard/app/editor')).toBe(null);
|
||||
});
|
||||
|
||||
@@ -17,30 +17,20 @@
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
const Component = use('util.Component');
|
||||
|
||||
/**
|
||||
* Allows using an HTML string as a component.
|
||||
* Whether a page load boots the dashboard instead of the desktop. The root
|
||||
* path and `/app/<name>` boot the dashboard unless the page is an iframe embed
|
||||
* or a popup, which the desktop still handles; `/dashboard` always does.
|
||||
*
|
||||
* @param {Object} location
|
||||
* @param {string} location.pathname
|
||||
* @param {boolean} location.inIframe
|
||||
* @param {boolean} location.embeddedInPopup
|
||||
* @returns {boolean}
|
||||
*/
|
||||
export default def(class JustHTML extends Component {
|
||||
static ID = 'ui.component.JustHTML';
|
||||
|
||||
static PROPERTIES = { html: { value: '' } };
|
||||
create_template ({ template }) {
|
||||
$(template).html('<span></span>');
|
||||
}
|
||||
on_ready ({ listen }) {
|
||||
listen('html', html => {
|
||||
$(this.dom_).find('span').html(html);
|
||||
});
|
||||
}
|
||||
|
||||
_set_dom_based_on_render_mode ({ property_values }) {
|
||||
if ( property_values.no_shadow ) {
|
||||
this.dom_ = this;
|
||||
return;
|
||||
}
|
||||
|
||||
return super._set_dom_based_on_render_mode();
|
||||
}
|
||||
});
|
||||
export function bootsDashboard ({ pathname, inIframe, embeddedInPopup }) {
|
||||
if ( pathname === '/dashboard' || pathname === '/dashboard/' ) return true;
|
||||
const isAppLanding = /^\/app\/[^/]+\/?$/.test(pathname);
|
||||
if ( pathname !== '/' && !isAppLanding ) return false;
|
||||
return !embeddedInPopup && !inIframe;
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
* Copyright (C) 2024-present Puter Technologies Inc.
|
||||
*
|
||||
* This file is part of Puter.
|
||||
*
|
||||
* Puter is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published
|
||||
* by the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import { describe, it, expect } from 'vitest';
|
||||
import { bootsDashboard } from './bootsDashboard.js';
|
||||
|
||||
const boots = (url, { inIframe = false, embeddedInPopup = false } = {}) => {
|
||||
const { pathname } = new URL(url, 'https://puter.com');
|
||||
return bootsDashboard({ pathname, inIframe, embeddedInPopup });
|
||||
};
|
||||
|
||||
describe('bootsDashboard', () => {
|
||||
it('boots the dashboard at the root, its alias, and app landings', () => {
|
||||
expect(boots('/')).toBe(true);
|
||||
expect(boots('/dashboard')).toBe(true);
|
||||
expect(boots('/dashboard/')).toBe(true);
|
||||
expect(boots('/app/editor')).toBe(true);
|
||||
});
|
||||
|
||||
it('boots the desktop on action pages', () => {
|
||||
expect(boots('/action/sign-in')).toBe(false);
|
||||
});
|
||||
|
||||
it('boots the desktop for flows only the desktop handles', () => {
|
||||
expect(boots('/', { inIframe: true })).toBe(false);
|
||||
expect(boots('/', { embeddedInPopup: true })).toBe(false);
|
||||
});
|
||||
|
||||
it('keeps /dashboard on the dashboard even inside an iframe', () => {
|
||||
expect(boots('/dashboard', { inIframe: true })).toBe(true);
|
||||
});
|
||||
|
||||
it('boots the dashboard whatever the query asks for', () => {
|
||||
expect(boots('/?shared=%2Fann%2Fuid%2Fnotes.txt')).toBe(true);
|
||||
expect(boots('/?download=https%3A%2F%2Fexample.com%2Ffile.zip')).toBe(true);
|
||||
expect(boots('/?app=explorer&path=%2Falice%2FDocuments')).toBe(true);
|
||||
expect(boots('/app/editor?app=explorer')).toBe(true);
|
||||
expect(boots('/app/editor?puter.fullpage=true')).toBe(true);
|
||||
expect(boots('/app/editor?puter.fullpage=false')).toBe(true);
|
||||
expect(boots('/?puter.fullpage=1')).toBe(true);
|
||||
});
|
||||
});
|
||||
@@ -20,7 +20,6 @@
|
||||
import UIAlert from '../UI/UIAlert.js';
|
||||
|
||||
import UIWindowItemProperties from '../UI/UIWindowItemProperties.js';
|
||||
import publish_as_website from './publishAsWebsite.js';
|
||||
import open_item from './openItem.js';
|
||||
import openWithAI from './openWithAI.js';
|
||||
import launch_app from './launchApp.js';
|
||||
@@ -44,7 +43,7 @@ import { is_default_app } from './defaultApp.js';
|
||||
* @param {boolean} options.openWithInNewTab - Open the "Open With" apps in a new browser tab instead of an in-page window (used by Dashboard)
|
||||
* @param {Function} options.onShowProperties - Optional custom properties handler (used by Dashboard); receives {name, path, uid, element}
|
||||
* @param {Function} options.onShare - Opens sharing for the item; Share is left out of the menu without it. Receives {name, path, uid, element}
|
||||
* @param {Function} options.onPublishWebsite - Optional custom publish-as-website handler (used by Dashboard); receives {uid, name, path}
|
||||
* @param {Function} options.onPublishWebsite - Publishes the folder as a website; Publish as Website is left out of the menu without it. Receives {uid, name, path}
|
||||
* @param {Function} options.onPublishWorker - Publishes the file as a worker; Publish as Worker is left out of the menu without it. Receives {uid, name, path}
|
||||
* @param {Function} options.onPasteInto - Optional custom paste handler (used by Dashboard); receives the folder's path
|
||||
* @param {Function} options.onRemovedFromShared - Optional, called once Remove from Shared has dropped the user's own access (used by Dashboard)
|
||||
@@ -135,24 +134,19 @@ const generate_file_context_menu = async function (options) {
|
||||
// -------------------------------------------
|
||||
// Publish As Website
|
||||
// -------------------------------------------
|
||||
if ( !is_trashed && !is_trash && fsentry.is_dir ) {
|
||||
if ( !is_trashed && !is_trash && fsentry.is_dir && options.onPublishWebsite ) {
|
||||
menu_items.push({
|
||||
html: i18n('publish_as_website'),
|
||||
// Publishing serves the folder to anyone, for good, so it takes the
|
||||
// same own-it-or-`manage` right as sharing it does (SubdomainDriver
|
||||
// enforces that). `write` on someone else's folder is not enough.
|
||||
disabled: !fsentry.is_dir || fsentry.has_website || !may_share,
|
||||
onClick: async function () {
|
||||
const target = {
|
||||
onClick: function () {
|
||||
options.onPublishWebsite({
|
||||
uid: fsentry.uid,
|
||||
name: $(el_item).attr('data-name'),
|
||||
path: $(el_item).attr('data-path'),
|
||||
};
|
||||
if ( options.onPublishWebsite ) {
|
||||
options.onPublishWebsite(target);
|
||||
} else {
|
||||
await publish_as_website(target);
|
||||
}
|
||||
});
|
||||
},
|
||||
});
|
||||
}
|
||||
@@ -465,7 +459,7 @@ const generate_file_context_menu = async function (options) {
|
||||
left = left > (window.innerWidth - window_width) ? (window.innerWidth - window_width) : left;
|
||||
|
||||
let top = $(el_item).position().top + $(el_item).height();
|
||||
top = top > (window.innerHeight - (window_height + window.toolbar_height)) ? (window.innerHeight - (window_height + window.toolbar_height)) : top;
|
||||
top = top > (window.innerHeight - window_height) ? (window.innerHeight - window_height) : top;
|
||||
|
||||
UIWindowItemProperties(
|
||||
$(el_item).attr('data-name'),
|
||||
|
||||
@@ -23,7 +23,6 @@ import jQuery from '../lib/jquery-3.6.1/jquery-3.6.1.min.js';
|
||||
|
||||
vi.mock('../UI/UIAlert.js', () => ({ default: vi.fn() }));
|
||||
vi.mock('../UI/UIWindowItemProperties.js', () => ({ default: vi.fn() }));
|
||||
vi.mock('./publishAsWebsite.js', () => ({ default: vi.fn() }));
|
||||
vi.mock('./openItem.js', () => ({ default: vi.fn() }));
|
||||
vi.mock('./openWithAI.js', () => ({ default: vi.fn() }));
|
||||
vi.mock('./launchApp.js', () => ({ default: vi.fn() }));
|
||||
@@ -114,6 +113,37 @@ describe('Share', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('Publish as Website', () => {
|
||||
const publishItem = async (options) => {
|
||||
is_owned_by_me.mockReturnValueOnce(true);
|
||||
can_share.mockResolvedValueOnce(true);
|
||||
const row = document.createElement('div');
|
||||
row.setAttribute('data-path', '/me/Site');
|
||||
row.setAttribute('data-name', 'Site');
|
||||
const items = await generate_file_context_menu({
|
||||
element: row,
|
||||
fsentry: { uid: 'dir-1', name: 'Site', path: '/me/Site', is_dir: true },
|
||||
associated_app_name: 'editor',
|
||||
...options,
|
||||
});
|
||||
return items.find((item) => item !== '-' && item.html === 'publish_as_website');
|
||||
};
|
||||
|
||||
it('hands the folder to onPublishWebsite', async () => {
|
||||
const onPublishWebsite = vi.fn();
|
||||
await (await publishItem({ onPublishWebsite })).onClick();
|
||||
expect(onPublishWebsite).toHaveBeenCalledWith({
|
||||
uid: 'dir-1',
|
||||
name: 'Site',
|
||||
path: '/me/Site',
|
||||
});
|
||||
});
|
||||
|
||||
it('is left out without onPublishWebsite', async () => {
|
||||
expect(await publishItem({})).toBeUndefined();
|
||||
});
|
||||
});
|
||||
|
||||
describe('Publish as Worker', () => {
|
||||
const publishItem = async (options) => {
|
||||
is_owned_by_me.mockReturnValueOnce(true);
|
||||
|
||||
@@ -0,0 +1,105 @@
|
||||
/*
|
||||
* Copyright (C) 2024-present Puter Technologies Inc.
|
||||
*
|
||||
* This file is part of Puter.
|
||||
*
|
||||
* Puter is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published
|
||||
* by the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import { jwtPayload } from './jwtPayload.js';
|
||||
|
||||
/**
|
||||
* A token's claims as key-sorted `[key, value]` pairs in JSON, without `iat`.
|
||||
* Read without checking the signature, so it only says what the token claims.
|
||||
*
|
||||
* @param {unknown} token
|
||||
* @returns {string | null} null when the token isn't a readable JWT
|
||||
*/
|
||||
export const tokenClaimsKey = (token) => {
|
||||
const claims = typeof token === 'string' ? jwtPayload(token) : null;
|
||||
if ( ! claims || Array.isArray(claims) ) return null;
|
||||
return JSON.stringify(Object.keys(claims)
|
||||
.filter(key => key !== 'iat')
|
||||
.sort()
|
||||
.map(key => [key, claims[key]]));
|
||||
};
|
||||
|
||||
/**
|
||||
* Whether two tokens claim exactly the same things apart from when they were
|
||||
* signed. Two GUI tokens that do are for the same session, user and type.
|
||||
*
|
||||
* @param {unknown} a
|
||||
* @param {unknown} b
|
||||
* @returns {boolean}
|
||||
*/
|
||||
export const sameTokenClaims = (a, b) => {
|
||||
const key = tokenClaimsKey(a);
|
||||
return key !== null && key === tokenClaimsKey(b);
|
||||
};
|
||||
|
||||
/**
|
||||
* The digest the shell sends as `guiTokenDigest`: SHA-256 of
|
||||
* {@link tokenClaimsKey}, first 32 hex chars. Must match
|
||||
* `TokenService.claimsDigest` on the server.
|
||||
*
|
||||
* @param {unknown} token
|
||||
* @param {SubtleCrypto | null} [subtle] - null on an insecure origin
|
||||
* @returns {Promise<string | null>} null when the token isn't readable or
|
||||
* there is no SubtleCrypto
|
||||
*/
|
||||
export const tokenClaimsDigest = async (token, subtle = globalThis.crypto?.subtle) => {
|
||||
const key = tokenClaimsKey(token);
|
||||
if ( key === null || ! subtle ) return null;
|
||||
const hash = new Uint8Array(await subtle.digest('SHA-256', new TextEncoder().encode(key)));
|
||||
return Array.from(hash, byte => byte.toString(16).padStart(2, '0')).join('').slice(0, 32);
|
||||
};
|
||||
|
||||
/**
|
||||
* Whether the server rendered this page for this load. A history navigation or
|
||||
* a restored tab can be a cached copy, rendered for a cookie that has changed.
|
||||
*
|
||||
* @param {Performance} [perf]
|
||||
* @returns {boolean}
|
||||
*/
|
||||
export const pageRenderedForThisLoad = (perf = globalThis.performance) => {
|
||||
const nav = perf?.getEntriesByType?.('navigation')?.[0];
|
||||
if ( ! nav ) return false;
|
||||
return (nav.type === 'navigate' || nav.type === 'reload') && nav.transferSize > 0;
|
||||
};
|
||||
|
||||
/**
|
||||
* What boot does about `/get-gui-token`, which hands over a token for the
|
||||
* session cookie:
|
||||
* - `fetch`: ask for it.
|
||||
* - `same-session`: the stored token is already the one it would hand over.
|
||||
* - `no-session`: there is no session cookie, so it would refuse.
|
||||
*
|
||||
* Anything short of a `guiTokenDigest` from this very page load is `fetch`.
|
||||
*
|
||||
* @param {Object} opts
|
||||
* @param {Record<string, unknown> | undefined} opts.params - gui_params
|
||||
* @param {string | null} opts.storedToken
|
||||
* @param {boolean} opts.sameOrigin - whether the page and `/get-gui-token` share an origin
|
||||
* @param {boolean} opts.renderedForThisLoad - {@link pageRenderedForThisLoad}
|
||||
* @param {SubtleCrypto | null} [opts.subtle]
|
||||
* @returns {Promise<'fetch' | 'same-session' | 'no-session'>}
|
||||
*/
|
||||
export const guiTokenBootStep = async ({ params, storedToken, sameOrigin, renderedForThisLoad, subtle }) => {
|
||||
if ( ! params || ! Object.hasOwn(params, 'guiTokenDigest') ) return 'fetch';
|
||||
if ( ! sameOrigin || ! renderedForThisLoad ) return 'fetch';
|
||||
const hint = params.guiTokenDigest;
|
||||
if ( hint === null ) return 'no-session';
|
||||
if ( typeof hint !== 'string' || ! storedToken ) return 'fetch';
|
||||
return await tokenClaimsDigest(storedToken, subtle) === hint ? 'same-session' : 'fetch';
|
||||
};
|
||||
@@ -0,0 +1,134 @@
|
||||
/*
|
||||
* Copyright (C) 2024-present Puter Technologies Inc.
|
||||
*
|
||||
* This file is part of Puter.
|
||||
*
|
||||
* Puter is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published
|
||||
* by the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import { createHash, webcrypto } from 'node:crypto';
|
||||
import { describe, expect, it } from 'vitest';
|
||||
import {
|
||||
guiTokenBootStep,
|
||||
pageRenderedForThisLoad,
|
||||
sameTokenClaims,
|
||||
tokenClaimsDigest,
|
||||
tokenClaimsKey,
|
||||
} from './guiToken.js';
|
||||
|
||||
const jwtWith = (claims) =>
|
||||
`h.${Buffer.from(JSON.stringify(claims)).toString('base64url')}.s`;
|
||||
const CLAIMS = { t: 'gui', v: '2', u: 'c2Vzc2lvbg==', su: 'c2Vzc2lvbg==', uu: 'dXNlcg==', ai: 'dXNlcg==' };
|
||||
const TOKEN = jwtWith({ ...CLAIMS, iat: 1 });
|
||||
const subtle = webcrypto.subtle;
|
||||
|
||||
describe('tokenClaimsKey', () => {
|
||||
it('sorts the claims and leaves out iat', () => {
|
||||
expect(tokenClaimsKey(jwtWith({ b: 1, a: 'x', iat: 5 }))).toBe('[["a","x"],["b",1]]');
|
||||
});
|
||||
|
||||
it('is null for anything that is not a readable JWT', () => {
|
||||
expect(tokenClaimsKey('not-a-token')).toBe(null);
|
||||
expect(tokenClaimsKey(null)).toBe(null);
|
||||
expect(tokenClaimsKey(`h.${Buffer.from('[1]').toString('base64url')}.s`)).toBe(null);
|
||||
});
|
||||
});
|
||||
|
||||
describe('sameTokenClaims', () => {
|
||||
it('is true for two tokens signed at different times for the same session', () => {
|
||||
expect(sameTokenClaims(TOKEN, jwtWith({ ...CLAIMS, iat: 2 }))).toBe(true);
|
||||
});
|
||||
|
||||
it('is false when any other claim differs, is added or is missing', () => {
|
||||
expect(sameTokenClaims(TOKEN, jwtWith({ ...CLAIMS, su: 'b3RoZXI=', iat: 2 }))).toBe(false);
|
||||
expect(sameTokenClaims(TOKEN, jwtWith({ ...CLAIMS, uu: 'b3RoZXI=', iat: 2 }))).toBe(false);
|
||||
expect(sameTokenClaims(TOKEN, jwtWith({ ...CLAIMS, t: 's', iat: 2 }))).toBe(false);
|
||||
expect(sameTokenClaims(TOKEN, jwtWith({ ...CLAIMS, x: true, iat: 2 }))).toBe(false);
|
||||
const { ai, ...withoutAuthId } = CLAIMS;
|
||||
expect(sameTokenClaims(TOKEN, jwtWith({ ...withoutAuthId, iat: 2 }))).toBe(false);
|
||||
});
|
||||
|
||||
it('is false when either token is unreadable', () => {
|
||||
expect(sameTokenClaims('garbage', 'garbage')).toBe(false);
|
||||
expect(sameTokenClaims(TOKEN, null)).toBe(false);
|
||||
expect(sameTokenClaims(null, null)).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe('tokenClaimsDigest', () => {
|
||||
it('is the first 32 hex chars of SHA-256 over the claims key', async () => {
|
||||
const expected = createHash('sha256').update(tokenClaimsKey(TOKEN)).digest('hex').slice(0, 32);
|
||||
expect(await tokenClaimsDigest(TOKEN, subtle)).toBe(expected);
|
||||
expect(await tokenClaimsDigest(jwtWith({ ...CLAIMS, iat: 9 }), subtle)).toBe(expected);
|
||||
});
|
||||
|
||||
it('is null without SubtleCrypto or a readable token', async () => {
|
||||
expect(await tokenClaimsDigest(TOKEN, null)).toBe(null);
|
||||
expect(await tokenClaimsDigest('garbage', subtle)).toBe(null);
|
||||
});
|
||||
});
|
||||
|
||||
describe('pageRenderedForThisLoad', () => {
|
||||
const perfWith = (entry) => ({ getEntriesByType: (type) => (type === 'navigation' && entry ? [entry] : []) });
|
||||
|
||||
it('is true for a navigation or reload the server answered', () => {
|
||||
expect(pageRenderedForThisLoad(perfWith({ type: 'navigate', transferSize: 900 }))).toBe(true);
|
||||
expect(pageRenderedForThisLoad(perfWith({ type: 'reload', transferSize: 300 }))).toBe(true);
|
||||
});
|
||||
|
||||
it('is false for a history navigation, a cached copy, or no timing at all', () => {
|
||||
expect(pageRenderedForThisLoad(perfWith({ type: 'back_forward', transferSize: 900 }))).toBe(false);
|
||||
expect(pageRenderedForThisLoad(perfWith({ type: 'navigate', transferSize: 0 }))).toBe(false);
|
||||
expect(pageRenderedForThisLoad(perfWith({ type: 'navigate' }))).toBe(false);
|
||||
expect(pageRenderedForThisLoad(perfWith(null))).toBe(false);
|
||||
expect(pageRenderedForThisLoad({})).toBe(false);
|
||||
expect(pageRenderedForThisLoad(undefined)).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe('guiTokenBootStep', () => {
|
||||
const step = async (overrides) => guiTokenBootStep({
|
||||
params: { guiTokenDigest: await tokenClaimsDigest(TOKEN, subtle) },
|
||||
storedToken: jwtWith({ ...CLAIMS, iat: 3 }),
|
||||
sameOrigin: true,
|
||||
renderedForThisLoad: true,
|
||||
subtle,
|
||||
...overrides,
|
||||
});
|
||||
|
||||
it('keeps the stored token when the shell names its session', async () => {
|
||||
expect(await step({})).toBe('same-session');
|
||||
});
|
||||
|
||||
it('skips the request when the shell says there is no session cookie', async () => {
|
||||
expect(await step({ params: { guiTokenDigest: null } })).toBe('no-session');
|
||||
expect(await step({ params: { guiTokenDigest: null }, storedToken: null })).toBe('no-session');
|
||||
});
|
||||
|
||||
it('asks when the shell names another session or nothing is stored', async () => {
|
||||
expect(await step({ storedToken: jwtWith({ ...CLAIMS, su: 'b3RoZXI=' }) })).toBe('fetch');
|
||||
expect(await step({ storedToken: null })).toBe('fetch');
|
||||
expect(await step({ params: { guiTokenDigest: 42 } })).toBe('fetch');
|
||||
});
|
||||
|
||||
it('asks whenever the shell\'s word can\'t be taken', async () => {
|
||||
// An older server, or one that couldn't tell.
|
||||
expect(await step({ params: {} })).toBe('fetch');
|
||||
expect(await step({ params: undefined })).toBe('fetch');
|
||||
expect(await step({ sameOrigin: false })).toBe('fetch');
|
||||
expect(await step({ renderedForThisLoad: false })).toBe('fetch');
|
||||
expect(await step({ renderedForThisLoad: false, params: { guiTokenDigest: null } })).toBe('fetch');
|
||||
expect(await step({ subtle: null })).toBe('fetch');
|
||||
});
|
||||
});
|
||||
@@ -106,9 +106,6 @@ const runLaunch = async (options) => {
|
||||
const launchAttributes = {
|
||||
'launch.app': options?.name ?? options?.app_obj?.name ?? 'unknown',
|
||||
'launch.dashboard_mode': !! window.is_dashboard_mode,
|
||||
// url_paths has the `/desktop` prefix stripped, so this counts the
|
||||
// desktop-booted landing (`/desktop/app/<name>`) as the app URL
|
||||
// it is.
|
||||
'launch.from_app_url':
|
||||
window.url_paths?.[0]?.toLocaleLowerCase() === 'app'
|
||||
&& !! window.url_paths?.[1],
|
||||
@@ -625,14 +622,14 @@ const runLaunch = async (options) => {
|
||||
window_height = parseFloat(app_info.metadata.window_size.height);
|
||||
} if ( options.maximized )
|
||||
{
|
||||
window_height = `calc(100% - ${window.toolbar_height + 1}px)`;
|
||||
window_height = 'calc(100% - 1px)';
|
||||
}
|
||||
|
||||
// top
|
||||
let top;
|
||||
if ( app_info.metadata?.window_position?.top !== undefined && app_info.metadata?.window_position?.top !== '' )
|
||||
{
|
||||
top = parseFloat(app_info.metadata.window_position.top) + window.toolbar_height + 1;
|
||||
top = parseFloat(app_info.metadata.window_position.top) + 1;
|
||||
}
|
||||
if ( options.maximized )
|
||||
{
|
||||
|
||||
@@ -323,7 +323,7 @@ Please try recreating the link.`);
|
||||
app: 'explorer',
|
||||
top: options.maximized ? 0 : undefined,
|
||||
left: options.maximized ? 0 : undefined,
|
||||
height: options.maximized ? `calc(100% - ${window.toolbar_height + 1}px)` : undefined,
|
||||
height: options.maximized ? 'calc(100% - 1px)' : undefined,
|
||||
width: options.maximized ? '100%' : undefined,
|
||||
});
|
||||
}
|
||||
|
||||
@@ -84,8 +84,9 @@ export function shared_link_recipient_uuid (params) {
|
||||
* that account's saved session, ask whether to sign in to it, or nothing.
|
||||
*
|
||||
* Popups, embeds (`embedded`) and `action` flows act for whoever opened them,
|
||||
* so a link must not change their account. A temporary session is left to the
|
||||
* share link's own sign-in prompt.
|
||||
* so a link must not change their account. The desktop (`desktop`) doesn't
|
||||
* open share links, so it never acts on the hint. A temporary session is left
|
||||
* to the share link's own sign-in prompt.
|
||||
*
|
||||
* @returns {{ switch_to: object } | { ask: true } | null}
|
||||
*/
|
||||
@@ -93,10 +94,11 @@ export function shared_link_account_step ({
|
||||
params,
|
||||
action,
|
||||
embedded,
|
||||
desktop,
|
||||
current_user,
|
||||
logged_in_users,
|
||||
}) {
|
||||
if ( action || embedded ) return null;
|
||||
if ( action || embedded || desktop ) return null;
|
||||
const uuid = shared_link_recipient_uuid(params);
|
||||
if ( ! uuid || uuid === current_user?.uuid?.toLowerCase() ) return null;
|
||||
const saved = (logged_in_users ?? []).find(user =>
|
||||
|
||||
@@ -127,6 +127,10 @@ describe('shared_link_account_step', () => {
|
||||
expect(step({ action: 'login' })).toBeNull();
|
||||
});
|
||||
|
||||
it('leaves the desktop alone, since it does not open share links', () => {
|
||||
expect(step({ desktop: true })).toBeNull();
|
||||
});
|
||||
|
||||
it('leaves a temporary session to the share link sign-in', () => {
|
||||
const temp = { uuid: CURRENT, is_temp: true };
|
||||
expect(step({ current_user: temp, logged_in_users: [temp] }))
|
||||
|
||||
@@ -1,40 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2024-present Puter Technologies Inc.
|
||||
*
|
||||
* This file is part of Puter.
|
||||
*
|
||||
* Puter is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published
|
||||
* by the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import UIWindowPublishWebsite from '../UI/UIWindowPublishWebsite.js';
|
||||
import ensure_can_publish from './ensureCanPublish.js';
|
||||
|
||||
/**
|
||||
* Opens the "Publish as website" flow for a directory, first walking the user
|
||||
* through account creation and email confirmation when the deployment requires
|
||||
* a verified email to publish. Returns without publishing if the user backs out
|
||||
* of either step.
|
||||
*
|
||||
* @param {Object} dir - The directory to publish
|
||||
* @param {string} dir.uid - UID of the directory
|
||||
* @param {string} dir.name - Display name of the directory
|
||||
* @param {string} dir.path - Full path of the directory
|
||||
* @returns {Promise<void>}
|
||||
*/
|
||||
const publish_as_website = async function ({ uid, name, path }) {
|
||||
if ( ! await ensure_can_publish(window.require_email_verification_to_publish_website) ) return;
|
||||
await UIWindowPublishWebsite(uid, name, path);
|
||||
};
|
||||
|
||||
export default publish_as_website;
|
||||
@@ -246,7 +246,6 @@ const refresh_item_container = function (el_item_container, options) {
|
||||
if ( item_path !== window.trash_path && item_path !== window.appdata_path ) {
|
||||
// if this is trash, get original name from item metadata
|
||||
fsentry.name = metadata.original_name ?? fsentry.name;
|
||||
const position = window.desktop_item_positions[fsentry.uid] ?? undefined;
|
||||
UIItem({
|
||||
appendTo: el_item_container,
|
||||
uid: fsentry.uid,
|
||||
@@ -269,7 +268,6 @@ const refresh_item_container = function (el_item_container, options) {
|
||||
suggested_apps: fsentry.suggested_apps,
|
||||
disabled: is_disabled,
|
||||
visible: visible,
|
||||
position: position,
|
||||
shared_with_me: fsentry.shared_with_me,
|
||||
share_mode: fsentry.share_mode,
|
||||
shared_by: fsentry.shared_by,
|
||||
@@ -281,31 +279,6 @@ const refresh_item_container = function (el_item_container, options) {
|
||||
}
|
||||
}
|
||||
|
||||
// if this is desktop, add Trash
|
||||
if ( $(el_item_container).hasClass('desktop') ) {
|
||||
try {
|
||||
const trash = await puter.fs.stat({ path: window.trash_path, consistency: options.consistency ?? 'eventual' });
|
||||
if ( ! is_current() ) {
|
||||
return;
|
||||
}
|
||||
UIItem({
|
||||
appendTo: el_item_container,
|
||||
uid: trash.id,
|
||||
immutable: trash.immutable,
|
||||
path: window.trash_path,
|
||||
icon: { image: (trash.is_empty ? window.icons['trash.svg'] : window.icons['trash-full.svg']), type: 'icon' },
|
||||
name: trash.name,
|
||||
is_dir: trash.is_dir,
|
||||
sort_by: trash.sort_by,
|
||||
type: trash.type,
|
||||
is_trash: true,
|
||||
sortable: false,
|
||||
});
|
||||
window.sort_items(el_item_container, $(el_item_container).attr('data-sort_by'), $(el_item_container).attr('data-sort_order'));
|
||||
} catch (e) {
|
||||
// Ignored
|
||||
}
|
||||
}
|
||||
// sort items
|
||||
window.sort_items(
|
||||
el_item_container,
|
||||
|
||||
@@ -47,7 +47,6 @@ Object.assign(window, {
|
||||
shared_path: '/alice/Shared',
|
||||
trash_path: '/alice/Trash',
|
||||
user_preferences: {},
|
||||
desktop_item_positions: {},
|
||||
check_fsentry_against_allowed_file_types_string: () => true,
|
||||
sort_items: () => {},
|
||||
update_explorer_footer_item_count: () => {},
|
||||
|
||||
@@ -21,47 +21,6 @@ const update_mouse_position = function (x, y) {
|
||||
window.mouseX = x;
|
||||
window.mouseY = y;
|
||||
|
||||
// mouse in top-left corner of screen
|
||||
if ( (window.mouseX < 150 && window.mouseY < window.toolbar_height + 20) || (window.mouseX < 20 && window.mouseY < 150) )
|
||||
{
|
||||
window.current_active_snap_zone = 'nw';
|
||||
}
|
||||
// mouse in left edge of screen
|
||||
else if ( window.mouseX < 20 && window.mouseY >= 150 && window.mouseY < window.desktop_height - 150 )
|
||||
{
|
||||
window.current_active_snap_zone = 'w';
|
||||
}
|
||||
// mouse in bottom-left corner of screen
|
||||
else if ( window.mouseX < 20 && window.mouseY > window.desktop_height - 150 )
|
||||
{
|
||||
window.current_active_snap_zone = 'sw';
|
||||
}
|
||||
// mouse in right edge of screen
|
||||
else if ( window.mouseX > window.desktop_width - 20 && window.mouseY >= 150 && window.mouseY < window.desktop_height - 150 )
|
||||
{
|
||||
window.current_active_snap_zone = 'e';
|
||||
}
|
||||
// mouse in top-right corner of screen
|
||||
else if ( (window.mouseX > window.desktop_width - 150 && window.mouseY < window.toolbar_height + 20) || (window.mouseX > window.desktop_width - 20 && window.mouseY < 150) )
|
||||
{
|
||||
window.current_active_snap_zone = 'ne';
|
||||
}
|
||||
// mouse in bottom-right corner of screen
|
||||
else if ( window.mouseX > window.desktop_width - 20 && window.mouseY >= window.desktop_height - 150 )
|
||||
{
|
||||
window.current_active_snap_zone = 'se';
|
||||
}
|
||||
// mouse in top edge of screen
|
||||
else if ( window.mouseY < window.toolbar_height + 20 && window.mouseX >= 150 && window.mouseX < window.desktop_width - 150 )
|
||||
{
|
||||
window.current_active_snap_zone = 'n';
|
||||
}
|
||||
// not in any snap zone
|
||||
else
|
||||
{
|
||||
window.current_active_snap_zone = undefined;
|
||||
}
|
||||
|
||||
// mouseover_window
|
||||
var windows = document.getElementsByClassName('window');
|
||||
let active_win;
|
||||
|
||||
@@ -21,22 +21,9 @@
|
||||
* Splits a GUI pathname into the route segments the boot code matches on
|
||||
* (`window.url_paths`), dropping empty segments.
|
||||
*
|
||||
* A leading `desktop` segment is dropped with them: `/desktop` only picks the
|
||||
* interface, and everything after it is the same route it would be at the
|
||||
* root. So `/desktop/app/<name>` yields `['app', '<name>']` — the app landing
|
||||
* every route check downstream already understands — and the only difference
|
||||
* from `/app/<name>` is that the dashboard-mode check (see initgui.js) doesn't
|
||||
* claim the path, leaving the app to open on the desktop.
|
||||
*
|
||||
* @param {string} pathname - the pathname to parse, e.g. `/desktop/app/editor`
|
||||
* @param {string} pathname - the pathname to parse, e.g. `/app/editor`
|
||||
* @returns {string[]} route segments
|
||||
*/
|
||||
export const parse_url_paths = (pathname) => {
|
||||
const paths = String(pathname ?? '')
|
||||
.split('/')
|
||||
.filter((element) => element);
|
||||
if ( paths[0]?.toLocaleLowerCase() === 'desktop' ) {
|
||||
paths.shift();
|
||||
}
|
||||
return paths;
|
||||
};
|
||||
export const parse_url_paths = (pathname) => String(pathname ?? '')
|
||||
.split('/')
|
||||
.filter((element) => element);
|
||||
@@ -28,29 +28,12 @@ describe('parse_url_paths', () => {
|
||||
expect(parse_url_paths('')).toEqual([]);
|
||||
});
|
||||
|
||||
it('drops a leading desktop segment so the rest reads as a root route', () => {
|
||||
it('keeps a leading desktop segment, so /desktop/app/<name> is not an app landing', () => {
|
||||
expect(parse_url_paths('/desktop')).toEqual(['desktop']);
|
||||
expect(parse_url_paths('/desktop/app/editor')).toEqual([
|
||||
'app',
|
||||
'editor',
|
||||
]);
|
||||
expect(parse_url_paths('/DeskTop/app/editor')).toEqual([
|
||||
'app',
|
||||
'editor',
|
||||
]);
|
||||
expect(parse_url_paths('/desktop')).toEqual([]);
|
||||
expect(parse_url_paths('/desktop/')).toEqual([]);
|
||||
});
|
||||
|
||||
it('only drops the prefix, not a later or lookalike segment', () => {
|
||||
expect(parse_url_paths('/app/desktop')).toEqual(['app', 'desktop']);
|
||||
expect(parse_url_paths('/desktops/app/editor')).toEqual([
|
||||
'desktops',
|
||||
'app',
|
||||
'editor',
|
||||
]);
|
||||
expect(parse_url_paths('/desktop/desktop/app')).toEqual([
|
||||
'desktop',
|
||||
'app',
|
||||
'editor',
|
||||
]);
|
||||
});
|
||||
});
|
||||
@@ -31,7 +31,6 @@ const ar = {
|
||||
allow: 'السماح',
|
||||
ascending: 'تصاعدي',
|
||||
associated_websites: 'المواقع المرتبطة',
|
||||
auto_arrange: 'ترتيب تلقائي',
|
||||
cancel: 'إلغاء',
|
||||
change_email: 'تغيير البريد الإلكتروني',
|
||||
change_language: 'تغيير اللغة',
|
||||
@@ -41,20 +40,13 @@ const ar = {
|
||||
close_all_windows_and_log_out: 'إغلاق النوافذ وتسجيل الخروج',
|
||||
change_always_open_with: 'هل تريد دائمًا فتح هذا النوع من الملفات باستخدام',
|
||||
confirm: 'تأكيد',
|
||||
confirm_2fa_setup: 'لقد أضفت الرمز إلى تطبيق المصادقة',
|
||||
confirm_2fa_recovery: 'لقد حفظت رموز الاسترداد في مكان آمن',
|
||||
confirm_account_for_free_referral_storage_c2a:
|
||||
'.أنشئ حسابًا وقم بتأكيد عنوان بريدك الإلكتروني للحصول على 1 جيجابايت من مساحة التخزين المجانية. سيحصل صديقك أيضًا على 1 جيجابايت من مساحة التخزين المجانية',
|
||||
confirm_code_generic_incorrect: 'رمز غير صحيح.',
|
||||
confirm_code_generic_too_many_requests:
|
||||
'.طلبات كثيرة جدًا. يرجى الانتظار بضع دقائق',
|
||||
confirm_code_generic_submit: 'إرسال الرمز',
|
||||
confirm_code_generic_try_again: 'حاول مرة أخرى',
|
||||
confirm_code_generic_title: 'أدخل رمز التأكيد',
|
||||
confirm_code_2fa_instruction:
|
||||
'.أدخل الرمز المكون من 6 أرقام من تطبيق المصادقة الخاص بك',
|
||||
confirm_code_2fa_submit_btn: 'إرسال',
|
||||
confirm_code_2fa_title: 'أدخل رمز المصادقة الثنائية',
|
||||
confirm_delete_multiple_items:
|
||||
'هل أنت متأكد أنك تريد حذف هذه العناصر نهائيًا؟',
|
||||
confirm_delete_single_item: 'هل تريد حذف هذا العنصر نهائيًا؟',
|
||||
@@ -67,8 +59,6 @@ const ar = {
|
||||
confirm_session_revoke: 'هل أنت متأكد أنك تريد إلغاء هذه الجلسة؟',
|
||||
confirm_your_email_address: 'تأكيد عنوان بريدك الإلكتروني',
|
||||
contact_us: 'اتصل بنا',
|
||||
contact_us_verification_required:
|
||||
'.يجب أن يكون لديك عنوان بريد إلكتروني مُؤكد لاستخدام هذه الخدمة',
|
||||
continue: 'استمر',
|
||||
copy: 'نسخ',
|
||||
copy_link: 'نسخ الرابط',
|
||||
@@ -90,17 +80,13 @@ const ar = {
|
||||
deploy_as_app: 'نشر كتطبيق',
|
||||
descending: 'تنازلي',
|
||||
desktop: 'سطح المكتب',
|
||||
desktop_background_fit: 'ملائمة',
|
||||
developers: 'المطورين',
|
||||
dir_published_as_website: ':%strong% تم نشره إلى',
|
||||
disable_2fa: 'تعطيل المصادقة الثنائية',
|
||||
disable_2fa_confirm: 'هل أنت متأكد أنك تريد تعطيل المصادقة الثنائية؟',
|
||||
disable_2fa_instructions: '.أدخل كلمة المرور لتعطيل المصادقة الثنائية',
|
||||
documents: 'المستندات',
|
||||
dont_allow: 'عدم السماح',
|
||||
download: 'تنزيل',
|
||||
download_file: 'تنزيل الملف',
|
||||
downloading: 'جارٍ التنزيل',
|
||||
email: 'البريد الإلكتروني',
|
||||
email_change_confirmation_sent:
|
||||
'.تم إرسال بريد تأكيد إلى عنوان بريدك الإلكتروني الجديد. يرجى التحقق من صندوق الوارد واتباع التعليمات لإكمال العملية',
|
||||
@@ -129,13 +115,10 @@ const ar = {
|
||||
forgot_pass_c2a: 'هل نسيت كلمة المرور؟',
|
||||
from: 'من',
|
||||
general: 'عام',
|
||||
get_a_copy_of_on_puter: "Puter.com! :احصل على نسخة من '%%' على",
|
||||
get_copy_link: 'احصل على رابط النسخ',
|
||||
home: 'الصفحة الرئيسية',
|
||||
html_document: 'HTML مستند',
|
||||
hue: 'درجة اللون',
|
||||
incorrect_password: 'كلمة مرور غير صحيحة',
|
||||
invite_link: 'رابط الدعوة',
|
||||
item: 'عنصر',
|
||||
items_in_trash_cannot_be_renamed:
|
||||
'.لا يمكن إعادة تسمية هذا العنصر لأنه في سلة المهملات. لإعادة تسمية هذا العنصر، اسحبه أولاً خارج سلة المهملات',
|
||||
@@ -147,7 +130,6 @@ const ar = {
|
||||
loading: 'جارٍ التحميل',
|
||||
log_in: 'تسجيل الدخول',
|
||||
log_out: 'تسجيل الخروج',
|
||||
looks_good: '!يبدو جيدًا',
|
||||
manage_sessions: 'إدارة الجلسات',
|
||||
modified: 'تم التعديل',
|
||||
move: 'نقل',
|
||||
@@ -172,7 +154,6 @@ const ar = {
|
||||
open_with: 'فتح باستخدام',
|
||||
original_name: 'الاسم الأصلي',
|
||||
original_path: 'المسار الأصلي',
|
||||
oss_code_and_content: 'برامج ومحتوى مفتوح المصدر',
|
||||
password: 'كلمة المرور',
|
||||
password_changed: '.تم تغيير كلمة المرور',
|
||||
password_recovery_rate_limit:
|
||||
@@ -188,29 +169,20 @@ const ar = {
|
||||
paste: 'لصق',
|
||||
paste_into_folder: 'لصق في المجلد',
|
||||
path: 'المسار',
|
||||
personalization: 'تخصيص',
|
||||
pick_name_for_website: 'اختر اسمًا لموقعك الإلكتروني:',
|
||||
pictures: 'الصور',
|
||||
plural_suffix: 's', //this is not necessary for Arabic
|
||||
powered_by_puter_js: '{{link=docs}}Puter.js{{/link}} مدعوم بواسطة ',
|
||||
preparing: '...جارٍ التحضير',
|
||||
preparing_for_upload: '...جارٍ التحضير للتحميل',
|
||||
print: 'طباعة',
|
||||
privacy: 'الخصوصية',
|
||||
proceed_to_login: 'المتابعة لتسجيل الدخول',
|
||||
proceed_with_account_deletion: 'المتابعة مع حذف الحساب',
|
||||
properties: 'الخصائص',
|
||||
public: 'عام',
|
||||
publish: 'نشر',
|
||||
publish_as_website: 'نشر كموقع إلكتروني',
|
||||
puter_description:
|
||||
'.هو سحابة شخصية تركز على الخصوصية للحفاظ على جميع ملفاتك، تطبيقاتك، وألعابك في مكان آمن واحد، متاحة من أي مكان وفي أي وقت Puter',
|
||||
reading_file: '%strong% جارٍ قراءة',
|
||||
recover_password: 'استعادة كلمة المرور',
|
||||
refer_friends_c2a:
|
||||
'!سيحصل صديقك على 1 جيجابايت أيضًا .Puter احصل على 1 جيجابايت عن كل صديق ينشئ حسابًا ويؤكده على',
|
||||
refer_friends_social_media_c2a:
|
||||
'Puter.com! احصل على 1 جيجابايت من التخزين المجاني على',
|
||||
refresh: 'تحديث',
|
||||
rename: 'إعادة تسمية',
|
||||
replace: 'استبدال',
|
||||
@@ -220,11 +192,9 @@ const ar = {
|
||||
save: 'حفظ',
|
||||
saturation: 'تشبع',
|
||||
save_account: 'حفظ الحساب',
|
||||
save_account_to_get_copy_link: '.يرجى إنشاء حساب للمتابعة',
|
||||
save_account_to_publish: '.يرجى إنشاء حساب للمتابعة',
|
||||
save_session: 'حفظ الجلسة',
|
||||
save_session_c2a: '.أنشئ حسابًا لحفظ جلستك الحالية وتجنب فقدان عملك',
|
||||
scan_qr_2fa: 'امسح رمز الاستجابة السريعة باستخدام تطبيق المصادقة الخاص بك',
|
||||
search: 'بحث',
|
||||
seconds: 'ثوانٍ',
|
||||
security: 'الأمان',
|
||||
@@ -242,13 +212,11 @@ const ar = {
|
||||
show_hidden: 'إظهار المخفي',
|
||||
sign_in_with_puter: 'Puter تسجيل الدخول باستخدام',
|
||||
sign_up: 'تسجيل',
|
||||
signing_in: '…جارٍ تسجيل الدخول',
|
||||
size: 'الحجم',
|
||||
skip: 'تخطي',
|
||||
something_went_wrong: 'حدث خطأ ما.',
|
||||
sort_by: 'فرز حسب',
|
||||
status: 'الحالة',
|
||||
storage_usage: 'استخدام التخزين',
|
||||
storage_puter_used: 'Puter مستخدم بواسطة',
|
||||
taking_longer_than_usual: '…يستغرق وقتًا أطول من المعتاد. يرجى الانتظار',
|
||||
terms: 'الشروط',
|
||||
@@ -277,25 +245,18 @@ const ar = {
|
||||
videos: 'مقاطع الفيديو',
|
||||
visibility: 'الرؤية',
|
||||
yes: 'نعم',
|
||||
you_have_been_referred_to_puter_by_a_friend:
|
||||
'!بواسطة صديق Puter تم إحالتك إلى',
|
||||
zip: 'ضغط',
|
||||
zipping_file: '%strong% جارٍ ضغط',
|
||||
|
||||
// === 2FA Setup ===
|
||||
setup2fa_1_step_heading: 'افتح تطبيق المصادقة الخاص بك',
|
||||
setup2fa_1_instructions: '.هو خيار موثوق به لنظام Android و iOS ولكن إذا كنت غير متأكد،<a target="_blank" href="https://authy.com/download">Authy</a> :هناك العديد للاختيار من بينها .(TOTP) يمكنك استخدام أي تطبيق مصادقة يدعم بروتوكول كلمة المرور لمرة واحدة المعتمدة على الوقت ',
|
||||
setup2fa_2_step_heading: ' (QR code)مسح رمز الاستجابة السريعة',
|
||||
setup2fa_3_step_heading: 'أدخل الرمز المكون من 6 أرقام',
|
||||
setup2fa_4_step_heading: 'انسخ رموز الاسترداد الخاصة بك',
|
||||
setup2fa_4_instructions: `
|
||||
.هذه رموز الاسترداد هي الطريقة الوحيدة للوصول إلى حسابك إذا فقدت هاتفك أو لم تتمكن من استخدام تطبيق المصادقة الخاص بك
|
||||
.تأكد من حفظها في مكان آمن
|
||||
`,
|
||||
setup2fa_5_step_heading: '(2FA) تأكيد إعداد المصادقة الثنائية',
|
||||
setup2fa_5_confirmation_1: 'لقد قمت بحفظ رموز الاسترداد في مكان آمن',
|
||||
setup2fa_5_confirmation_2: '(2FA) أنا جاهز لتمكين المصادقة الثنائية',
|
||||
setup2fa_5_button: ' (2FA) تمكين المصادقة الثنائية',
|
||||
|
||||
// === 2FA Login ===
|
||||
login2fa_otp_title: '(2FA) أدخل رمز المصادقة الثنائية',
|
||||
@@ -305,7 +266,6 @@ const ar = {
|
||||
login2fa_recovery_instructions:
|
||||
'.أدخل أحد رموز الاسترداد الخاصة بك للوصول إلى حسابك',
|
||||
login2fa_use_recovery_code: 'استخدام رمز الاسترداد',
|
||||
login2fa_recovery_back: 'الرجوع',
|
||||
login2fa_recovery_placeholder: 'XXXXXXXX',
|
||||
|
||||
change: 'تغيير', // In English: "Change"
|
||||
@@ -378,21 +338,13 @@ const ar = {
|
||||
'billing.enjoy_msg':
|
||||
'.بالإضافة إلى مزايا أخرى Cloud Storage استمتع بـ %% من', // In English: "Enjoy %% of Cloud Storage plus other benefits."
|
||||
|
||||
choose_publishing_option:
|
||||
'اختر الطريقة التي تريد نشر موقع الويب الخاص بك بها', // In English: "Choose how you want to publish your website:"
|
||||
create_desktop_shortcut: 'إنشاء اختصار (سطح المكتب)', // In English: "Create Shortcut (Desktop)"
|
||||
create_desktop_shortcut_s: 'إنشاء اختصارات (سطح المكتب)', // In English: "Create Shortcuts (Desktop)"
|
||||
create_shortcut_s: 'إنشاء اختصارات', // In English: "Create Shortcuts"
|
||||
minimize: 'تصغير', // In English: "Minimize"
|
||||
reload_app: 'إعادة تحميل التطبيق', // In English: "Reload App"
|
||||
publish_as_serverless_worker: 'النشر كعامل', // In English: "Publish as Worker"
|
||||
'toolbar.enter_fullscreen': 'وضع ملء الشاشة', // In English: "Enter Full Screen"
|
||||
'toolbar.github': 'GitHub', // In English: "GitHub"
|
||||
'toolbar.refer': 'إحالة', // In English: "Refer"
|
||||
used_of: '{{available}}محاولات مستخدمة من {{used}}', // In English: "{{used}} used of {{available}}"
|
||||
worker: 'العامل', // In English: "Worker"
|
||||
'billing.offering.basic': 'أساسي', // In English: "Basic"
|
||||
too_many_attempts: '.محاولات كثيرة. يُرجى المحاولة لاحقًا', // In English: "Too many attempts. Please try again later."
|
||||
server_timeout:
|
||||
'.استغرق الخادم وقتًا طويلاً للاستجابة. يُرجى المحاولة مرة أخرى', // In English: "The server took too long to respond. Please try again."
|
||||
signup_error: '.حدث خطأ أثناء التسجيل. يُرجى المحاولة مرة أخرى', // In English: "An error occurred during signup. Please try again."
|
||||
@@ -411,15 +363,10 @@ const ar = {
|
||||
window_title_open: 'فتح',
|
||||
window_title_change_password: 'تغيير كلمة المرور',
|
||||
window_title_select_font: '…اختر الخط',
|
||||
window_title_session_list: '!قائمة الجلسات',
|
||||
window_title_set_new_password: 'تعيين كلمة مرور جديدة',
|
||||
window_title_publish_website: 'نشر الموقع',
|
||||
window_title_publish_worker: 'نشر العامل',
|
||||
window_title_authenticating: '…جارٍ التحقق',
|
||||
window_title_refer_friend: '!أوصِ صديقًا',
|
||||
desktop_exit_full_screen: 'الخروج من وضع ملء الشاشة',
|
||||
desktop_enter_full_screen: 'وضع ملء الشاشة',
|
||||
item_shared_with_you: '.قام مستخدم بمشاركة هذا العنصر معك',
|
||||
item_shared_by_you: '.لقد قمت بمشاركة هذا العنصر مع مستخدم آخر على الأقل',
|
||||
item_shortcut: 'اختصار',
|
||||
item_associated_websites: 'الموقع المرتبط',
|
||||
@@ -428,9 +375,6 @@ const ar = {
|
||||
window_click_to_go_back: 'انقر للرجوع.',
|
||||
window_click_to_go_forward: 'انقر للتقدم.',
|
||||
window_click_to_go_up: '.انقر للصعود مجلد واحد',
|
||||
window_title_public: 'عام',
|
||||
window_title_videos: 'فيديوهات',
|
||||
window_title_pictures: 'صور',
|
||||
window_title_puter: 'بيوتر',
|
||||
window_folder_empty: 'هذا المجلد فارغ',
|
||||
},
|
||||
|
||||
@@ -31,7 +31,6 @@ const bg = {
|
||||
allow: 'Разреши',
|
||||
ascending: 'Възходящ',
|
||||
associated_websites: 'Свързани уебсайтове',
|
||||
auto_arrange: 'Автоматично подреждане',
|
||||
cancel: 'Отказ',
|
||||
change: 'Промени',
|
||||
change_always_open_with: 'Искате ли винаги да отваряте този тип файл с',
|
||||
@@ -42,20 +41,13 @@ const bg = {
|
||||
close: 'Затвори',
|
||||
close_all_windows_and_log_out: 'Затвори прозорците и излез',
|
||||
confirm: 'Потвърди',
|
||||
confirm_2fa_setup: 'Добавих кода към приложението си за удостоверяване',
|
||||
confirm_2fa_recovery: 'Запазих кодовете за възстановяване на сигурно място',
|
||||
confirm_account_for_free_referral_storage_c2a:
|
||||
'Създайте акаунт и потвърдете имейл адреса си, за да получите 1 GB безплатно пространство. Вашият приятел също ще получи 1 GB безплатно пространство.',
|
||||
confirm_code_generic_incorrect: 'Неправилен код.',
|
||||
confirm_code_generic_too_many_requests:
|
||||
'Твърде много заявки. Моля, изчакайте няколко минути.',
|
||||
confirm_code_generic_submit: 'Изпрати код',
|
||||
confirm_code_generic_try_again: 'Опитай отново',
|
||||
confirm_code_generic_title: 'Въведете код за потвърждение',
|
||||
confirm_code_2fa_instruction:
|
||||
'Въведете 6-цифрения код от приложението си за удостоверяване.',
|
||||
confirm_code_2fa_submit_btn: 'Изпрати',
|
||||
confirm_code_2fa_title: 'Въведете 2FA код',
|
||||
confirm_delete_multiple_items:
|
||||
'Сигурни ли сте, че искате да изтриете завинаги тези елементи?',
|
||||
confirm_delete_single_item: 'Искате ли да изтриете завинаги този елемент?',
|
||||
@@ -68,10 +60,7 @@ const bg = {
|
||||
confirm_session_revoke:
|
||||
'Сигурни ли сте, че искате да прекратите тази сесия?',
|
||||
confirm_your_email_address: 'Потвърдете имейл адреса си',
|
||||
choose_publishing_option: 'Изберете как искате да публикувате уебсайта си:',
|
||||
contact_us: 'Свържете се с нас',
|
||||
contact_us_verification_required:
|
||||
'Трябва да имате потвърден имейл адрес, за да използвате това.',
|
||||
continue: 'Продължи',
|
||||
copy: 'Копирай',
|
||||
copy_link: 'Копирай връзката',
|
||||
@@ -79,8 +68,6 @@ const bg = {
|
||||
copying_file: 'Копиране на %%',
|
||||
create_account: 'Създай акаунт',
|
||||
create_free_account: 'Създай безплатен акаунт',
|
||||
create_desktop_shortcut: 'Създай пряк път (Работен плот)',
|
||||
create_desktop_shortcut_s: 'Създай преки пътища (Работен плот)',
|
||||
create_shortcut: 'Създай пряк път',
|
||||
create_shortcut_s: 'Създай преки пътища',
|
||||
credits: 'Благодарности',
|
||||
@@ -96,17 +83,13 @@ const bg = {
|
||||
deploy_as_app: 'Разгърни като приложение',
|
||||
descending: 'Низходящ',
|
||||
desktop: 'Работен плот',
|
||||
desktop_background_fit: 'Побери',
|
||||
developers: 'Разработчици',
|
||||
dir_published_as_website: '%strong% беше публикувана на:',
|
||||
disable_2fa: 'Изключи 2FA',
|
||||
disable_2fa_confirm: 'Сигурни ли сте, че искате да изключите 2FA?',
|
||||
disable_2fa_instructions: 'Въведете паролата си, за да изключите 2FA.',
|
||||
documents: 'Документи',
|
||||
dont_allow: 'Не разрешавай',
|
||||
download: 'Изтегли',
|
||||
download_file: 'Изтегли файл',
|
||||
downloading: 'Изтегляне',
|
||||
email: 'Имейл',
|
||||
email_change_confirmation_sent:
|
||||
'Потвърдителен имейл беше изпратен на новия ви имейл адрес. Моля, проверете входящата си поща и следвайте инструкциите, за да завършите процеса.',
|
||||
@@ -136,13 +119,10 @@ const bg = {
|
||||
forgot_pass_c2a: 'Забравена парола?',
|
||||
from: 'От',
|
||||
general: 'Общи',
|
||||
get_a_copy_of_on_puter: 'Вземете копие на %% в Puter.com!',
|
||||
get_copy_link: 'Вземи връзка за копие',
|
||||
home: 'Начало',
|
||||
html_document: 'HTML документ',
|
||||
hue: 'Нюанс',
|
||||
incorrect_password: 'Грешна парола',
|
||||
invite_link: 'Линк за покана',
|
||||
item: 'елемент',
|
||||
items_in_trash_cannot_be_renamed:
|
||||
'Този елемент не може да бъде преименуван, защото е в Кошчето. За да го преименувате, първо го извадете от Кошчето.',
|
||||
@@ -154,7 +134,6 @@ const bg = {
|
||||
loading: 'Зареждане',
|
||||
log_in: 'Вход',
|
||||
log_out: 'Изход',
|
||||
looks_good: 'Изглежда добре!',
|
||||
manage_sessions: 'Управление на сесиите',
|
||||
modified: 'Променено',
|
||||
move: 'Премести',
|
||||
@@ -181,7 +160,6 @@ const bg = {
|
||||
open_with: 'Отвори с',
|
||||
original_name: 'Оригинално име',
|
||||
original_path: 'Оригинален път',
|
||||
oss_code_and_content: 'Софтуер и съдържание с отворен код',
|
||||
password: 'Парола',
|
||||
password_changed: 'Паролата е променена.',
|
||||
password_recovery_rate_limit:
|
||||
@@ -197,31 +175,22 @@ const bg = {
|
||||
paste: 'Постави',
|
||||
paste_into_folder: 'Постави в папката',
|
||||
path: 'Път',
|
||||
personalization: 'Персонализация',
|
||||
pick_name_for_website: 'Изберете име за вашия уебсайт:',
|
||||
pictures: 'Снимки',
|
||||
plural_suffix: 'и',
|
||||
powered_by_puter_js: 'Работи с {{link=docs}}Puter.js{{/link}}',
|
||||
preparing: 'Подготовка…',
|
||||
preparing_for_upload: 'Подготовка за качване…',
|
||||
print: 'Принтирай',
|
||||
privacy: 'Поверителност',
|
||||
proceed_to_login: 'Продължи към вход',
|
||||
proceed_with_account_deletion: 'Продължи с изтриването на акаунта',
|
||||
properties: 'Свойства',
|
||||
public: 'Публична',
|
||||
publish: 'Публикувай',
|
||||
publish_as_website: 'Публикувай като уебсайт',
|
||||
publish_as_serverless_worker: 'Публикувай като Worker',
|
||||
puter_description:
|
||||
'Puter е личен облак с приоритет на поверителността, който съхранява всичките ви файлове, приложения и игри на едно сигурно място, достъпно отвсякъде и по всяко време.',
|
||||
reading: 'Четене на %strong%',
|
||||
writing: 'Записване на %strong%',
|
||||
recover_password: 'Възстанови паролата',
|
||||
refer_friends_c2a:
|
||||
'Получете 1 GB за всеки приятел, който създаде и потвърди акаунт в Puter. Вашият приятел също ще получи 1 GB!',
|
||||
refer_friends_social_media_c2a:
|
||||
'Получете 1 GB безплатно пространство в Puter.com!',
|
||||
refresh: 'Опресни',
|
||||
rename: 'Преименувай',
|
||||
replace: 'Замени',
|
||||
@@ -231,12 +200,10 @@ const bg = {
|
||||
save: 'Запази',
|
||||
saturation: 'Наситеност',
|
||||
save_account: 'Запазване на акаунт',
|
||||
save_account_to_get_copy_link: 'Моля, създайте акаунт, за да продължите.',
|
||||
save_account_to_publish: 'Моля, създайте акаунт, за да продължите.',
|
||||
save_session: 'Запазване на сесия',
|
||||
save_session_c2a:
|
||||
'Създайте акаунт, за да запазите текущата си сесия и да избегнете загуба на работата си.',
|
||||
scan_qr_2fa: 'Сканирайте QR кода с приложението си за удостоверяване',
|
||||
search: 'Търсене',
|
||||
seconds: 'секунди',
|
||||
security: 'Сигурност',
|
||||
@@ -255,21 +222,16 @@ const bg = {
|
||||
show_hidden: 'Покажи скритите',
|
||||
sign_in_with_puter: 'Влез с Puter',
|
||||
sign_up: 'Регистрирай се',
|
||||
signing_in: 'Влизане…',
|
||||
size: 'Размер',
|
||||
skip: 'Пропусни',
|
||||
something_went_wrong: 'Нещо се обърка.',
|
||||
sort_by: 'Сортиране по',
|
||||
status: 'Статус',
|
||||
storage_usage: 'Използване на място за съхранение',
|
||||
storage_puter_used: 'използвано от Путер',
|
||||
taking_longer_than_usual:
|
||||
'Отнема малко повече време от обикновено. Моля, изчакайте...',
|
||||
terms: 'Условия',
|
||||
text_document: 'Текстов документ',
|
||||
'toolbar.enter_fullscreen': 'Вход в режим на цял екран',
|
||||
'toolbar.github': 'GitHub',
|
||||
'toolbar.refer': 'Препоръчай',
|
||||
tos_fineprint:
|
||||
"С натискане на 'Създай безплатен акаунт' вие се съгласявате с {{link=terms}}Условията за ползване{{/link}} и {{link=privacy}}Политиката за поверителност{{/link}} на Puter.",
|
||||
transparency: 'Прозрачност',
|
||||
@@ -299,8 +261,6 @@ const bg = {
|
||||
videos: 'Видеоклипове',
|
||||
visibility: 'Видимост',
|
||||
yes: 'Да',
|
||||
you_have_been_referred_to_puter_by_a_friend:
|
||||
'Били сте препоръчани в Puter от приятел!',
|
||||
zip: 'ZIP архивиране',
|
||||
tar: 'TAR архивиране',
|
||||
download_as_tar: 'Изтегли като TAR',
|
||||
@@ -310,25 +270,20 @@ const bg = {
|
||||
tarring: 'TAR архивиране на %strong%',
|
||||
|
||||
// === 2FA Setup ===
|
||||
setup2fa_1_step_heading: 'Отворете приложението си за удостоверяване',
|
||||
setup2fa_1_instructions: `
|
||||
Можете да използвате всяко приложение за удостоверяване, което поддържа протокола Time-based One-Time Password (TOTP).
|
||||
Има много варианти, но ако не сте сигурни,
|
||||
<a target="_blank" href="https://authy.com/download">Authy</a>
|
||||
е отлично решение за Android и iOS.
|
||||
`,
|
||||
setup2fa_2_step_heading: 'Сканирайте QR кода',
|
||||
setup2fa_3_step_heading: 'Въведете 6-цифрения код',
|
||||
setup2fa_4_step_heading: 'Копирайте кодовете за възстановяване',
|
||||
setup2fa_4_instructions: `
|
||||
Тези кодове за възстановяване са единственият начин да получите достъп до акаунта си, ако загубите телефона си или не можете да използвате приложението за удостоверяване.
|
||||
Уверете се, че ги съхранявате на сигурно място.
|
||||
`,
|
||||
setup2fa_5_step_heading: 'Потвърдете настройката на 2FA',
|
||||
setup2fa_5_confirmation_1:
|
||||
'Запазих кодовете за възстановяване на сигурно място',
|
||||
setup2fa_5_confirmation_2: 'Готов съм да включа 2FA',
|
||||
setup2fa_5_button: 'Включи 2FA',
|
||||
|
||||
// === 2FA Login ===
|
||||
login2fa_otp_title: 'Въведете 2FA код',
|
||||
@@ -338,7 +293,6 @@ const bg = {
|
||||
login2fa_recovery_instructions:
|
||||
'Въведете един от кодовете си за възстановяване, за да получите достъп до акаунта си.',
|
||||
login2fa_use_recovery_code: 'Използвай код за възстановяване',
|
||||
login2fa_recovery_back: 'Назад',
|
||||
login2fa_recovery_placeholder: 'XXXXXXXX',
|
||||
|
||||
// Sharing
|
||||
@@ -408,7 +362,6 @@ const bg = {
|
||||
'billing.accelerated': 'Ускорен',
|
||||
'billing.enjoy_msg':
|
||||
'Насладете се на %% облачно хранилище и други предимства.',
|
||||
too_many_attempts: 'Твърде много опити. Моля, опитайте отново по-късно.',
|
||||
server_timeout:
|
||||
'Сървърът отне твърде много време за отговор. Моля, опитайте отново.',
|
||||
signup_error:
|
||||
@@ -438,19 +391,14 @@ const bg = {
|
||||
window_title_open: 'Отвори',
|
||||
window_title_change_password: 'Промяна на парола',
|
||||
window_title_select_font: 'Изберете шрифт…',
|
||||
window_title_session_list: 'Списък със сесии!',
|
||||
window_title_set_new_password: 'Задайте нова парола',
|
||||
window_title_publish_website: 'Публикуване на уебсайт',
|
||||
window_title_publish_worker: 'Публикуване на Worker',
|
||||
window_title_authenticating: 'Удостоверяване…',
|
||||
window_title_refer_friend: 'Препоръчайте приятел!',
|
||||
|
||||
// Desktop UI
|
||||
desktop_exit_full_screen: 'Изход от режим на цял екран',
|
||||
desktop_enter_full_screen: 'Вход в режим на цял екран',
|
||||
|
||||
// Item UI
|
||||
item_shared_with_you: 'Потребител е споделил този елемент с вас.',
|
||||
item_shared_by_you:
|
||||
'Споделили сте този елемент с поне един друг потребител.',
|
||||
item_shortcut: 'Пряк път',
|
||||
@@ -462,9 +410,6 @@ const bg = {
|
||||
window_click_to_go_back: 'Кликнете, за да се върнете назад.',
|
||||
window_click_to_go_forward: 'Кликнете, за да продължите напред.',
|
||||
window_click_to_go_up: 'Кликнете, за да отидете една папка нагоре.',
|
||||
window_title_public: 'Публична',
|
||||
window_title_videos: 'Видеоклипове',
|
||||
window_title_pictures: 'Снимки',
|
||||
window_title_puter: 'Puter',
|
||||
window_folder_empty: 'Тази папка е празна',
|
||||
},
|
||||
|
||||
@@ -31,7 +31,6 @@ const bn = {
|
||||
allow: 'অনুমতি দিন',
|
||||
ascending: 'ঊর্ধ্বক্রমে',
|
||||
associated_websites: 'সংযুক্ত ওয়েবসাইটগুলি',
|
||||
auto_arrange: 'অটো বিন্যাস',
|
||||
cancel: 'বাতিল করুন',
|
||||
change_email: 'ই-মেইল পরিবর্তন করুন',
|
||||
change_language: 'ভাষা পরিবর্তন করুন',
|
||||
@@ -41,17 +40,10 @@ const bn = {
|
||||
close_all_windows_and_log_out: 'উইন্ডো বন্ধ এবং লগ আউট করুন',
|
||||
change_always_open_with: 'আপনি কি এই ধরনের ফাইলটি সবসময় এই সাথে খোলা রাখতে চান',
|
||||
confirm: 'অনুমোদন',
|
||||
confirm_2fa_setup: '২ ফেক্টর অথেন্টিকেশন সেটাপ নিশ্চিত করুন',
|
||||
confirm_2fa_recovery: 'আমি আমার পুনরুদ্ধার কোডগুলি একটি নিরাপদ স্থানে সংরক্ষণ করতে চাই',
|
||||
confirm_account_for_free_referral_storage_c2a: 'একটি অ্যাকাউন্ট তৈরি করুন এবং আপনার ইমেল ঠিকানা নিশ্চিত করুন যাতে ফ্রি ১ জিবি স্টোরেজ পান। আপনার বন্ধুও ১ জিবি ফ্রি স্টোরেজ পাবেন',
|
||||
confirm_code_generic_incorrect: 'কোডটি সঠিক নয় নিশ্চিত করুন।',
|
||||
confirm_code_generic_too_many_requests: 'অনুরোধের সংখ্যা বেশি হয়েছে, দয়া করে পরে আবার চেষ্টা করুন।',
|
||||
confirm_code_generic_submit: 'কোডটি নিশ্চিত করুন',
|
||||
confirm_code_generic_try_again: 'আবার চেষ্টা করুন',
|
||||
confirm_code_generic_title: 'শিরোনাম অনুমোদন দিন',
|
||||
confirm_code_2fa_instruction: 'আপনার অথেন্টিকেশন অ্যাপ্লিকেশন থেকে ৬-ডিজিটের কোডটি প্রবেশ করুন।',
|
||||
confirm_code_2fa_submit_btn: 'জমা দিন',
|
||||
confirm_code_2fa_title: '2FA কোড প্রবেশ করুন',
|
||||
confirm_delete_multiple_items: 'আপনি কি নিশ্চিত যে আপনি এই আইটেমগুলি স্থায়ীভাবে মুছতে চান?',
|
||||
confirm_delete_single_item: 'আপনি কি এই আইটেমটি স্থায়ীভাবে মুছতে চান?',
|
||||
confirm_open_apps_log_out: 'আপনার খোলা অ্যাপ আছে। আপনি কি নিশ্চিত যে আপনি লগ আউট করতে চান?',
|
||||
@@ -61,7 +53,6 @@ const bn = {
|
||||
confirm_session_revoke: 'আপনি কি নিশ্চিত যে আপনি এই সেশনটি প্রত্যাহার করতে চান?',
|
||||
confirm_your_email_address: 'আপনার ইমেল ঠিকানা নিশ্চিত করুন',
|
||||
contact_us: 'যোগাযোগ করুন',
|
||||
contact_us_verification_required: 'যোগাযোগের জন্য যাচাইকরণ প্রয়োজন',
|
||||
continue: 'চালিয়ে যান',
|
||||
copy: 'কপি',
|
||||
copy_link: 'লিংক কপি করুন',
|
||||
@@ -83,17 +74,13 @@ const bn = {
|
||||
deploy_as_app: 'অ্যাপ্লিকেশন হিসেবে ডিপ্লয়',
|
||||
descending: 'নিম্নক্রমে',
|
||||
desktop: 'ডেস্কটপ',
|
||||
desktop_background_fit: 'ফিট',
|
||||
developers: 'ডেভেলপারগণ',
|
||||
dir_published_as_website: '%strong% প্রকাশিত হয়েছে:',
|
||||
disable_2fa: '2FA অক্ষম করুন',
|
||||
disable_2fa_confirm: 'আপনি কি নিশ্চিত যে আপনি 2FA অক্ষম করতে চান?',
|
||||
disable_2fa_instructions: '2FA অক্ষম করতে আপনার পাসওয়ার্ড লিখুন।',
|
||||
documents: 'ডকুমেন্টস',
|
||||
dont_allow: 'অনুমতি নেই',
|
||||
download: 'ডাউনলোড',
|
||||
download_file: 'ফাইল ডাউনলোড করুন',
|
||||
downloading: 'ডাউনলোড হচ্ছে',
|
||||
email: 'ই-মেইল',
|
||||
email_change_confirmation_sent: 'নতুন ই-মেইল ঠিকানা নিশ্চিতকরণের জন্য একটি নিশ্চিতকরণ ইমেল পাঠানো হয়েছে। আপনার ইনবক্স পরীক্ষা করুন এবং নির্দেশানুযায়ী প্রক্রিয়াটি সম্পন্ন করুন।',
|
||||
email_invalid: 'ই-মেইল অবৈধ।',
|
||||
@@ -118,13 +105,10 @@ const bn = {
|
||||
forgot_pass_c2a: 'পাসওয়ার্ড ভুলে গেছেন?',
|
||||
from: 'থেকে',
|
||||
general: 'সাধারণ',
|
||||
get_a_copy_of_on_puter: 'পিউটার ডটকমে \'%%\' এর একটি অনুলিপি পান!',
|
||||
get_copy_link: 'কপি লিংক নিন',
|
||||
home: 'হোম',
|
||||
html_document: 'এইচটিএমএল ডকুমেন্ট',
|
||||
hue: 'হিউ',
|
||||
incorrect_password: 'ভুল পাসওয়ার্ড',
|
||||
invite_link: 'আমন্ত্রণ লিংক',
|
||||
item: 'আইটেম',
|
||||
items_in_trash_cannot_be_renamed: 'এই আইটেমটি নাম পরিবর্তন করা যাবে না কারণ এটি ট্র্যাশে রয়েছে। এই আইটেমটির নাম পরিবর্তন করতে, প্রথমে এটি ট্র্যাশ থেকে তুলে নিন।',
|
||||
jpeg_image: 'জেপিইজি ইমেজ',
|
||||
@@ -135,7 +119,6 @@ const bn = {
|
||||
loading: 'লোড হচ্ছে',
|
||||
log_in: 'লগ ইন করুন',
|
||||
log_out: 'লগ আউট',
|
||||
looks_good: 'ভাল দেখা যাচ্ছে!',
|
||||
manage_sessions: 'সেশন পরিচালনা করুন',
|
||||
modified: 'পরিবর্তিত',
|
||||
move: 'চলুন',
|
||||
@@ -160,7 +143,6 @@ const bn = {
|
||||
open_with: 'দিয়ে খোলুন',
|
||||
original_name: 'মূল নাম',
|
||||
original_path: 'মূল পথ',
|
||||
oss_code_and_content: 'ওপেন সোর্স সফটওয়্যার এবং কন্টেন্ট',
|
||||
password: 'পাসওয়ার্ড',
|
||||
password_changed: 'পাসওয়ার্ড পরিবর্তন করা হয়েছে।',
|
||||
password_recovery_rate_limit: 'আপনি আমাদের রেকভারি সিস্টেমে প্রতি দিনে অধিকতর পাঁচবার ব্যবহার করতে পারবেন না। দয়া করে কয়েক ঘণ্টা অপেক্ষা করুন এবং পুনরায় চেষ্টা করুন।',
|
||||
@@ -175,26 +157,19 @@ const bn = {
|
||||
paste: 'পেস্ট',
|
||||
paste_into_folder: 'ফোল্ডারে পেস্ট করুন',
|
||||
path: 'পথ',
|
||||
personalization: 'ব্যক্তিগতীকরণ',
|
||||
pick_name_for_website: 'আপনার ওয়েবসাইটের জন্য নাম নির্বাচন করুন:',
|
||||
pictures: 'চিত্র',
|
||||
plural_suffix: 'গুলি',
|
||||
powered_by_puter_js: '{{link=docs}}Puter.js{{/link}} দ্বারা প্রচালিত',
|
||||
preparing: 'প্রস্তুতি চলছে...',
|
||||
preparing_for_upload: 'আপলোডের জন্য প্রস্তুতি চলছে...',
|
||||
print: 'প্রিন্ট',
|
||||
privacy: 'গোপনীয়তা',
|
||||
proceed_to_login: 'লগইনে অগ্রসর হোন',
|
||||
proceed_with_account_deletion: 'অ্যাকাউন্ট মোছার জন্য অগ্রসর হন',
|
||||
properties: 'বৈশিষ্ট্য',
|
||||
public: 'পাবলিক',
|
||||
publish: 'প্রকাশ করুন',
|
||||
publish_as_website: 'ওয়েবসাইট হিসাবে প্রকাশ করুন',
|
||||
puter_description: 'Puter হল একটি গোপনীয়তা-প্রথম ব্যক্তিগত ক্লাউড, যেখানে আপনার সমস্ত ফাইল, অ্যাপ্লিকেশন এবং গেম একটি নিরাপদ জায়গায় রাখা হয়, যেখান থেকে যে কোনো সময় অ্যাক্সেস করা যায়।',
|
||||
reading_file: '%strong% পড়া হচ্ছে',
|
||||
recover_password: 'পাসওয়ার্ড পুনরুদ্ধার করুন',
|
||||
refer_friends_c2a: 'Puter তে অ্যাকাউন্ট তৈরি এবং নিশ্চিতকরণ করে ১ জিবি পান। আপনার বন্ধুও ১ জিবি পাবে!',
|
||||
refer_friends_social_media_c2a: 'Puter.com এ 1 GB বিনামূল্যের সংরক্ষণ পান!',
|
||||
refresh: 'রিফ্রেশ',
|
||||
rename: 'পুনঃনামকরণ',
|
||||
replace: 'বদলান',
|
||||
@@ -204,11 +179,9 @@ const bn = {
|
||||
save: 'সংরক্ষণ করুন',
|
||||
saturation: 'সম্পৃক্তি',
|
||||
save_account: 'অ্যাকাউন্ট সংরক্ষণ করুন',
|
||||
save_account_to_get_copy_link: 'অগ্রসর হতে অ্যাকাউন্ট তৈরি করুন।',
|
||||
save_account_to_publish: 'অগ্রসর হতে অ্যাকাউন্ট তৈরি করুন।',
|
||||
save_session: 'সেশন সংরক্ষণ করুন',
|
||||
save_session_c2a: 'আপনার বর্তমান সেশনটি সংরক্ষণ করতে একটি অ্যাকাউন্ট তৈরি করুন যাতে আপনার কাজ হারাতে না হয়।',
|
||||
scan_qr_2fa: 'আপনার প্রামাণিকতা অ্যাপ্লিকেশন দিয়ে QR কোডটি স্ক্যান করুন',
|
||||
search: 'অনুসন্ধান',
|
||||
seconds: 'সেকেন্ড',
|
||||
security: 'নিরাপত্তা',
|
||||
@@ -226,13 +199,11 @@ const bn = {
|
||||
show_hidden: 'লুকানো দেখান',
|
||||
sign_in_with_puter: 'Puter দিয়ে সাইন ইন করুন',
|
||||
sign_up: 'নিবন্ধন করুন',
|
||||
signing_in: 'সাইন ইন হচ্ছে...',
|
||||
size: 'আকার',
|
||||
skip: 'এড়িয়ে যান',
|
||||
something_went_wrong: 'কিছু সমস্যা হয়েছে।',
|
||||
sort_by: 'অনুযায়ী সাজান',
|
||||
status: 'অবস্থা',
|
||||
storage_usage: 'স্টোরেজ ব্যবহার',
|
||||
storage_puter_used: 'Puter দ্বারা ব্যবহৃত',
|
||||
taking_longer_than_usual: 'স্বাভাবিক চেয়ে বেশি সময় নিচ্ছে। অনুগ্রহ করে অপেক্ষা করুন...',
|
||||
terms: 'শর্তাবলী',
|
||||
@@ -260,29 +231,23 @@ const bn = {
|
||||
videos: 'ভিডিও',
|
||||
visibility: 'দৃশ্যমানতা',
|
||||
yes: 'হ্যাঁ',
|
||||
you_have_been_referred_to_puter_by_a_friend: 'আপনাকে একটি বন্ধুর মাধ্যমে পিউটার-এ রেফার করা হয়েছে',
|
||||
zip: 'জিপ',
|
||||
zipping_file: '%strong% জিপিং হচ্ছে',
|
||||
|
||||
// === 2FA Setup ===
|
||||
setup2fa_1_step_heading: 'আপনার প্রামাণিকতা অ্যাপ খুলুন',
|
||||
setup2fa_1_instructions: `
|
||||
আপনি যেকোনো প্রামাণিকতা অ্যাপ ব্যবহার করতে পারেন যা Time-based One-Time Password (TOTP) প্রোটোকল সমর্থন করে।
|
||||
অনেক বিকল্প রয়েছে, তবে যদি আপনি নিশ্চিত না হন
|
||||
<a target="_blank" href="https://authy.com/download">Authy</a>
|
||||
একটি ভালো পছন্দ Android এবং iOS এর জন্য।
|
||||
`,
|
||||
setup2fa_2_step_heading: 'QR কোড স্ক্যান করুন',
|
||||
setup2fa_3_step_heading: '৬-টি অংকের কোড লিখুন',
|
||||
setup2fa_4_step_heading: 'আপনার পুনরুদ্ধার কোড কপি করুন',
|
||||
setup2fa_4_instructions: `
|
||||
এই পুনরুদ্ধার কোডগুলি আপনার অ্যাকাউন্টে অ্যাক্সেস পাওয়ার একমাত্র উপায় যদি আপনি আপনার ফোন হারান বা আপনার প্রামাণিকতা অ্যাপ ব্যবহার করতে না পারেন।
|
||||
নিশ্চিত করুন যে আপনি তাদের একটি নিরাপদ জায়গায় সংরক্ষণ করেছেন।
|
||||
`,
|
||||
setup2fa_5_step_heading: '2FA সেটআপ নিশ্চিত করুন',
|
||||
setup2fa_5_confirmation_1: 'আমি আমার পুনরুদ্ধার কোডগুলি একটি নিরাপদ অবস্থানে সংরক্ষণ করেছি',
|
||||
setup2fa_5_confirmation_2: 'আমি 2FA সক্ষম করার জন্য প্রস্তুত',
|
||||
setup2fa_5_button: '2FA সক্ষম করুন',
|
||||
|
||||
// === 2FA Login ===
|
||||
login2fa_otp_title: '2FA কোড লিখুন',
|
||||
@@ -290,7 +255,6 @@ const bn = {
|
||||
login2fa_recovery_title: 'একটি পুনরুদ্ধার কোড লিখুন',
|
||||
login2fa_recovery_instructions: 'আপনার অ্যাকাউন্টে অ্যাক্সেস পাওয়ার জন্য আপনার পুনরুদ্ধার কোডগুলির মধ্য থেকে একটি লিখুন।',
|
||||
login2fa_use_recovery_code: 'একটি পুনরুদ্ধার কোড ব্যবহার করুন',
|
||||
login2fa_recovery_back: 'পিছনে',
|
||||
login2fa_recovery_placeholder: 'XXXXXXXX',
|
||||
|
||||
'change': 'পরিবর্তন করুন',
|
||||
@@ -359,20 +323,13 @@ const bn = {
|
||||
'billing.accelerated': 'ত্বরান্বিত',
|
||||
'billing.enjoy_msg': '%% ক্লাউড স্টোরেজ এবং অন্যান্য সুবিধা উপভোগ করুন।',
|
||||
|
||||
'choose_publishing_option': 'কিভাবে আপনি ওয়েবসাইট পাবলিশ করবেন সেটা বেছে নিনঃ',
|
||||
'create_desktop_shortcut': 'শর্টকাট তৈরি করুন (ডেস্কটপ)',
|
||||
'create_desktop_shortcut_s': 'শর্টকাটগুলো তৈরি করুন (ডেস্কটপ)',
|
||||
'create_shortcut_s': 'শর্টকাটগুলো তৈরি করুন',
|
||||
'minimize': 'আড়াল করুন',
|
||||
'reload_app': 'অ্যাপ রিলোড করুন',
|
||||
'publish_as_serverless_worker': 'কর্মী হিসেবে পাবলিশ করুন',
|
||||
'toolbar.enter_fullscreen': 'পরিপূর্ণ পর্দায় প্রবেশ করুন',
|
||||
'toolbar.github': 'গিটহাব',
|
||||
'toolbar.refer': 'রেফার',
|
||||
'used_of': '{{used}} ব্যবহৃত হয়েছে {{available}} এর মধ্যে',
|
||||
'worker': 'কর্মী',
|
||||
'billing.offering.basic': 'মৌলিক',
|
||||
'too_many_attempts': 'অনেক বেশী প্রচেষ্টা করা হয়েছে। দয়া করে পরে আবার চেষ্টা করুন।',
|
||||
'server_timeout': 'সার্ভারটি অনেক বেশী সময় নিয়েছে উত্তর দিতে। দয়া করে আবার চেষ্টা করুন।',
|
||||
'signup_error': 'সাইনআপ করার সময় একটি ত্রুটি ঘটেছে। দয়া করে আবার চেষ্টা করুন।',
|
||||
'alert_error_title': 'ত্রুটি!',
|
||||
@@ -390,15 +347,10 @@ const bn = {
|
||||
'window_title_open': 'খুলুন',
|
||||
'window_title_change_password': 'পাসওয়ার্ড পরিবর্তন করুন',
|
||||
'window_title_select_font': 'ফন্ট নির্বাচন করুন...',
|
||||
'window_title_session_list': 'সেশন তালিকা!',
|
||||
'window_title_set_new_password': 'নতুন পাসওয়ার্ড সেট করুন',
|
||||
'window_title_publish_website': 'ওয়েবসাইট পাবলিশ করুন',
|
||||
'window_title_publish_worker': 'কর্মী পাবলিশ করুন',
|
||||
'window_title_authenticating': 'প্রমানীকরণ চলমান...',
|
||||
'window_title_refer_friend': 'বন্ধুকে রেফার করুন!',
|
||||
'desktop_exit_full_screen': 'পরিপূর্ণ পর্দা থেকে বের হয়ে যান',
|
||||
'desktop_enter_full_screen': 'পরিপূর্ণ পর্দায় প্রবেশ করুন',
|
||||
'item_shared_with_you': 'একজন ব্যবহারকারী এটি আপনার সাথে শেয়ার করেছে।',
|
||||
'item_shared_by_you': 'আপনি এই বস্তুটি কমপক্ষে একজন ব্যবহারকারীর সাথে শেয়ার করেছেন।',
|
||||
'item_shortcut': 'শর্টকাট',
|
||||
'item_associated_websites': 'সংশ্লিষ্ট ওয়েবসাইট',
|
||||
@@ -407,9 +359,6 @@ const bn = {
|
||||
'window_click_to_go_back': 'ফিরে যেতে ক্লিক করুন।',
|
||||
'window_click_to_go_forward': 'এগিয়ে যেতে ক্লিক করুন।',
|
||||
'window_click_to_go_up': 'এক ডিরেক্টরি উপরে যেতে ক্লিক করুন।',
|
||||
'window_title_public': 'প্রকাশ্য',
|
||||
'window_title_videos': 'ভিডিও',
|
||||
'window_title_pictures': 'ছবি',
|
||||
'window_title_puter': 'পিউটার',
|
||||
'window_folder_empty': 'এই ফোল্ডারটি খালি আছে',
|
||||
|
||||
|
||||
@@ -31,7 +31,6 @@ const br = {
|
||||
allow: 'Permitir',
|
||||
ascending: 'Ascendente',
|
||||
associated_websites: 'Sites Associados',
|
||||
auto_arrange: 'Organizar Automaticamente',
|
||||
cancel: 'Cancelar',
|
||||
change_email: 'Mudar Email',
|
||||
change_language: 'Mudar Idioma',
|
||||
@@ -41,17 +40,10 @@ const br = {
|
||||
close_all_windows_and_log_out: 'Fechar Janelas e Sair',
|
||||
change_always_open_with: 'Deseja sempre abrir este tipo de arquivo com',
|
||||
confirm: 'Confirmar',
|
||||
confirm_2fa_setup: 'Adicionei o código ao meu aplicativo autenticador',
|
||||
confirm_2fa_recovery: 'Salvei meus códigos de recuperação em um local seguro',
|
||||
confirm_account_for_free_referral_storage_c2a: 'Crie uma conta e confirme seu endereço de e-mail para receber 1 GB de armazenamento gratuito. Seu amigo também receberá 1 GB de armazenamento gratuito.',
|
||||
confirm_code_generic_incorrect: 'Código Incorreto.',
|
||||
confirm_code_generic_too_many_requests: 'Muitas solicitações. Por favor, aguarde alguns minutos.',
|
||||
confirm_code_generic_submit: 'Enviar Código',
|
||||
confirm_code_generic_try_again: 'Tente Novamente',
|
||||
confirm_code_generic_title: 'Digite o Código de Confirmação',
|
||||
confirm_code_2fa_instruction: 'Digite o código de 6 dígitos do seu aplicativo autenticador.',
|
||||
confirm_code_2fa_submit_btn: 'Enviar',
|
||||
confirm_code_2fa_title: 'Digite o Código 2FA',
|
||||
confirm_delete_multiple_items: 'Tem certeza de que deseja excluir permanentemente estes itens?',
|
||||
confirm_delete_single_item: 'Deseja excluir permanentemente este item?',
|
||||
confirm_open_apps_log_out: 'Você tem aplicativos abertos. Tem certeza de que deseja sair?',
|
||||
@@ -61,7 +53,6 @@ const br = {
|
||||
confirm_session_revoke: 'Tem certeza de que deseja revogar esta sessão?',
|
||||
confirm_your_email_address: 'Confirme Seu Endereço de Email',
|
||||
contact_us: 'Fale Conosco',
|
||||
contact_us_verification_required: 'Você deve ter um endereço de e-mail verificado para usar isto.',
|
||||
continue: 'Continuar',
|
||||
copy: 'Copiar',
|
||||
copy_link: 'Copiar Link',
|
||||
@@ -83,17 +74,13 @@ const br = {
|
||||
deploy_as_app: 'Implantar como aplicativo',
|
||||
descending: 'Descendente',
|
||||
desktop: 'Área de Trabalho',
|
||||
desktop_background_fit: 'Ajustar',
|
||||
developers: 'Desenvolvedores',
|
||||
dir_published_as_website: '%strong% foi publicado em:',
|
||||
disable_2fa: 'Desativar 2FA',
|
||||
disable_2fa_confirm: 'Tem certeza de que deseja desativar 2FA?',
|
||||
disable_2fa_instructions: 'Digite sua senha para desativar 2FA.',
|
||||
documents: 'Documentos',
|
||||
dont_allow: 'Não Permitir',
|
||||
download: 'Baixar',
|
||||
download_file: 'Baixar Arquivo',
|
||||
downloading: 'Baixando',
|
||||
email: 'Email',
|
||||
email_change_confirmation_sent: 'Um e-mail de confirmação foi enviado para seu novo endereço de e-mail. Por favor, verifique sua caixa de entrada e siga as instruções para concluir o processo.',
|
||||
email_invalid: 'Email inválido.',
|
||||
@@ -118,13 +105,10 @@ const br = {
|
||||
forgot_pass_c2a: 'Esqueceu a senha?',
|
||||
from: 'De',
|
||||
general: 'Geral',
|
||||
get_a_copy_of_on_puter: 'Obtenha uma cópia de \'%%\' em Puter.com!',
|
||||
get_copy_link: 'Obter Link de Cópia',
|
||||
home: 'Início',
|
||||
html_document: 'Documento HTML',
|
||||
hue: 'Matiz',
|
||||
incorrect_password: 'Senha incorreta',
|
||||
invite_link: 'Link de Convite',
|
||||
item: 'item',
|
||||
items_in_trash_cannot_be_renamed: 'Este item não pode ser renomeado porque está na lixeira. Para renomear este item, primeiro arraste-o para fora da Lixeira.',
|
||||
jpeg_image: 'Imagem JPEG',
|
||||
@@ -135,7 +119,6 @@ const br = {
|
||||
loading: 'Carregando',
|
||||
log_in: 'Entrar',
|
||||
log_out: 'Sair',
|
||||
looks_good: 'Parece bom!',
|
||||
manage_sessions: 'Gerenciar Sessões',
|
||||
modified: 'Modificado',
|
||||
move: 'Mover',
|
||||
@@ -160,7 +143,6 @@ const br = {
|
||||
'open_with': 'Abrir com',
|
||||
'original_name': 'Nome Original',
|
||||
'original_path': 'Caminho Original',
|
||||
'oss_code_and_content': 'Software e Conteúdo de Código Aberto',
|
||||
'password': 'Senha',
|
||||
'password_changed': 'Senha alterada.',
|
||||
'password_recovery_rate_limit': 'Você atingiu nosso limite de tentativas; por favor, aguarde alguns minutos. Para evitar isso no futuro, evite recarregar a página muitas vezes.',
|
||||
@@ -172,26 +154,19 @@ const br = {
|
||||
'paste': 'Colar',
|
||||
'paste_into_folder': 'Colar na Pasta',
|
||||
'path': 'Caminho',
|
||||
'personalization': 'Personalização',
|
||||
'pick_name_for_website': 'Escolha um nome para o seu site:',
|
||||
'pictures': 'Imagens',
|
||||
'plural_suffix': 's',
|
||||
'powered_by_puter_js': 'Desenvolvido por {{link=docs}}Puter.js{{/link}}',
|
||||
'preparing': 'Preparando...',
|
||||
'preparing_for_upload': 'Preparando para upload...',
|
||||
'print': 'Imprimir',
|
||||
'privacy': 'Privacidade',
|
||||
'proceed_to_login': 'Prossiga para o login',
|
||||
'proceed_with_account_deletion': 'Prosseguir com a Exclusão da Conta',
|
||||
'properties': 'Propriedades',
|
||||
'public': 'Público',
|
||||
'publish': 'Publicar',
|
||||
'publish_as_website': 'Publicar como site',
|
||||
'puter_description': 'Puter é uma nuvem pessoal que prioriza a privacidade para manter todos os seus arquivos, aplicativos e jogos em um lugar seguro, acessível de qualquer lugar a qualquer momento.',
|
||||
'reading_file': 'Lendo %strong%',
|
||||
'recover_password': 'Recuperar Senha',
|
||||
'refer_friends_c2a': 'Ganhe 1 GB para cada amigo que criar e confirmar uma conta no Puter. Seu amigo também ganhará 1 GB!',
|
||||
'refer_friends_social_media_c2a': 'Ganhe 1 GB de armazenamento gratuito no Puter.com!',
|
||||
'refresh': 'Atualizar',
|
||||
'rename': 'Renomear',
|
||||
'replace': 'Substituir',
|
||||
@@ -201,11 +176,9 @@ const br = {
|
||||
'save': 'Salvar',
|
||||
'saturation': 'Saturação',
|
||||
'save_account': 'Salvar conta',
|
||||
'save_account_to_get_copy_link': 'Por favor, crie uma conta para prosseguir.',
|
||||
'save_account_to_publish': 'Por favor, crie uma conta para prosseguir.',
|
||||
'save_session': 'Salvar sessão',
|
||||
'save_session_c2a': 'Crie uma conta para salvar sua sessão atual e evitar perder seu trabalho.',
|
||||
'scan_qr_2fa': 'Escaneie o código QR com seu aplicativo autenticador',
|
||||
'search': 'Buscar',
|
||||
'seconds': 'segundos',
|
||||
'security': 'Segurança',
|
||||
@@ -224,13 +197,11 @@ const br = {
|
||||
'show_hidden': 'Mostrar ocultos',
|
||||
'sign_in_with_puter': 'Entrar com Puter',
|
||||
'sign_up': 'Cadastrar-se',
|
||||
'signing_in': 'Entrando...',
|
||||
'size': 'Tamanho',
|
||||
'skip': 'Pular',
|
||||
'something_went_wrong': 'Algo deu errado.',
|
||||
'sort_by': 'Ordenar por',
|
||||
'status': 'Status',
|
||||
'storage_usage': 'Uso de Armazenamento',
|
||||
'storage_puter_used': 'usado pelo Puter',
|
||||
'taking_longer_than_usual': 'Levando um pouco mais de tempo do que o normal. Por favor, aguarde...',
|
||||
'terms': 'Termos',
|
||||
@@ -258,29 +229,23 @@ const br = {
|
||||
'videos': 'Vídeos',
|
||||
'visibility': 'Visibilidade',
|
||||
'yes': 'Sim',
|
||||
'you_have_been_referred_to_puter_by_a_friend': 'Você foi indicado ao Puter por um amigo!',
|
||||
'zip': 'Compactar',
|
||||
'zipping_file': 'Compactando %strong%',
|
||||
|
||||
// === 2FA Setup ===
|
||||
'setup2fa_1_step_heading': 'Abra seu aplicativo autenticador',
|
||||
'setup2fa_1_instructions': `
|
||||
Você pode usar qualquer aplicativo autenticador que suporte o protocolo de Senha de Uso Único com Base em Tempo (TOTP).
|
||||
Existem muitas opções, mas se você não tiver certeza
|
||||
<a target='_blank' href='https://authy.com/download'>Authy</a>
|
||||
é uma escolha sólida para Android e iOS.
|
||||
`,
|
||||
'setup2fa_2_step_heading': 'Escaneie o código QR',
|
||||
'setup2fa_3_step_heading': 'Digite o código de 6 dígitos',
|
||||
'setup2fa_4_step_heading': 'Copie seus códigos de recuperação',
|
||||
'setup2fa_4_instructions': `
|
||||
Esses códigos de recuperação são a única maneira de acessar sua conta se você perder seu telefone ou não puder usar seu aplicativo autenticador.
|
||||
Certifique-se de armazená-los em um lugar seguro.
|
||||
`,
|
||||
'setup2fa_5_step_heading': 'Confirme a configuração do 2FA',
|
||||
'setup2fa_5_confirmation_1': 'Salvei meus códigos de recuperação em um local seguro',
|
||||
'setup2fa_5_confirmation_2': 'Estou pronto para ativar o 2FA',
|
||||
'setup2fa_5_button': 'Ativar 2FA',
|
||||
|
||||
// === 2FA Login ===
|
||||
'login2fa_otp_title': 'Digite o Código 2FA',
|
||||
@@ -288,7 +253,6 @@ const br = {
|
||||
'login2fa_recovery_title': 'Digite um código de recuperação',
|
||||
'login2fa_recovery_instructions': 'Digite um dos seus códigos de recuperação para acessar sua conta.',
|
||||
'login2fa_use_recovery_code': 'Usar um código de recuperação',
|
||||
'login2fa_recovery_back': 'Voltar',
|
||||
'login2fa_recovery_placeholder': 'XXXXXXXX',
|
||||
|
||||
'change': 'Alterar', // In English: "Change"
|
||||
@@ -353,20 +317,13 @@ const br = {
|
||||
'billing.accelerated': 'Aprimorado', // In English: "Accelerated"
|
||||
'billing.enjoy_msg': 'Aproveite %% de Armazenamento em Nuvem, além de outros benefícios.', // In English: "Enjoy %% of Cloud Storage plus other benefits."
|
||||
|
||||
'choose_publishing_option': 'Escolha como você gostaria de publicar seu site', // In English: "Choose how you want to publish your website:"
|
||||
'create_desktop_shortcut': 'Criar atalho (Área de Trabalho)', // In English: "Create Shortcut (Desktop)"
|
||||
'create_desktop_shortcut_s': 'Criar atalhos (Área de Trabalho)', // In English: "Create Shortcuts (Desktop)"
|
||||
'create_shortcut_s': 'Criar atalhos', // In English: "Create Shortcuts"
|
||||
'minimize': 'Minimizar', // In English: "Minimize"
|
||||
'reload_app': 'Recarregar App', // In English: "Reload App"
|
||||
'publish_as_serverless_worker': 'Publicar como Worker', // In English: "Publish as Worker"
|
||||
'toolbar.enter_fullscreen': 'Entrar em Tela Cheia', // In English: "Enter Full Screen"
|
||||
'toolbar.github': 'GitHub', // In English: "GitHub"
|
||||
'toolbar.refer': 'Indicar', // In English: "Refer"
|
||||
'used_of': '{{used}} utilizado de {{available}} disponível', // In English: "{{used}} used of {{available}}"
|
||||
'worker': 'Worker', // In English: "Worker"
|
||||
'billing.offering.basic': 'Básico', // In English: "Basic"
|
||||
'too_many_attempts': 'Muitas tentativas. Por favor, tente novamente mais tarde.', // In English: "Too many attempts. Please try again later."
|
||||
'server_timeout': 'O servidor demorou muito para responder. Por favor, tente novamente mais tarde.', // In English: "The server took too long to respond. Please try again."
|
||||
'signup_error': 'Ocorreu um erro durante o registro. Por favor, tente novamente mais tarde.', // In English: "An error occurred during signup. Please try again."
|
||||
'alert_error_title': 'Erro!', // In English: "Error!"
|
||||
@@ -384,15 +341,10 @@ const br = {
|
||||
'window_title_open': 'Abrir', // In English: "Open"
|
||||
'window_title_change_password': 'Mudar Senha', // In English: "Change Password"
|
||||
'window_title_select_font': 'Selecionar', // In English: "Select font…"
|
||||
'window_title_session_list': 'Lista de Sessões!', // In English: "Session List!"
|
||||
'window_title_set_new_password': 'Definir Nova Senha', // In English: "Set New Password"
|
||||
'window_title_publish_website': 'Publicar site', // In English: "Publish Website"
|
||||
'window_title_publish_worker': 'Publicar Worker', // In English: "Publish Worker"
|
||||
'window_title_authenticating': 'Autenticando...', // In English: "Authenticating..."
|
||||
'window_title_refer_friend': 'Indicar um amigo!', // In English: "Refer a friend!"
|
||||
'desktop_exit_full_screen': 'Sair de Tela Cheia', // In English: "Exit Full Screen"
|
||||
'desktop_enter_full_screen': 'Entrar em Tela Cheia', // In English: "Enter Full Screen"
|
||||
'item_shared_with_you': 'Um usuário compartilhou este item com você.', // In English: "A user has shared this item with you."
|
||||
'item_shared_by_you': 'Você compartilhou este item com pelo menos um usuário.', // In English: "You have shared this item with at least one other user."
|
||||
'item_shortcut': 'Atalho', // In English: "Shortcut"
|
||||
'item_associated_websites': 'Site associado', // In English: "Associated website"
|
||||
@@ -401,9 +353,6 @@ const br = {
|
||||
'window_click_to_go_back': 'Clique para retornar.', // In English: "Click to go back."
|
||||
'window_click_to_go_forward': 'Clique para avançar.', // In English: "Click to go forward."
|
||||
'window_click_to_go_up': 'Clique para voltar uma pasta.', // In English: "Click to go one directory up."
|
||||
'window_title_public': 'Público', // In English: "Public"
|
||||
'window_title_videos': 'Vídeos', // In English: "Videos"
|
||||
'window_title_pictures': 'Imagens', // In English: "Pictures"
|
||||
'window_title_puter': 'Puter', // In English: "Puter"
|
||||
'window_folder_empty': 'Esta pasta está vazia', // In English: "This folder is empty"
|
||||
|
||||
|
||||
@@ -62,8 +62,6 @@ const cs = {
|
||||
"app_group_remove_from_folder": "Odebrat ze složky",
|
||||
"associated_websites": "Přidružené weby",
|
||||
"app_feedback_sent": "Zpětná vazba byla odeslána. Děkujeme!",
|
||||
"auto_arrange": "Automaticky uspořádat",
|
||||
"browser_version": "Verze prohlížeče",
|
||||
"change_language": "Změnit jazyk",
|
||||
"captcha_required": "Dokončete prosím ověření CAPTCHA",
|
||||
"change_username": "Změnit uživatelské jméno",
|
||||
@@ -74,29 +72,19 @@ const cs = {
|
||||
"close": "Zavřít",
|
||||
"change_email": "Změnit e-mail",
|
||||
"revalidated": "Znovu ověřeno.",
|
||||
"color_depth": "Barevná hloubka",
|
||||
"revalidate_with_google": "Znovu ověřte pomocí Googlu",
|
||||
"confirm": "Potvrdit",
|
||||
"revalidate_sign_in_popup": "Ve vyskakovacím okně se přihlaste pomocí svého propojeného účtu.",
|
||||
"confirm_code_generic_try_again": "Zkuste to znovu",
|
||||
"confirm_code_generic_submit": "Odeslat kód",
|
||||
"confirm_code_generic_title": "Zadejte potvrzovací kód",
|
||||
"confirm_code_generic_incorrect": "Nesprávný kód.",
|
||||
"confirm_code_2fa_submit_btn": "Potvrdit",
|
||||
"confirm_2fa_recovery": "Uložil jsem své kódy pro obnovení na bezpečné místo",
|
||||
"confirm_code_2fa_instruction": "Zadejte 6místný kód z aplikace pro ověřování.",
|
||||
"confirm_continue_as": "Pokračovat jako <strong>{{username}}</strong>?<p>Tento odkaz vás přihlásí k danému účtu. Vše, co vytvoříte – soubory, nahraná videa, chaty – tam bude uloženo a viditelné pro každého, kdo to vlastní. Pokračujte, pouze pokud je účet váš.</p>",
|
||||
"confirm_new_password": "Potvrďte nové heslo",
|
||||
"confirm_code_generic_too_many_requests": "Příliš mnoho požadavků. Počkejte prosím několik minut.",
|
||||
"confirm_2fa_setup": "Přidal jsem kód do své aplikace pro ověřování",
|
||||
"close_all_windows_and_log_out": "Zavřít všechna okna a odhlásit se",
|
||||
"confirm_delete_user_title": "Smazat účet?",
|
||||
"confirm_delete_multiple_items": "Opravdu chcete tyto položky trvale smazat?",
|
||||
"confirm_code_2fa_title": "Zadejte 2FA kód",
|
||||
"contact_us": "Kontaktujte nás",
|
||||
"confirm_open_apps_log_out": "Máte otevřené aplikace. Opravdu se chcete odhlásit?",
|
||||
"confirm_delete_user": "Opravdu chcete trvale smazat svůj účet? Všechny vaše soubory a data budou odstraněny. Tuto akci nelze vrátit zpět.",
|
||||
"choose_publishing_option": "Vyberte, jak chcete svůj web publikovat:",
|
||||
"confirm_delete_single_item": "Chcete tuto položku trvale smazat?",
|
||||
"confirm_revoke_all_other_sessions": "Zrušit všechny ostatní relace? Zde zůstanete přihlášeni.",
|
||||
"confirm_your_email_address": "Potvrďte svou e-mailovou adresu",
|
||||
@@ -106,16 +94,12 @@ const cs = {
|
||||
"create_account": "Vytvořit účet",
|
||||
"continue": "Pokračovat",
|
||||
"cpu": "CPU",
|
||||
"contact_us_verification_required": "Abyste to mohli používat, musíte mít ověřenou e-mailovou adresu.",
|
||||
"create_desktop_shortcut": "Vytvořit zástupce na ploše",
|
||||
"copying_file": "Kopírování %%",
|
||||
"create_desktop_shortcut_s": "Vytvořit zástupce na ploše",
|
||||
"credits": "Kredity",
|
||||
"current_password": "Aktuální heslo",
|
||||
"cut": "Vyjmout",
|
||||
"close_all": "Zavřít vše",
|
||||
"created": "Vytvořeno",
|
||||
"cpu_cores": "CPU jádra",
|
||||
"change_icon": "Změnit ikonu",
|
||||
"create_free_account": "Vytvořit bezplatný účet",
|
||||
"create_shortcut": "Vytvořit zástupce",
|
||||
@@ -124,31 +108,22 @@ const cs = {
|
||||
"delete_permanently": "Trvale smazat",
|
||||
"delete_account": "Smazat účet",
|
||||
"desktop": "Plocha",
|
||||
"desktop_background_fit": "Přizpůsobit",
|
||||
"descending": "Klesající",
|
||||
"developers": "Vývojáři",
|
||||
"disable_2fa": "Zakázat 2FA",
|
||||
"deleting_file": "Mazání %%",
|
||||
"directory_depth_limit_exceeded": "Tato složka je vnořena příliš hluboko. Než do ní přidáte další složky, přesuňte ji někam blíže ke kořeni.",
|
||||
"disable_2fa_confirm": "Opravdu chcete deaktivovat 2FA?",
|
||||
"dir_published_as_website": "%strong% byl publikován pro:",
|
||||
"documents": "Dokumenty",
|
||||
"dont_allow": "Nepovolit",
|
||||
"date_modified": "Datum změny",
|
||||
"create_shortcut_s": "Vytvořte zástupce",
|
||||
"deploy_as_app": "Nasadit jako aplikaci",
|
||||
"client_information": "Informace o klientovi",
|
||||
"download": "Stáhnout",
|
||||
"download_file": "Stáhnout soubor",
|
||||
"downloading": "Stahování",
|
||||
"email": "E-mail",
|
||||
"confirm_download_file_to_desktop": "Opravdu chcete stáhnout %% na plochu?",
|
||||
"email_change_confirmation_sent": "Na novou e-mailovou adresu byl odeslán potvrzovací e-mail. Zkontrolujte doručenou poštu a dokončete postup podle pokynů.",
|
||||
"disk_storage": "Diskové úložiště",
|
||||
"email_invalid": "E-mail je neplatný.",
|
||||
"error_download_failed": "Stažení souboru se nezdařilo",
|
||||
"disable_2fa_instructions": "Pro deaktivaci 2FA zadejte své heslo.",
|
||||
"downloading_file": "Stahování %%",
|
||||
"email_required": "E-mail je povinný.",
|
||||
"empty_trash": "Vysypat koš",
|
||||
"emptying_trash": "Vysypávání koše…",
|
||||
@@ -170,7 +145,6 @@ const cs = {
|
||||
"home": "Domů",
|
||||
"hue": "Odstín",
|
||||
"incorrect_password": "Nesprávné heslo",
|
||||
"get_a_copy_of_on_puter": "Získejte kopii '%%' na Puter.com!",
|
||||
"enter_password_to_confirm_delete_user": "Pro potvrzení smazání účtu zadejte své heslo",
|
||||
"error_unknown_cause": "Došlo k neznámé chybě.",
|
||||
"error_message_is_missing": "Chybí chybová zpráva.",
|
||||
@@ -182,13 +156,10 @@ const cs = {
|
||||
"link_copied": "Odkaz zkopírován",
|
||||
"loading": "Načítání",
|
||||
"jpeg_image": "obrázek JPEG",
|
||||
"get_copy_link": "Získat odkaz ke kopírování",
|
||||
"keep_both": "Nechte si obojí",
|
||||
"html_document": "HTML dokument",
|
||||
"invite_link": "Odkaz na pozvánku",
|
||||
"log_in": "Přihlásit se",
|
||||
"log_out": "Odhlásit se",
|
||||
"looks_good": "Vypadá to dobře!",
|
||||
"move": "Přesunout",
|
||||
"minimize": "Minimalizovat",
|
||||
"modified": "Upraveno",
|
||||
@@ -216,8 +187,6 @@ const cs = {
|
||||
"open_with_ai": "Otevřít pomocí AI",
|
||||
"os": "Operační systém",
|
||||
"name_must_be_string": "Název může být pouze řetězec.",
|
||||
"oss_code_and_content": "Software a obsah s otevřeným zdrojovým kódem",
|
||||
"os_version": "Verze OS",
|
||||
"password": "Heslo",
|
||||
"password_changed": "Heslo bylo změněno.",
|
||||
"password_recovery_unknown_error": "Došlo k neznámé chybě. Zkuste to znovu později.",
|
||||
@@ -226,7 +195,6 @@ const cs = {
|
||||
"password_required": "Heslo je povinné.",
|
||||
"open_with": "Otevřít pomocí",
|
||||
"path": "Cesta",
|
||||
"personalization": "Personalizace",
|
||||
"paste": "Vložit",
|
||||
"password_strength_error": "Heslo musí mít alespoň 8 znaků a obsahovat alespoň jedno velké písmeno, jedno malé písmeno, jednu číslici a jeden speciální znak.",
|
||||
"phone_country_label": "Země",
|
||||
@@ -257,24 +225,17 @@ const cs = {
|
||||
"preparing": "Příprava...",
|
||||
"print": "Vytisknout",
|
||||
"privacy": "Soukromí",
|
||||
"powered_by_puter_js": "Používá technologii {{link=docs}}Puter.js{{/link}}",
|
||||
"proceed_with_account_deletion": "Pokračujte ve smazání účtu",
|
||||
"pick_name_for_website": "Vyberte název pro svůj web:",
|
||||
"phone_code_sent_whatsapp": "Zadejte 6místný kód odeslaný přes WhatsApp na",
|
||||
"phone_code_sent_to": "Zadejte 6místný kód odeslaný na",
|
||||
"properties": "Vlastnosti",
|
||||
"publish": "Publikovat",
|
||||
"public": "Veřejné",
|
||||
"ram": "RAM",
|
||||
"preparing_for_upload": "Příprava na nahrání...",
|
||||
"pixel_ratio": "Poměr pixelů",
|
||||
"proceed_to_login": "Pokračovat k přihlášení",
|
||||
"publish_as_website": "Publikovat jako web",
|
||||
"refresh": "Obnovit",
|
||||
"puter_description": "Puter je osobní cloud zaměřený na ochranu soukromí, který uchovává všechny vaše soubory, aplikace a hry na jednom bezpečném místě, které jsou dostupné odkudkoli a kdykoli.",
|
||||
"rename": "Přejmenovat",
|
||||
"replace": "Nahradit",
|
||||
"refer_friends_social_media_c2a": "Získejte 1 GB úložného prostoru zdarma na Puter.com!",
|
||||
"reading": "Čtení %strong%",
|
||||
"writing": "Psaní %strong%",
|
||||
"Resources": "Zdroje",
|
||||
@@ -285,53 +246,27 @@ const cs = {
|
||||
"recover_password": "Obnovit heslo",
|
||||
"publish_as_serverless_worker": "Publikovat jako pracovník",
|
||||
"save_session": "Uložit relaci",
|
||||
"save_account_to_get_copy_link": "Chcete-li pokračovat, vytvořte si účet.",
|
||||
"resend_confirmation_code": "Znovu odeslat potvrzovací kód",
|
||||
"scan_qr_2fa": "Naskenujte QR kód pomocí aplikace pro ověřování",
|
||||
"save_account_to_publish": "Chcete-li pokračovat, vytvořte si účet.",
|
||||
"seconds": "sekundy",
|
||||
"search": "Hledat",
|
||||
"save_session_c2a": "Vytvořte si účet pro uložení aktuální relace a vyhněte se ztrátě své práce.",
|
||||
"security": "Zabezpečení",
|
||||
"screen_resolution": "Rozlišení obrazovky",
|
||||
"select": "Vybrat",
|
||||
"send": "Odeslat",
|
||||
"sessions": "Relace",
|
||||
"selected": "vybráno",
|
||||
"server_information": "Informace o serveru",
|
||||
"settings": "Nastavení",
|
||||
"keyboard_shortcuts": "Klávesové zkratky",
|
||||
"keyboard_shortcuts_action": "Akce",
|
||||
"session_saved": "Děkujeme za vytvoření účtu. Tato relace byla uložena.",
|
||||
"send_password_recovery_email": "Odeslat e-mail pro obnovení hesla",
|
||||
"save_account": "Uložit účet",
|
||||
"keyboard_shortcuts_shortcut": "Zkratka",
|
||||
"keyboard_shortcuts_navigation": "Navigace",
|
||||
"keyboard_shortcuts_general": "Obecné",
|
||||
"keyboard_shortcuts_search": "Otevřít vyhledávání",
|
||||
"keyboard_shortcuts_select_all": "Vybrat všechny položky",
|
||||
"keyboard_shortcuts_intro": "Naučte se nejužitečnější zkratky pro rychlejší navigaci v Puteru.",
|
||||
"keyboard_shortcuts_files": "Soubory a schránka",
|
||||
"keyboard_shortcuts_undo": "Vrátit zpět poslední akci",
|
||||
"keyboard_shortcuts_open_item": "Otevřít vybranou položku",
|
||||
"keyboard_shortcuts_close_window": "Zavřít aktivní okno",
|
||||
"keyboard_shortcuts_arrow_navigation": "Procházet nabídky a výběry",
|
||||
"keyboard_shortcuts_type_to_select": "Zadat název položky a přejít na ni",
|
||||
"keyboard_shortcuts_open_help": "Otevřít tuto příručku klávesových zkratek",
|
||||
"keyboard_shortcuts_close_menus": "Zavřít dialogová okna, nabídky a vyskakovací okna",
|
||||
"share": "Sdílet",
|
||||
"share_ellipsis": "Sdílet…",
|
||||
"keyboard_shortcuts_copy": "Kopírovat vybrané položky",
|
||||
"keyboard_shortcuts_type_to_select_keys": "Zadat písmena nebo čísla",
|
||||
"keyboard_shortcuts_cut": "Vyjmout vybrané položky",
|
||||
"keyboard_shortcuts_paste": "Vložit položky",
|
||||
"share_to": "Sdílet s",
|
||||
"set_new_password": "Nastavit nové heslo",
|
||||
"shared": "Sdíleno",
|
||||
"share_access_level": "Úroveň přístupu",
|
||||
"keyboard_shortcuts_permanent_delete": "Trvale smazat (po potvrzení)",
|
||||
"share_access_level_for": "Úroveň přístupu pro {{recipient}}",
|
||||
"keyboard_shortcuts_delete": "Přesunout vybrané položky do koše",
|
||||
"shared_by": "Sdíleno uživatelem",
|
||||
"shared_with_me": "Sdíleno se mnou",
|
||||
"share_access_write": "Může upravovat",
|
||||
@@ -341,11 +276,9 @@ const cs = {
|
||||
"share_owner": "Majitel",
|
||||
"share_done": "Hotovo",
|
||||
"share_no_one": "Zatím s nikým nesdíleno.",
|
||||
"share_remove_access_for": "Odebrat přístup pro {{recipient}}",
|
||||
"share_shared_with": "Sdíleno s {{recipient}}",
|
||||
"share_failed": "Tuto položku nelze sdílet.",
|
||||
"share_add_people": "Přidejte lidi pomocí e-mailu nebo uživatelského jména",
|
||||
"share_nothing_shared": "Zatím s vámi nebylo nic sdíleno.",
|
||||
"share_awaiting_signup": "Pozván",
|
||||
"share_invited": "Pozván {{recipient}} – přístup získá po registraci",
|
||||
"share_cancel_invite": "Zrušit pozvánku",
|
||||
@@ -357,7 +290,6 @@ const cs = {
|
||||
"share_confirm_remove": "Odebrat uživateli {{recipient}} přístup k této položce?",
|
||||
"share_invite_cancelled": "Pozvánka do {{recipient}} byla zrušena",
|
||||
"share_access_removed": "Odebráno {{recipient}}",
|
||||
"share_cancel_invite_for": "Zrušit pozvánku do {{recipient}}",
|
||||
"share_access_updated": "Aktualizován přístup pro {{recipient}}",
|
||||
"share_confirm_cancel_invite": "Zrušit pozvánku odeslanou uživateli {{recipient}}?",
|
||||
"manage": "Spravovat",
|
||||
@@ -379,7 +311,6 @@ const cs = {
|
||||
"share_inherited_via": "přes {{folder}}",
|
||||
"sign_in": "Přihlásit se",
|
||||
"size": "Velikost",
|
||||
"signing_in": "Přihlašování…",
|
||||
"sign_up": "Vytvořit účet",
|
||||
"skip": "Přeskočit",
|
||||
"something_went_wrong": "Něco se pokazilo. Zkuste to prosím znovu.",
|
||||
@@ -387,15 +318,11 @@ const cs = {
|
||||
"Storage": "Úložiště",
|
||||
"blocked_added": "Blokováno {{username}}",
|
||||
"storage_puter_used": "používá Puter",
|
||||
"storage_usage": "Využití úložiště",
|
||||
"sign_in_with_puter": "Přihlásit se pomocí Puteru",
|
||||
"your_plan": "Váš plán",
|
||||
"show_hidden": "Zobrazit skryté",
|
||||
"sort_by": "Seřadit podle",
|
||||
"terms": "Podmínky",
|
||||
"toolbar.enter_fullscreen": "Přejít na celou obrazovku",
|
||||
"toolbar.github": "GitHub",
|
||||
"toolbar.refer": "Odkázat",
|
||||
"transparency": "Průhlednost",
|
||||
"taking_longer_than_usual": "Trvá to trochu déle než obvykle. Čekejte prosím...",
|
||||
"trash": "Koš",
|
||||
@@ -407,13 +334,10 @@ const cs = {
|
||||
"text_document": "Textový dokument",
|
||||
"two_factor_disabled": "2FA vypnuto",
|
||||
"ui_revoke": "Zrušit",
|
||||
"ui_session_app": "Aplikace",
|
||||
"ui_session_client": "Klient",
|
||||
"tos_fineprint": "Registrací vyjadřujete souhlas s {{link=terms}}smluvními podmínkami{{/link}} a {{link=privacy}}zásadami ochrany soukromí{{/link}} společnosti Puter.",
|
||||
"ui_session_created": "Vytvořeno",
|
||||
"ui_session_current": "Aktuální",
|
||||
"ui_session_expires": "Platnost vyprší",
|
||||
"ui_session_ip": "IP",
|
||||
"ui_manage_sessions": "Spravovat relace",
|
||||
"ui_search": "Hledat relace…",
|
||||
"ui_session_count_one": "1 aktivní relace",
|
||||
@@ -437,7 +361,6 @@ const cs = {
|
||||
"username": "Uživatelské jméno",
|
||||
"username_required": "Uživatelské jméno je povinné.",
|
||||
"unzipping": "Rozbalení %strong%",
|
||||
"uploading_file": "Nahrávání %%",
|
||||
"untarring": "Rozbalování %strong%",
|
||||
"visibility": "Viditelnost",
|
||||
"videos": "Videa",
|
||||
@@ -449,26 +372,19 @@ const cs = {
|
||||
"worker": "Pracovník",
|
||||
"tar": "Archiv TAR",
|
||||
"sequencing": "Sekvenování %strong%",
|
||||
"you_have_been_referred_to_puter_by_a_friend": "Přítel vás doporučil do Puteru!",
|
||||
"setup2fa_1_step_heading": "Otevřít ověřovací aplikaci",
|
||||
"zipping": "Komprimování %strong%",
|
||||
"used_of": "{{used}} využito z {{available}}",
|
||||
"username_changed": "Uživatelské jméno bylo úspěšně změněno.",
|
||||
"tarring": "Vytváření archivu TAR %strong%",
|
||||
"setup2fa_2_step_heading": "Naskenujte QR kód",
|
||||
"setup2fa_5_confirmation_1": "Uložil jsem své kódy pro obnovení na bezpečné místo",
|
||||
"setup2fa_5_button": "Povolit 2FA",
|
||||
"login2fa_otp_title": "Zadejte 2FA kód",
|
||||
"setup2fa_1_instructions": "Naskenujte QR kód pomocí ověřovací aplikace a poté zadejte 6místný kód, který aplikace vygeneruje.",
|
||||
"login2fa_otp_instructions": "Zadejte 6místný kód z aplikace pro ověřování.",
|
||||
"login2fa_recovery_title": "Zadejte kód pro obnovení",
|
||||
"login2fa_use_recovery_code": "Použijte kód pro obnovení",
|
||||
"download_as_tar": "Stáhnout jako archiv TAR",
|
||||
"setup2fa_4_step_heading": "Zkopírujte své kódy pro obnovení",
|
||||
"setup2fa_3_step_heading": "Zadejte 6místný kód",
|
||||
"setup2fa_5_confirmation_2": "Jsem připraven povolit 2FA",
|
||||
"setup2fa_5_step_heading": "Potvrďte nastavení 2FA",
|
||||
"login2fa_recovery_back": "Zpět",
|
||||
"Editor": "Editor",
|
||||
"Owner": "Majitel",
|
||||
"login2fa_recovery_instructions": "Chcete-li získat přístup k účtu, zadejte jeden ze svých obnovovacích kódů.",
|
||||
@@ -534,7 +450,6 @@ const cs = {
|
||||
"billing.download_receipt": "Stáhnout potvrzení",
|
||||
"billing.current_plan": "Aktuální plán",
|
||||
"auth_error_generic": "Ověření se nezdařilo. Zkuste to prosím znovu.",
|
||||
"too_many_attempts": "Příliš mnoho pokusů. Zkuste to znovu později.",
|
||||
"welcome": "Vítejte",
|
||||
"signup_blocked_message": "Váš účet se nepodařilo vytvořit.",
|
||||
"signup_error": "Při registraci došlo k chybě. Zkuste to prosím znovu.",
|
||||
@@ -570,20 +485,12 @@ const cs = {
|
||||
"window_title_select_font": "Vybrat písmo…",
|
||||
"window_title_publish_website": "Publikovat webové stránky",
|
||||
"sign_up_with_email": "Zaregistrujte se pomocí e-mailu",
|
||||
"window_title_refer_friend": "Doporučte příteli!",
|
||||
"window_title_session_list": "Seznam relací!",
|
||||
"desktop_enter_full_screen": "Přejít na celou obrazovku",
|
||||
"item_shortcut": "Zkratka",
|
||||
"item_shared_by_you": "Tuto položku jste sdíleli s alespoň jedním dalším uživatelem.",
|
||||
"item_shared_with_you": "Tuto položku s vámi sdílí uživatel.",
|
||||
"window_click_to_go_up": "Kliknutím přejdete o jeden adresář nahoru.",
|
||||
"window_title_public": "Veřejné",
|
||||
"window_title_videos": "Videa",
|
||||
"window_title_pictures": "Obrázky",
|
||||
"window_folder_empty": "Tato složka je prázdná",
|
||||
"item_associated_websites": "Přidružený web",
|
||||
"window_click_to_go_back": "Kliknutím se vrátíte zpět.",
|
||||
"desktop_exit_full_screen": "Ukončit režim celé obrazovky",
|
||||
"no_suitable_apps_found": "Nebyly nalezeny žádné vhodné aplikace",
|
||||
"window_title_puter": "Puter",
|
||||
"item_associated_websites_plural": "Přidružené webové stránky",
|
||||
@@ -605,17 +512,13 @@ const cs = {
|
||||
"perm_app_data_store_all": "číst, měnit a mazat {{subject}}.",
|
||||
"perm_app_data_all": "číst, měnit a mazat vše, co pro vás {{app}} uložil, včetně všech uložených přihlašovacích údajů.",
|
||||
"approve": "Schválit",
|
||||
"copy_token_message": "Váš ověřovací token je zobrazen níže. Uchovejte jej v tajnosti – kdokoli s tímto tokenem má přístup k vašemu účtu.",
|
||||
"perm_dialog_footnote": "Toto můžete kdykoli změnit v Nastavení.",
|
||||
"auth_token": "Ověřovací token",
|
||||
"error_user_or_path_not_found": "Uživatel nebo cesta nenalezena.",
|
||||
"token_copied": "Token zkopírován",
|
||||
"copy_auth_token": "Kopírovat ověřovací token",
|
||||
"error_invalid_username": "Neplatné uživatelské jméno.",
|
||||
"perm_dialog_wants_to": "chce povolení",
|
||||
"token_label": "Označení",
|
||||
"token_label_required": "Zadejte štítek pro tento token.",
|
||||
"copy_token_description": "Zobrazit a zkopírovat ověřovací token",
|
||||
"create_api_token": "Vytvořit token API",
|
||||
"token_label_placeholder": "např. Moje CLI, akce GitHubu",
|
||||
"create_token": "Vytvořit token",
|
||||
@@ -636,10 +539,8 @@ const cs = {
|
||||
"redirect_destination": "Cíl přesměrování",
|
||||
"authorization_cancelled_desc": "Zamítli jste žádost o autorizaci.",
|
||||
"external_site_auth_request": "Aplikace požaduje přístup k vašemu účtu.",
|
||||
"your_auth_token": "Váš ověřovací token",
|
||||
"authorization_cancelled_message": "Aplikace nezíská přístup k vašemu účtu. Toto okno můžete bezpečně zavřít.",
|
||||
"token_manage_hint": "Tento token můžete kdykoli odvolat pod",
|
||||
"authme_security_warning": "Váš ověřovací token bude sdílen s touto aplikací za účelem dokončení přihlášení.",
|
||||
"authme_full_token_request": "Aplikace požaduje token s úplným přístupem k vašemu účtu.",
|
||||
"shared_full_token_item_account": "Změňte své heslo, e-mailovou adresu a dvoufaktorová nastavení",
|
||||
"shared_full_token_note": "Toto není omezený token API. Pokračujte pouze v případě, že jste s tím začali sami a zcela důvěřujete výše uvedenému cíli. Můžete jej zrušit v Nastavení → Zabezpečení → Spravovat relace.",
|
||||
|
||||
@@ -31,7 +31,6 @@ const da = {
|
||||
allow: 'Tillad',
|
||||
ascending: 'Stigende',
|
||||
associated_websites: 'Tilknyttede websteder',
|
||||
auto_arrange: 'Auto Arrangere',
|
||||
cancel: 'Annuller',
|
||||
change_email: 'Ændre e-mail',
|
||||
change_language: 'Ændre sprog',
|
||||
@@ -41,17 +40,10 @@ const da = {
|
||||
close_all_windows_and_log_out: 'Luk vinduer og log ud',
|
||||
change_always_open_with: 'Vil du altid åbne denne filtype med',
|
||||
confirm: 'Bekræft',
|
||||
confirm_2fa_setup: 'Jeg har tilføjet koden til min autentifikator-app',
|
||||
confirm_2fa_recovery: 'Jeg har gemt mine gendannelseskoder på et sikkert sted',
|
||||
confirm_account_for_free_referral_storage_c2a: 'Opret en konto og bekræft din e-mailadresse for at modtage 1 GB gratis lagerplads. Din ven vil også få 1 GB gratis lagerplads.',
|
||||
confirm_code_generic_incorrect: 'Forkert kode.',
|
||||
confirm_code_generic_too_many_requests: 'For mange anmodninger. Vent et par minutter.',
|
||||
confirm_code_generic_submit: 'Indsend kode',
|
||||
confirm_code_generic_try_again: 'Prøv igen',
|
||||
confirm_code_generic_title: 'Indtast bekræftelseskode',
|
||||
confirm_code_2fa_instruction: 'Indtast den 6-cifrede kode fra din autentifikator-app.',
|
||||
confirm_code_2fa_submit_btn: 'Indsend',
|
||||
confirm_code_2fa_title: 'Indtast 2FA-kode',
|
||||
confirm_delete_multiple_items: 'Er du sikker på, at du vil slette disse elementer permanent?',
|
||||
confirm_delete_single_item: 'Vil du slette dette element permanent?',
|
||||
confirm_open_apps_log_out: 'Du har åbne apps. Er du sikker på, at du vil logge ud?',
|
||||
@@ -61,7 +53,6 @@ const da = {
|
||||
confirm_session_revoke: 'Er du sikker på, at du vil tilbagekalde denne session?',
|
||||
confirm_your_email_address: 'Bekræft din e-mailadresse',
|
||||
contact_us: 'Kontakt os',
|
||||
contact_us_verification_required: 'Du skal have en verificeret e-mailadresse for at bruge dette.',
|
||||
continue: 'Fortsæt',
|
||||
copy: 'Kopier',
|
||||
copy_link: 'Kopier link',
|
||||
@@ -83,17 +74,13 @@ const da = {
|
||||
deploy_as_app: 'Implementer som app',
|
||||
descending: 'Faldende',
|
||||
desktop: 'Skrivebord',
|
||||
desktop_background_fit: 'Tilpas',
|
||||
developers: 'Udviklere',
|
||||
dir_published_as_website: '%strong% er blevet offentliggjort til:',
|
||||
disable_2fa: 'Deaktiver 2FA',
|
||||
disable_2fa_confirm: 'Er du sikker på, at du vil deaktivere 2FA?',
|
||||
disable_2fa_instructions: 'Indtast din adgangskode for at deaktivere 2FA.',
|
||||
documents: 'Dokumenter',
|
||||
dont_allow: 'Tillad ikke',
|
||||
download: 'Download',
|
||||
download_file: 'Download fil',
|
||||
downloading: 'Downloader',
|
||||
email: 'E-mail',
|
||||
email_change_confirmation_sent: 'En bekræftelses-e-mail er sendt til din nye e-mailadresse. Kontroller din indbakke og følg instruktionerne for at fuldføre processen.',
|
||||
email_invalid: 'E-mail er ugyldig.',
|
||||
@@ -118,13 +105,10 @@ const da = {
|
||||
forgot_pass_c2a: 'Glemt adgangskode?',
|
||||
from: 'Fra',
|
||||
general: 'Generelt',
|
||||
get_a_copy_of_on_puter: 'Få en kopi af \'%%\' på Puter.com!',
|
||||
get_copy_link: 'Få kopi-link',
|
||||
home: 'Hjem',
|
||||
html_document: 'HTML-dokument',
|
||||
hue: 'Farvetone',
|
||||
incorrect_password: 'Forkert adgangskode',
|
||||
invite_link: 'Inviter link',
|
||||
item: 'element',
|
||||
items_in_trash_cannot_be_renamed: 'Dette element kan ikke omdøbes, fordi det er i papirkurven. For at omdøbe dette element, skal du først trække det ud af papirkurven.',
|
||||
jpeg_image: 'JPEG-billede',
|
||||
@@ -135,7 +119,6 @@ const da = {
|
||||
loading: 'Indlæser',
|
||||
log_in: 'Log ind',
|
||||
log_out: 'Log ud',
|
||||
looks_good: 'Ser godt ud!',
|
||||
manage_sessions: 'Administrer sessioner',
|
||||
modified: 'Ændret',
|
||||
move: 'Flyt',
|
||||
@@ -160,7 +143,6 @@ const da = {
|
||||
open_with: 'Åbn med',
|
||||
original_name: 'Originalt navn',
|
||||
original_path: 'Original sti',
|
||||
oss_code_and_content: 'Open Source Software og indhold',
|
||||
password: 'Adgangskode',
|
||||
password_changed: 'Adgangskode ændret.',
|
||||
password_recovery_rate_limit: 'Du har nået vores rate-limit; vent venligst et par minutter. For at undgå dette i fremtiden, undgå at genindlæse siden for mange gange.',
|
||||
@@ -172,26 +154,19 @@ const da = {
|
||||
paste: 'Sæt ind',
|
||||
paste_into_folder: 'Sæt ind i mappe',
|
||||
path: 'Sti',
|
||||
personalization: 'Personalisering',
|
||||
pick_name_for_website: 'Vælg et navn til dit websted:',
|
||||
pictures: 'Billeder',
|
||||
plural_suffix: 's',
|
||||
powered_by_puter_js: 'Udviklet af {{link=docs}}Puter.js{{/link}}',
|
||||
preparing: 'Forbereder...',
|
||||
preparing_for_upload: 'Forbereder til upload...',
|
||||
print: 'Udskriv',
|
||||
privacy: 'Privatliv',
|
||||
proceed_to_login: 'Fortsæt til login',
|
||||
proceed_with_account_deletion: 'Fortsæt med sletning af konto',
|
||||
properties: 'Egenskaber',
|
||||
public: 'Offentlig',
|
||||
publish: 'Offentliggør',
|
||||
publish_as_website: 'Offentliggør som websted',
|
||||
puter_description: 'Puter er en privatlivsorienteret personlig sky til at opbevare alle dine filer, apps og spil på ét sikkert sted, tilgængeligt fra hvor som helst, når som helst.',
|
||||
reading_file: 'Læser %strong%',
|
||||
recover_password: 'Gendan adgangskode',
|
||||
refer_friends_c2a: 'Få 1 GB for hver ven, der opretter og bekræfter en konto på Puter. Din ven vil også få 1 GB!',
|
||||
refer_friends_social_media_c2a: 'Få 1 GB gratis lagerplads på Puter.com!',
|
||||
refresh: 'Opdater',
|
||||
rename: 'Omdøb',
|
||||
replace: 'Erstat',
|
||||
@@ -201,11 +176,9 @@ const da = {
|
||||
save: 'Gem',
|
||||
saturation: 'Mætning',
|
||||
save_account: 'Gem konto',
|
||||
save_account_to_get_copy_link: 'Opret venligst en konto for at fortsætte.',
|
||||
save_account_to_publish: 'Opret venligst en konto for at fortsætte.',
|
||||
save_session: 'Gem session',
|
||||
save_session_c2a: 'Opret en konto for at gemme din nuværende session og undgå at miste dit ændringer.',
|
||||
scan_qr_2fa: 'Scan QR-koden med din autentifikator-app',
|
||||
search: 'Søg',
|
||||
seconds: 'sekunder',
|
||||
security: 'Sikkerhed',
|
||||
@@ -223,13 +196,11 @@ const da = {
|
||||
show_hidden: 'Vis skjulte',
|
||||
sign_in_with_puter: 'Log ind med Puter',
|
||||
sign_up: 'Tilmeld dig',
|
||||
signing_in: 'Logger ind…',
|
||||
size: 'Størrelse',
|
||||
skip: 'Spring over',
|
||||
something_went_wrong: 'Noget gik galt.',
|
||||
sort_by: 'Sorter efter',
|
||||
status: 'Status',
|
||||
storage_usage: 'Lagerforbrug',
|
||||
storage_puter_used: 'brugt af Puter',
|
||||
taking_longer_than_usual: 'Tager lidt længere tid end normalt. Vent venligst...',
|
||||
terms: 'Vilkår',
|
||||
@@ -257,29 +228,23 @@ const da = {
|
||||
videos: 'Videoer',
|
||||
visibility: 'Synlighed',
|
||||
yes: 'Ja',
|
||||
you_have_been_referred_to_puter_by_a_friend: 'Du er blevet henvist til Puter af en ven!',
|
||||
zip: 'Zip',
|
||||
zipping_file: 'Zipper %strong%',
|
||||
|
||||
// === 2FA Setup ===
|
||||
setup2fa_1_step_heading: 'Åbn din autentifikator-app',
|
||||
setup2fa_1_instructions: `
|
||||
Du kan bruge enhver autentifikator-app, der understøtter Time-based One-Time Password (TOTP) protokollen.
|
||||
Der er mange at vælge imellem, men hvis du er usikker
|
||||
<a target="_blank" href="https://authy.com/download">Authy</a>
|
||||
er et solidt valg til Android og iOS.
|
||||
`,
|
||||
setup2fa_2_step_heading: 'Scan QR-koden',
|
||||
setup2fa_3_step_heading: 'Indtast den 6-cifrede kode',
|
||||
setup2fa_4_step_heading: 'Kopier dine gendannelseskoder',
|
||||
setup2fa_4_instructions: `
|
||||
Disse gendannelseskoder er den eneste måde at få adgang til din konto, hvis du mister din telefon eller ikke kan bruge din autentifikator-app.
|
||||
Sørg for at opbevare dem på et sikkert sted.
|
||||
`,
|
||||
setup2fa_5_step_heading: 'Bekræft 2FA-opsætning',
|
||||
setup2fa_5_confirmation_1: 'Jeg har gemt mine gendannelseskoder på et sikkert sted',
|
||||
setup2fa_5_confirmation_2: 'Jeg er klar til at aktivere 2FA',
|
||||
setup2fa_5_button: 'Aktivér 2FA',
|
||||
|
||||
// === 2FA Login ===
|
||||
login2fa_otp_title: 'Indtast 2FA-kode',
|
||||
@@ -287,7 +252,6 @@ const da = {
|
||||
login2fa_recovery_title: 'Indtast en gendannelseskode',
|
||||
login2fa_recovery_instructions: 'Indtast en af dine gendannelseskoder for at få adgang til din konto.',
|
||||
login2fa_use_recovery_code: 'Brug en gendannelseskode',
|
||||
login2fa_recovery_back: 'Tilbage',
|
||||
login2fa_recovery_placeholder: 'XXXXXXXX',
|
||||
|
||||
change: 'Skift',
|
||||
@@ -353,16 +317,10 @@ const da = {
|
||||
// =============================================================
|
||||
// Missing translations
|
||||
// =============================================================
|
||||
'choose_publishing_option': undefined, // In English: "Choose how you want to publish your website:"
|
||||
'create_desktop_shortcut': undefined, // In English: "Create Shortcut (Desktop)"
|
||||
'create_desktop_shortcut_s': undefined, // In English: "Create Shortcuts (Desktop)"
|
||||
'create_shortcut_s': undefined, // In English: "Create Shortcuts"
|
||||
'minimize': undefined, // In English: "Minimize"
|
||||
'reload_app': undefined, // In English: "Reload App"
|
||||
'publish_as_serverless_worker': undefined, // In English: "Publish as Worker"
|
||||
'toolbar.enter_fullscreen': undefined, // In English: "Enter Full Screen"
|
||||
'toolbar.github': undefined, // In English: "GitHub"
|
||||
'toolbar.refer': undefined, // In English: "Refer"
|
||||
'used_of': undefined, // In English: "{{used}} used of {{available}}"
|
||||
'worker': undefined, // In English: "Worker"
|
||||
'People with access': undefined, // In English: "People with access"
|
||||
@@ -417,7 +375,6 @@ const da = {
|
||||
'billing.expanded': undefined, // In English: "Expanded"
|
||||
'billing.accelerated': undefined, // In English: "Accelerated"
|
||||
'billing.enjoy_msg': undefined, // In English: "Enjoy %% of Cloud Storage plus other benefits."
|
||||
'too_many_attempts': undefined, // In English: "Too many attempts. Please try again later."
|
||||
'server_timeout': undefined, // In English: "The server took too long to respond. Please try again."
|
||||
'signup_error': undefined, // In English: "An error occurred during signup. Please try again."
|
||||
'alert_error_title': undefined, // In English: "Error!"
|
||||
@@ -435,15 +392,10 @@ const da = {
|
||||
'window_title_open': undefined, // In English: "Open"
|
||||
'window_title_change_password': undefined, // In English: "Change Password"
|
||||
'window_title_select_font': undefined, // In English: "Select font…"
|
||||
'window_title_session_list': undefined, // In English: "Session List!"
|
||||
'window_title_set_new_password': undefined, // In English: "Set New Password"
|
||||
'window_title_publish_website': undefined, // In English: "Publish Website"
|
||||
'window_title_publish_worker': undefined, // In English: "Publish Worker"
|
||||
'window_title_authenticating': undefined, // In English: "Authenticating..."
|
||||
'window_title_refer_friend': undefined, // In English: "Refer a friend!"
|
||||
'desktop_exit_full_screen': undefined, // In English: "Exit Full Screen"
|
||||
'desktop_enter_full_screen': undefined, // In English: "Enter Full Screen"
|
||||
'item_shared_with_you': undefined, // In English: "A user has shared this item with you."
|
||||
'item_shared_by_you': undefined, // In English: "You have shared this item with at least one other user."
|
||||
'item_shortcut': undefined, // In English: "Shortcut"
|
||||
'item_associated_websites': undefined, // In English: "Associated website"
|
||||
@@ -452,9 +404,6 @@ const da = {
|
||||
'window_click_to_go_back': undefined, // In English: "Click to go back."
|
||||
'window_click_to_go_forward': undefined, // In English: "Click to go forward."
|
||||
'window_click_to_go_up': undefined, // In English: "Click to go one directory up."
|
||||
'window_title_public': undefined, // In English: "Public"
|
||||
'window_title_videos': undefined, // In English: "Videos"
|
||||
'window_title_pictures': undefined, // In English: "Pictures"
|
||||
'window_title_puter': undefined, // In English: "Puter"
|
||||
'window_folder_empty': undefined, // In English: "This folder is empty"
|
||||
|
||||
|
||||
@@ -31,7 +31,6 @@ const de = {
|
||||
allow: 'Erlauben',
|
||||
ascending: 'Aufsteigend',
|
||||
associated_websites: 'Zugeordnete Webseiten',
|
||||
auto_arrange: 'Automatisch anordnen',
|
||||
cancel: 'Abbrechen',
|
||||
change_email: 'E-Mail ändern',
|
||||
change_language: 'Sprache ändern',
|
||||
@@ -40,17 +39,10 @@ const de = {
|
||||
close: 'Schließen',
|
||||
close_all_windows_and_log_out: 'Fenster schließen und abmelden',
|
||||
change_always_open_with: 'Öffnen Sie diesen Dateityp immer mit',
|
||||
confirm_2fa_setup: 'Ich habe den Code in meine Authentifizierungs-App eingegeben',
|
||||
confirm_2fa_recovery: 'Ich habe meine Wiederherstellungscodes an einem sicheren Ort gespeichert',
|
||||
confirm_account_for_free_referral_storage_c2a: 'Erstellen Sie ein Konto und bestätigen Sie Ihre E-Mail-Adresse, um 1 GB kostenlosen Speicherplatz zu erhalten. Ihr Freund erhält ebenfalls 1 GB kostenlosen Speicherplatz.',
|
||||
confirm_code_generic_incorrect: 'Falscher Code.',
|
||||
confirm_code_generic_too_many_requests: 'Zu viele Anfragen. Bitte warten Sie ein paar Minuten.',
|
||||
confirm_code_generic_submit: 'Code einreichen',
|
||||
confirm_code_generic_try_again: 'Erneut versuchen',
|
||||
confirm_code_generic_title: 'Bestätigungscode eingeben',
|
||||
confirm_code_2fa_instruction: 'Geben Sie den 6-stelligen Code aus Ihrer Authentifizierungs-App ein.',
|
||||
confirm_code_2fa_submit_btn: 'Einreichen',
|
||||
confirm_code_2fa_title: '2FA-Code eingeben',
|
||||
confirm_delete_multiple_items: 'Möchten Sie diese Elemente dauerhaft löschen?',
|
||||
confirm_delete_single_item: 'Möchten Sie dieses Element dauerhaft löschen?',
|
||||
confirm_open_apps_log_out: 'Sie haben geöffnete Apps. Möchten Sie sich wirklich abmelden?',
|
||||
@@ -60,7 +52,6 @@ const de = {
|
||||
confirm_session_revoke: 'Möchten Sie diese Sitzung wirklich widerrufen?',
|
||||
confirm_your_email_address: 'Bestätigen Sie Ihre E-Mail-Adresse',
|
||||
contact_us: 'Kontaktieren Sie uns',
|
||||
contact_us_verification_required: 'Sie müssen eine verifizierte E-Mail-Adresse haben, um dies zu verwenden.',
|
||||
continue: 'Weiter',
|
||||
copy: 'Kopieren',
|
||||
copy_link: 'Link kopieren',
|
||||
@@ -82,17 +73,13 @@ const de = {
|
||||
deploy_as_app: 'Als App bereitstellen',
|
||||
descending: 'Absteigend',
|
||||
desktop: 'Desktop',
|
||||
desktop_background_fit: 'Passend',
|
||||
developers: 'Entwickler',
|
||||
dir_published_as_website: '%strong% wurde veröffentlicht unter:',
|
||||
disable_2fa: '2FA deaktivieren',
|
||||
disable_2fa_confirm: 'Möchten Sie 2FA wirklich deaktivieren?',
|
||||
disable_2fa_instructions: 'Geben Sie Ihr Passwort ein, um 2FA zu deaktivieren.',
|
||||
documents: 'Dokumente',
|
||||
dont_allow: 'Nicht erlauben',
|
||||
download: 'Herunterladen',
|
||||
download_file: 'Datei herunterladen',
|
||||
downloading: 'Lädt herunter',
|
||||
email: 'E-Mail',
|
||||
email_change_confirmation_sent: 'Eine Bestätigungs-E-Mail wurde an Ihre neue E-Mail-Adresse gesendet. Bitte überprüfen Sie Ihren Posteingang und folgen Sie den Anweisungen, um den Vorgang abzuschließen.',
|
||||
email_invalid: 'E-Mail ist ungültig.',
|
||||
@@ -117,13 +104,10 @@ const de = {
|
||||
forgot_pass_c2a: 'Passwort vergessen?',
|
||||
from: 'Von',
|
||||
general: 'Allgemein',
|
||||
get_a_copy_of_on_puter: 'Holen Sie sich eine Kopie von \'%%\' auf Puter.com!',
|
||||
get_copy_link: 'Kopierlink erhalten',
|
||||
home: 'Startseite',
|
||||
html_document: 'HTML-Dokument',
|
||||
hue: 'Farbton',
|
||||
incorrect_password: 'Falsches Passwort',
|
||||
invite_link: 'Einladungslink',
|
||||
item: 'Element',
|
||||
items_in_trash_cannot_be_renamed: 'Dieses Element kann nicht umbenannt werden, da es sich im Papierkorb befindet. Um dieses Element umzubenennen, ziehen Sie es zunächst aus dem Papierkorb.',
|
||||
jpeg_image: 'JPEG-Bild',
|
||||
@@ -134,7 +118,6 @@ const de = {
|
||||
loading: 'Laden',
|
||||
log_in: 'Anmelden',
|
||||
log_out: 'Abmelden',
|
||||
looks_good: 'Sieht gut aus!',
|
||||
manage_sessions: 'Sitzungen verwalten',
|
||||
modified: 'Geändert',
|
||||
move: 'Verschieben',
|
||||
@@ -159,7 +142,6 @@ const de = {
|
||||
open_with: 'Öffnen mit',
|
||||
original_name: 'Originalname',
|
||||
original_path: 'Originalpfad',
|
||||
oss_code_and_content: 'Open-Source-Software und Inhalte',
|
||||
password: 'Passwort',
|
||||
password_changed: 'Passwort geändert.',
|
||||
password_recovery_rate_limit: 'Sie haben unser Limit erreicht; bitte warten Sie ein paar Minuten. Um dies in Zukunft zu vermeiden, laden Sie die Seite nicht zu oft neu.',
|
||||
@@ -171,26 +153,19 @@ const de = {
|
||||
paste: 'Einfügen',
|
||||
paste_into_folder: 'In Ordner einfügen',
|
||||
path: 'Pfad',
|
||||
personalization: 'Personalisierung',
|
||||
pick_name_for_website: 'Wählen Sie einen Namen für Ihre Webseite:',
|
||||
pictures: 'Bilder',
|
||||
plural_suffix: 's',
|
||||
powered_by_puter_js: 'Betrieben von {{link=docs}}Puter.js{{/link}}',
|
||||
preparing: 'Bereite vor...',
|
||||
preparing_for_upload: 'Vorbereiten zum Hochladen...',
|
||||
print: 'Drucken',
|
||||
privacy: 'Datenschutz',
|
||||
proceed_to_login: 'Zum Login fortfahren',
|
||||
proceed_with_account_deletion: 'Konto löschen',
|
||||
properties: 'Eigenschaften',
|
||||
public: 'Öffentlich',
|
||||
publish: 'Veröffentlichen',
|
||||
publish_as_website: 'Als Webseite veröffentlichen',
|
||||
puter_description: 'Puter ist eine datenschutzorientierte persönliche Cloud, um alle Ihre Dateien, Apps und Spiele an einem sicheren Ort zu speichern, von überall und jederzeit zugänglich.',
|
||||
reading_file: 'Lesen von %strong%',
|
||||
recover_password: 'Passwort wiederherstellen',
|
||||
refer_friends_c2a: 'Erhalten Sie 1 GB für jeden Freund, der ein Konto auf Puter erstellt und bestätigt. Ihr Freund erhält ebenfalls 1 GB!',
|
||||
refer_friends_social_media_c2a: 'Erhalten Sie 1 GB kostenlosen Speicherplatz auf Puter.com!',
|
||||
refresh: 'Aktualisieren',
|
||||
rename: 'Umbenennen',
|
||||
replace: 'Ersetzen',
|
||||
@@ -200,11 +175,9 @@ const de = {
|
||||
save: 'Speichern',
|
||||
saturation: 'Sättigung',
|
||||
save_account: 'Konto speichern',
|
||||
save_account_to_get_copy_link: 'Bitte erstellen Sie ein Konto, um fortzufahren.',
|
||||
save_account_to_publish: 'Bitte erstellen Sie ein Konto, um fortzufahren.',
|
||||
save_session: 'Sitzung speichern',
|
||||
save_session_c2a: 'Erstellen Sie ein Konto, um Ihre aktuelle Sitzung zu speichern um den Verlust Ihrer Arbeit zu verhindern.',
|
||||
scan_qr_2fa: 'Scannen Sie den QR-Code mit Ihrer Authentifizierungs-App',
|
||||
search: 'Suchen',
|
||||
seconds: 'Sekunden',
|
||||
security: 'Sicherheit',
|
||||
@@ -222,13 +195,11 @@ const de = {
|
||||
show_hidden: 'Zeige versteckte',
|
||||
sign_in_with_puter: 'Mit Puter anmelden',
|
||||
sign_up: 'Registrieren',
|
||||
signing_in: 'Anmelden…',
|
||||
size: 'Größe',
|
||||
skip: 'Überspringen',
|
||||
something_went_wrong: 'Etwas ist schief gelaufen.',
|
||||
sort_by: 'Sortieren nach',
|
||||
status: 'Status',
|
||||
storage_usage: 'Speichernutzung',
|
||||
storage_puter_used: 'Verwendet von Puter',
|
||||
taking_longer_than_usual: 'Es dauert etwas länger als gewöhnlich. Bitte warten...',
|
||||
terms: 'Bedingungen',
|
||||
@@ -256,29 +227,23 @@ const de = {
|
||||
videos: 'Videos',
|
||||
visibility: 'Sichtbarkeit',
|
||||
yes: 'Ja',
|
||||
you_have_been_referred_to_puter_by_a_friend: 'Sie wurden von einem Freund an Puter verwiesen!',
|
||||
zip: 'Verpacken',
|
||||
zipping_file: 'Verpacken von %strong%',
|
||||
|
||||
// === 2FA Setup ===
|
||||
setup2fa_1_step_heading: 'Öffnen Sie Ihre Authentifizierungs-App',
|
||||
setup2fa_1_instructions: `
|
||||
Sie können jede Authentifizierungs-App verwenden, die das Time-based One-Time Password (TOTP) Protokoll unterstützt.
|
||||
Es gibt viele zur Auswahl, aber wenn Sie unsicher sind, ist
|
||||
<a target="_blank" href="https://authy.com/download">Authy</a>
|
||||
eine solide Wahl für Android und iOS.
|
||||
`,
|
||||
setup2fa_2_step_heading: 'Scannen Sie den QR-Code',
|
||||
setup2fa_3_step_heading: 'Geben Sie den 6-stelligen Code ein',
|
||||
setup2fa_4_step_heading: 'Kopieren Sie Ihre Wiederherstellungscodes',
|
||||
setup2fa_4_instructions: `
|
||||
Diese Wiederherstellungscodes sind die einzige Möglichkeit, auf Ihr Konto zuzugreifen, wenn Sie Ihr Telefon verlieren oder Ihre Authentifizierungs-App nicht verwenden können.
|
||||
Stellen Sie sicher, dass Sie sie an einem sicheren Ort aufbewahren.
|
||||
`,
|
||||
setup2fa_5_step_heading: 'Bestätigen Sie die 2FA-Einrichtung',
|
||||
setup2fa_5_confirmation_1: 'Ich habe meine Wiederherstellungscodes an einem sicheren Ort gespeichert',
|
||||
setup2fa_5_confirmation_2: 'Ich bin bereit, 2FA zu aktivieren',
|
||||
setup2fa_5_button: '2FA aktivieren',
|
||||
|
||||
// === 2FA Login ===
|
||||
login2fa_otp_title: 'Geben Sie den 2FA-Code ein',
|
||||
@@ -286,7 +251,6 @@ const de = {
|
||||
login2fa_recovery_title: 'Geben Sie einen Wiederherstellungscode ein',
|
||||
login2fa_recovery_instructions: 'Geben Sie einen Ihrer Wiederherstellungscodes ein, um auf Ihr Konto zuzugreifen.',
|
||||
login2fa_use_recovery_code: 'Verwenden Sie einen Wiederherstellungscode',
|
||||
login2fa_recovery_back: 'Zurück',
|
||||
login2fa_recovery_placeholder: 'XXXXXXXX',
|
||||
|
||||
'change': 'Ändern', // In English: "Change"
|
||||
@@ -351,20 +315,13 @@ const de = {
|
||||
'billing.expanded': 'Erweitert', // In English: "Expanded"
|
||||
'billing.accelerated': 'Beschleunigt', // In English: "Accelerated"
|
||||
'billing.enjoy_msg': 'Genießen Sie %% des Cloud-Speichers und weitere Vorteile.', // In English: "Enjoy %% of Cloud Storage plus other benefits."
|
||||
'choose_publishing_option': 'Wählen Sie, wie Sie Ihre Website veröffentlichen möchten', // In English: "Choose how you want to publish your website:"
|
||||
'create_desktop_shortcut': 'Verknüpfung erstellen (Desktop)', // In English: "Create Shortcut (Desktop)"
|
||||
'create_desktop_shortcut_s': 'Verknüpfungen erstellen (Desktop)', // In English: "Create Shortcuts (Desktop)"
|
||||
'create_shortcut_s': 'Verknüpfungen erstellen', // In English: "Create Shortcuts"
|
||||
'minimize': 'Minimieren', // In English: "Minimize"
|
||||
'reload_app': 'App neu laden', // In English: "Reload App"
|
||||
'publish_as_serverless_worker': 'Als Worker veröffentlichen', // In English: "Publish as Worker"
|
||||
'toolbar.enter_fullscreen': 'Vollbildmodus aktivieren', // In English: "Enter Full Screen"
|
||||
'toolbar.github': 'GitHub', // In English: "GitHub"
|
||||
'toolbar.refer': 'Empfehlen', // In English: "Refer"
|
||||
'used_of': '{{used}} verwendet von {{available}} ', // In English: "{{used}} used of {{available}}"
|
||||
'worker': 'Worker', // In English: "Worker"
|
||||
'billing.offering.basic': 'Basic', // In English: "Basic"
|
||||
'too_many_attempts': 'Zu viele Versuche. Bitte versuchen Sie es später erneut.', // In English: "Too many attempts. Please try again later."
|
||||
'server_timeout': 'Die Antwort des Servers hat zu lange gedauert. Bitte versuchen Sie es erneut.', // In English: "The server took too long to respond. Please try again."
|
||||
'signup_error': 'Bei der Anmeldung ist ein Fehler aufgetreten. Versuchen Sie es bitte noch einmal.', // In English: "An error occurred during signup. Please try again."
|
||||
'alert_error_title': 'Fehler', // In English: "Error!"
|
||||
@@ -382,15 +339,10 @@ const de = {
|
||||
'window_title_open': 'Öffnen', // In English: "Open"
|
||||
'window_title_change_password': 'Kennwort ändern', // In English: "Change Password"
|
||||
'window_title_select_font': 'Schriftart auswählen…', // In English: "Select font…"
|
||||
'window_title_session_list': 'Sitzungsliste!', // In English: "Session List!"
|
||||
'window_title_set_new_password': 'Neues Passwort festlegen', // In English: "Set New Password"
|
||||
'window_title_publish_website': 'Website veröffentlichen', // In English: "Publish Website"
|
||||
'window_title_publish_worker': 'Veröffentlichungsmitarbeiter', // In English: "Publish Worker"
|
||||
'window_title_authenticating': 'Authentifizierung...', // In English: "Authenticating..."
|
||||
'window_title_refer_friend': 'Empfehlen Sie uns weiter!', // In English: "Refer a friend!"
|
||||
'desktop_exit_full_screen': 'Vollbildmodus beenden', // In English: "Exit Full Screen"
|
||||
'desktop_enter_full_screen': 'Vollbildmodus aktivieren', // In English: "Enter Full Screen"
|
||||
'item_shared_with_you': 'Ein Benutzer hat diesen Artikel mit Ihnen geteilt.', // In English: "A user has shared this item with you."
|
||||
'item_shared_by_you': 'Sie haben diesen Artikel mit mindestens einem anderen Benutzer geteilt.', // In English: "You have shared this item with at least one other user."
|
||||
'item_shortcut': 'Verknüpfung', // In English: "Shortcut"
|
||||
'item_associated_websites': 'Zugehörige Website', // In English: "Associated website"
|
||||
@@ -399,9 +351,6 @@ const de = {
|
||||
'window_click_to_go_back': 'Klicken Sie hier, um zurückzugehen.', // In English: "Click to go back."
|
||||
'window_click_to_go_forward': 'Klicken Sie, um fortzufahren.', // In English: "Click to go forward."
|
||||
'window_click_to_go_up': 'Klicken Sie, um ein Verzeichnis nach oben zu gehen.', // In English: "Click to go one directory up."
|
||||
'window_title_public': 'Öffentlich', // In English: "Public"
|
||||
'window_title_videos': 'Videos', // In English: "Videos"
|
||||
'window_title_pictures': 'Bilder', // In English: "Pictures"
|
||||
'window_title_puter': 'Puter', // In English: "Puter"
|
||||
'window_folder_empty': 'Dieser Ordner ist leer', // In English: "This folder is empty"
|
||||
},
|
||||
|
||||
@@ -26,7 +26,6 @@ const emoji = {
|
||||
add_another_account: '➕👤',
|
||||
all_fields_required: '📝🔒✅',
|
||||
ascending: '🔼',
|
||||
auto_arrange: '🔄📂📄',
|
||||
cancel: '❌',
|
||||
change_language: '🔄🌐',
|
||||
change_password: '🔑🔄',
|
||||
@@ -52,11 +51,8 @@ const emoji = {
|
||||
delete_permanently: '🗑️🔚',
|
||||
deploy_as_app: '🚀📱',
|
||||
descending: '🔽',
|
||||
desktop_background_fit: '🖥️🖼️',
|
||||
dir_published_as_website: '📂📰🌐',
|
||||
download: '⬇️',
|
||||
download_file: '⬇️📄',
|
||||
downloading: '⬇️➡️',
|
||||
email: '📧',
|
||||
email_or_username: '📧👤',
|
||||
empty_trash: '🗑️🆓',
|
||||
@@ -68,10 +64,7 @@ const emoji = {
|
||||
forgot_pass_c2a: '🔑❓📧',
|
||||
from: '📩',
|
||||
general: '⚙️',
|
||||
get_a_copy_of_on_puter: '📩🔄📂',
|
||||
get_copy_link: '🔗🔄',
|
||||
html_document: '📄🌐',
|
||||
invite_link: '🔗📩',
|
||||
item: '📂',
|
||||
items_in_trash_cannot_be_renamed: '🗑️🆓❌',
|
||||
jpeg_image: '🖼️',
|
||||
@@ -102,10 +95,7 @@ const emoji = {
|
||||
passwords_do_not_match: '🔑❌🔑',
|
||||
paste: '📋➡️',
|
||||
paste_into_folder: '📋➡️📂',
|
||||
pick_name_for_website: '🌐📛❓:',
|
||||
powered_by_puter_js: '⚙️🔌🔗',
|
||||
preparing: '🔄🔜',
|
||||
preparing_for_upload: '🔄🔜',
|
||||
proceed_to_login: '👤🔍',
|
||||
properties: '⚙️',
|
||||
publish: '📰',
|
||||
@@ -113,7 +103,6 @@ const emoji = {
|
||||
plural_suffix: '🅰️',
|
||||
recover_password: '📧🔑🔄', // Flow correction
|
||||
refer_friends_c2a: '👤📞📧👤',
|
||||
refer_friends_social_media_c2a: '📲👤🆓',
|
||||
refresh: '🔄🔄',
|
||||
rename: '🔄📛',
|
||||
replace: '🔄🔄',
|
||||
@@ -121,7 +110,6 @@ const emoji = {
|
||||
resend_confirmation_code: '📧🔁',
|
||||
restore: '🔄🔙',
|
||||
save_account: '👤💾',
|
||||
save_account_to_get_copy_link: '💾👤🔗',
|
||||
save_account_to_publish: '💾👤📰',
|
||||
save_session: '💾📂',
|
||||
save_session_c2a: '💾👤🔄',
|
||||
@@ -135,7 +123,6 @@ const emoji = {
|
||||
show_hidden: '👁️🔄',
|
||||
sign_in_with_puter: '👤🆔',
|
||||
sign_up: '👤🆕',
|
||||
signing_in: '🔄👤',
|
||||
size: '📏',
|
||||
skip: '⏩',
|
||||
sort_by: '🔢🔄',
|
||||
@@ -152,7 +139,6 @@ const emoji = {
|
||||
username_changed: '👤✅',
|
||||
versions: '🔄📃',
|
||||
yes: '✅',
|
||||
you_have_been_referred_to_puter_by_a_friend: '👤👫🔁🆓',
|
||||
zip: '📂🔒',
|
||||
},
|
||||
};
|
||||
|
||||
@@ -67,11 +67,9 @@ const en = {
|
||||
app_launch_no_access_unnamed: "You don't have access to this app.",
|
||||
ascending: 'Ascending',
|
||||
associated_websites: 'Associated Websites',
|
||||
auto_arrange: 'Auto Arrange',
|
||||
back: 'Back',
|
||||
bio: 'Bio',
|
||||
browser: 'Browser',
|
||||
browser_version: 'Browser Version',
|
||||
captcha_required: 'Please complete the CAPTCHA verification',
|
||||
cancel: 'Cancel',
|
||||
change: 'Change',
|
||||
@@ -83,28 +81,19 @@ const en = {
|
||||
change_username: 'Change Username',
|
||||
username_set_by_team: 'Set by {{team}}. Ask an admin to change it.',
|
||||
username_set_by_team_generic: 'Set by your team. Ask an admin to change it.',
|
||||
revalidate_with_google: 'Re-validate with Google',
|
||||
revalidated: 'Re-validated.',
|
||||
revalidate_sign_in_popup: 'Sign in with your linked account in the popup.',
|
||||
revalidate_flow_notice: 'You will be asked to sign in with your linked account when you continue.',
|
||||
revalidate_failed: 'Signing in with your linked account didn\u2019t finish. Please try again.',
|
||||
reauth_required_message: 'Your session was updated for security — please sign in again.',
|
||||
color_depth: 'Color Depth',
|
||||
close: 'Close',
|
||||
close_all_windows_and_log_out: 'Close Windows and Log Out',
|
||||
close_menu: 'Close menu',
|
||||
collapse_sidebar: 'Collapse sidebar',
|
||||
confirm: 'Confirm',
|
||||
confirm_2fa_setup: 'I have added the code to my authenticator app',
|
||||
confirm_2fa_recovery: 'I have saved my recovery codes in a secure location',
|
||||
confirm_code_generic_incorrect: 'Incorrect Code.',
|
||||
confirm_code_generic_too_many_requests: 'Too many requests. Please wait a few minutes.',
|
||||
confirm_code_generic_submit: 'Submit Code',
|
||||
confirm_code_generic_try_again: 'Try Again',
|
||||
confirm_code_generic_title: 'Enter Confirmation Code',
|
||||
confirm_code_2fa_instruction: 'Enter the 6-digit code from your authenticator app.',
|
||||
confirm_code_2fa_submit_btn: 'Submit',
|
||||
confirm_code_2fa_title: 'Enter 2FA Code',
|
||||
confirm_continue_as: 'Continue as <strong>{{username}}</strong>?<p>This link signs you in to that account. Anything you create — files, uploads, chats — will be saved there and visible to whoever owns it. Only continue if the account is yours.</p>',
|
||||
confirm_delete_multiple_items: 'Are you sure you want to permanently delete these items?',
|
||||
confirm_delete_single_item: 'Do you want to permanently delete this item?',
|
||||
@@ -117,7 +106,6 @@ const en = {
|
||||
confirm_events_worker_destroy: 'Are you sure you want to destroy this background worker? Its published event handlers will be removed, and any subscriptions using them will be suspended.',
|
||||
confirm_revoke_all_other_sessions: 'Revoke all other sessions? You will stay signed in here.',
|
||||
confirm_your_email_address: 'Confirm Your Email Address',
|
||||
choose_publishing_option: 'Choose how you want to publish your website:',
|
||||
contact_us: 'Contact Us',
|
||||
contact_us_attach: 'Attach Files',
|
||||
contact_us_attach_or_drop: 'Attach files or drop them here',
|
||||
@@ -135,7 +123,6 @@ const en = {
|
||||
contact_us_message_placeholder: 'How can we help? For a bug, the steps that lead to it help us most.',
|
||||
contact_us_message_required: 'Please write a message before sending.',
|
||||
contact_us_rate_limited: 'You have sent a lot of messages recently. Please try again later.',
|
||||
contact_us_verification_required: 'You must have a verified email address to use this.',
|
||||
continue: 'Continue',
|
||||
copied: 'Copied',
|
||||
copy: 'Copy',
|
||||
@@ -143,13 +130,10 @@ const en = {
|
||||
copying: 'Copying',
|
||||
copying_file: 'Copying %%',
|
||||
cost: 'Cost',
|
||||
cpu_cores: 'CPU Cores',
|
||||
cpu: 'CPU',
|
||||
create_account: 'Create Account',
|
||||
create_free_account: 'Create Free Account',
|
||||
change_icon: 'Change Icon',
|
||||
create_desktop_shortcut: 'Create Shortcut (Desktop)',
|
||||
create_desktop_shortcut_s: 'Create Shortcuts (Desktop)',
|
||||
create_shortcut: 'Create Shortcut',
|
||||
create_shortcut_s: 'Create Shortcuts',
|
||||
credits: 'Credits',
|
||||
@@ -202,7 +186,6 @@ const en = {
|
||||
custom_domain_use: 'Use',
|
||||
custom_domain_verify_and_add: 'Verify and Add',
|
||||
cut: 'Cut',
|
||||
client_information: 'Client Information',
|
||||
close_all: 'Close All',
|
||||
created: 'Created',
|
||||
date_modified: 'Date modified',
|
||||
@@ -213,28 +196,20 @@ const en = {
|
||||
deploy_as_app: 'Deploy as app',
|
||||
descending: 'Descending',
|
||||
desktop: 'Desktop',
|
||||
desktop_background_fit: 'Fit',
|
||||
developers: 'Developers',
|
||||
dir_published_as_website: '%strong% has been published to:',
|
||||
directory_depth_limit_exceeded: 'This folder is nested too deeply. Move it somewhere closer to the top before adding more folders inside it.',
|
||||
disable_2fa: 'Disable 2FA',
|
||||
disable_2fa_confirm: 'Are you sure you want to disable 2FA?',
|
||||
disable_2fa_instructions: 'Confirm your identity and enter an authenticator code or an unused recovery code to disable 2FA.',
|
||||
disable_2fa_code_instruction: 'Enter a 6-digit authenticator code or an unused recovery code.',
|
||||
display_name: 'Display Name',
|
||||
directory: 'Directory',
|
||||
disassociate: 'disassociate',
|
||||
disk_storage: 'Disk Storage',
|
||||
documents: 'Documents',
|
||||
done: 'Done',
|
||||
dont_allow: 'Don\'t Allow',
|
||||
download: 'Download',
|
||||
confirm_download_file_to_desktop: 'Are you sure you want to download %% to your Desktop?',
|
||||
download_file: 'Download File',
|
||||
downloading: 'Downloading',
|
||||
downloading_file: 'Downloading %%',
|
||||
drag_to_reposition: 'Drag to reposition',
|
||||
error_download_failed: 'Failed to download file',
|
||||
email: 'Email',
|
||||
email_change_confirmation_sent: 'A confirmation email has been sent to your new email address. Please check your inbox and follow the instructions to complete the process.',
|
||||
email_invalid: 'Email is invalid.',
|
||||
@@ -266,14 +241,11 @@ const en = {
|
||||
forgot_pass_c2a: 'Forgot password?',
|
||||
from: 'From',
|
||||
general: 'General',
|
||||
get_a_copy_of_on_puter: 'Get a copy of \'%%\' on Puter.com!',
|
||||
get_copy_link: 'Get Copy Link',
|
||||
hide_password: 'Hide password',
|
||||
home: 'Home',
|
||||
html_document: 'HTML document',
|
||||
hue: 'Hue',
|
||||
incorrect_password: 'Incorrect password',
|
||||
invite_link: 'Invite Link',
|
||||
item: 'item',
|
||||
items_count_one: '1 item',
|
||||
items_count_other: '{{count}} items',
|
||||
@@ -300,7 +272,6 @@ const en = {
|
||||
log_in: 'Log In',
|
||||
log_out: 'Log Out',
|
||||
logging_in_as: 'Logging in as <strong>{{identity}}</strong>',
|
||||
looks_good: 'Looks good!',
|
||||
manage_sessions: 'Manage Sessions',
|
||||
manage_sessions_hint: 'Manage active sessions',
|
||||
account_subtitle: 'Manage your account settings and profile',
|
||||
@@ -374,8 +345,6 @@ const en = {
|
||||
original_name: 'Original Name',
|
||||
original_path: 'Original Path',
|
||||
os: 'Operating System',
|
||||
oss_code_and_content: 'Open Source Software and Content',
|
||||
os_version: 'OS Version',
|
||||
password: 'Password',
|
||||
password_changed: 'Password changed.',
|
||||
password_recovery_rate_limit: "You've reached our rate-limit; please wait a few minutes. To prevent this in the future, avoid reloading the page too many times.",
|
||||
@@ -393,7 +362,6 @@ const en = {
|
||||
paste: 'Paste',
|
||||
paste_into_folder: 'Paste Into Folder',
|
||||
path: 'Path',
|
||||
personalization: 'Personalization',
|
||||
phone_verify_title: 'Verify your phone number',
|
||||
phone_verify_subtitle: "We'll text you a verification code to confirm it's really you.",
|
||||
phone_country_label: 'Country',
|
||||
@@ -420,17 +388,12 @@ const en = {
|
||||
phone_card_fallback_link: 'Verify with a card instead',
|
||||
phone_card_fallback_note: "We only check that the card is valid \u2014 you won't be charged.",
|
||||
phone_card_fallback_unavailable: "Card verification isn't available right now. Please try your phone number again, or email [email protected] and we'll help you finish setting up your account.",
|
||||
pick_name_for_website: 'Pick a name for your website:',
|
||||
pictures: 'Pictures',
|
||||
pixel_ratio: 'Pixel Ratio',
|
||||
plural_suffix: 's',
|
||||
powered_by_puter_js: 'Powered by {{link=docs}}Puter.js{{/link}}',
|
||||
preparing: 'Preparing...',
|
||||
preparing_for_upload: 'Preparing for upload...',
|
||||
print: 'Print',
|
||||
privacy: 'Privacy',
|
||||
proceed_to_login: 'Proceed to login',
|
||||
proceed_with_account_deletion: 'Proceed with Account Deletion',
|
||||
profile: 'Profile',
|
||||
profile_empty: 'Add a display name and bio',
|
||||
profile_picture_adjust_hint: 'Drag to reposition. Scroll or use the slider to zoom.',
|
||||
@@ -440,7 +403,6 @@ const en = {
|
||||
profile_picture_remove_failed: 'Your photo could not be removed. Please try again.',
|
||||
profile_picture_save_failed: 'Your photo could not be saved. Please try again.',
|
||||
profile_save_failed: 'Your profile could not be saved. Please try again.',
|
||||
profile_saved: 'Profile saved.',
|
||||
properties: 'Properties',
|
||||
public: 'Public',
|
||||
publish: 'Publish',
|
||||
@@ -495,12 +457,10 @@ const en = {
|
||||
push_this_browser: 'This browser',
|
||||
push_turn_off: 'Turn off',
|
||||
push_turn_on: 'Turn on',
|
||||
puter_description: 'Puter is a privacy-first personal cloud to keep all your files, apps, and games in one secure place, accessible from anywhere at any time.',
|
||||
ram: 'RAM',
|
||||
reading: 'Reading %strong%',
|
||||
writing: 'Writing %strong%',
|
||||
recover_password: 'Recover Password',
|
||||
refer_friends_social_media_c2a: 'Get 1 GB of free storage on Puter.com!',
|
||||
refresh: 'Refresh',
|
||||
remove_profile_picture: 'Remove photo',
|
||||
rename: 'Rename',
|
||||
@@ -518,13 +478,10 @@ const en = {
|
||||
save: 'Save',
|
||||
saturation: 'Saturation',
|
||||
save_account: 'Save account',
|
||||
save_account_to_get_copy_link: 'Please create an account to proceed.',
|
||||
save_account_to_proceed: 'Please create an account to proceed.',
|
||||
save_account_to_publish: 'Please create an account to proceed.',
|
||||
save_session: 'Save session',
|
||||
save_session_c2a: 'Create an account to save your current session and avoid losing your work.',
|
||||
scan_qr_2fa: 'Scan the QR code with your authenticator app',
|
||||
screen_resolution: 'Screen Resolution',
|
||||
search: 'Search',
|
||||
seconds: 'seconds',
|
||||
security: 'Security',
|
||||
@@ -533,31 +490,8 @@ const en = {
|
||||
sessions: 'Sessions',
|
||||
send: 'Send',
|
||||
send_password_recovery_email: 'Send Password Recovery Email',
|
||||
server_information: 'Server Information',
|
||||
session_saved: 'Thank you for creating an account. This session has been saved.',
|
||||
settings: 'Settings',
|
||||
keyboard_shortcuts: 'Keyboard Shortcuts',
|
||||
keyboard_shortcuts_intro: 'Learn the most useful shortcuts for navigating Puter faster.',
|
||||
keyboard_shortcuts_action: 'Action',
|
||||
keyboard_shortcuts_shortcut: 'Shortcut',
|
||||
keyboard_shortcuts_general: 'General',
|
||||
keyboard_shortcuts_navigation: 'Navigation',
|
||||
keyboard_shortcuts_files: 'Files & Clipboard',
|
||||
keyboard_shortcuts_open_help: 'Open this keyboard shortcuts guide',
|
||||
keyboard_shortcuts_search: 'Open search',
|
||||
keyboard_shortcuts_close_window: 'Close the active window',
|
||||
keyboard_shortcuts_undo: 'Undo last action',
|
||||
keyboard_shortcuts_select_all: 'Select all items',
|
||||
keyboard_shortcuts_open_item: 'Open selected item',
|
||||
keyboard_shortcuts_close_menus: 'Close dialogs, menus, and popovers',
|
||||
keyboard_shortcuts_arrow_navigation: 'Navigate menus and selections',
|
||||
keyboard_shortcuts_type_to_select: 'Type to jump to an item by name',
|
||||
keyboard_shortcuts_type_to_select_keys: 'Type letters or numbers',
|
||||
keyboard_shortcuts_copy: 'Copy selected items',
|
||||
keyboard_shortcuts_cut: 'Cut selected items',
|
||||
keyboard_shortcuts_paste: 'Paste items',
|
||||
keyboard_shortcuts_delete: 'Move selected items to Trash',
|
||||
keyboard_shortcuts_permanent_delete: 'Permanently delete (after confirmation)',
|
||||
set_new_password: 'Set New Password',
|
||||
share: 'Share',
|
||||
share_ellipsis: 'Share…',
|
||||
@@ -589,9 +523,7 @@ const en = {
|
||||
share_no_one: 'Not shared with anyone yet.',
|
||||
share_owner: 'Owner',
|
||||
share_remove_access: 'Remove access',
|
||||
share_remove_access_for: 'Remove access for {{recipient}}',
|
||||
share_remove_from_shared: 'Remove from Shared',
|
||||
share_nothing_shared: 'Nothing has been shared with you yet.',
|
||||
share_done: 'Done',
|
||||
share_failed: 'Could not share this item.',
|
||||
share_shared_with: 'Shared with {{recipient}}',
|
||||
@@ -601,7 +533,6 @@ const en = {
|
||||
share_awaiting_signup: 'Invited',
|
||||
share_invited_someone: 'Someone by email',
|
||||
share_cancel_invite: 'Cancel invitation',
|
||||
share_cancel_invite_for: 'Cancel the invitation to {{recipient}}',
|
||||
share_confirm_cancel_invite:
|
||||
'Cancel the invitation sent to {{recipient}}?',
|
||||
share_invite_cancelled: 'Invitation to {{recipient}} cancelled',
|
||||
@@ -693,14 +624,12 @@ const en = {
|
||||
sign_in: 'Sign in',
|
||||
sign_in_with_puter: 'Sign in with Puter',
|
||||
sign_up: 'Sign Up',
|
||||
signing_in: 'Signing in…',
|
||||
size: 'Size',
|
||||
skip: 'Skip',
|
||||
something_went_wrong: 'Something went wrong.',
|
||||
sort_by: 'Sort by',
|
||||
status: 'Status',
|
||||
'Storage': 'Storage',
|
||||
storage_usage: 'Storage Usage',
|
||||
storage_puter_used: 'used by Puter',
|
||||
'your_plan': 'Your Plan',
|
||||
teams_account_of: 'This account belongs to %%',
|
||||
@@ -743,9 +672,6 @@ const en = {
|
||||
terms: 'Terms',
|
||||
text_document: 'Text document',
|
||||
toggle_view: 'Toggle view',
|
||||
'toolbar.enter_fullscreen': 'Enter Full Screen',
|
||||
'toolbar.github': 'GitHub',
|
||||
'toolbar.refer': 'Refer',
|
||||
tos_fineprint: 'By signing up, you agree to Puter\'s {{link=terms}}Terms of Service{{/link}} and {{link=privacy}}Privacy Policy{{/link}}.',
|
||||
transparency: 'Transparency',
|
||||
trash: 'Trash',
|
||||
@@ -759,14 +685,11 @@ const en = {
|
||||
ui_revoke: 'Revoke',
|
||||
ui_revoke_all_other_sessions: 'Revoke all other sessions',
|
||||
ui_search: 'Search sessions…',
|
||||
ui_session_app: 'App',
|
||||
ui_session_client: 'Client',
|
||||
ui_session_count_one: '1 active session',
|
||||
ui_session_count_other: '%% active sessions',
|
||||
ui_session_created: 'Created',
|
||||
ui_session_current: 'Current',
|
||||
ui_session_expires: 'Expires',
|
||||
ui_session_ip: 'IP',
|
||||
ui_session_kind_access_token: 'Access token',
|
||||
ui_session_kind_app: 'App session',
|
||||
ui_session_kind_web: 'Browser session',
|
||||
@@ -783,7 +706,6 @@ const en = {
|
||||
untarring: 'Untarring %strong%',
|
||||
upload: 'Upload',
|
||||
uploading: 'Uploading',
|
||||
uploading_file: 'Uploading %%',
|
||||
upload_here: 'Upload here',
|
||||
uptime: 'Uptime',
|
||||
used_of: '{{used}} used of {{available}}',
|
||||
@@ -803,7 +725,6 @@ const en = {
|
||||
videos: 'Videos',
|
||||
visibility: 'Visibility',
|
||||
yes: 'Yes',
|
||||
you_have_been_referred_to_puter_by_a_friend: 'You have been referred to Puter by a friend!',
|
||||
zip: 'Zip',
|
||||
zoom: 'Zoom',
|
||||
zoom_in: 'Zoom in',
|
||||
@@ -820,21 +741,15 @@ const en = {
|
||||
tarring: 'Tarring %strong%',
|
||||
|
||||
// === 2FA Setup ===
|
||||
setup2fa_1_step_heading: 'Open your authenticator app',
|
||||
setup2fa_1_instructions: 'Scan the QR code with your authenticator app.',
|
||||
setup2fa_2_step_heading: 'Scan the QR code',
|
||||
setup2fa_3_step_heading: 'Enter the 6-digit code',
|
||||
setup2fa_4_step_heading: 'Copy your recovery codes',
|
||||
setup2fa_4_instructions: `
|
||||
These recovery codes are the only way to access your account if you lose your phone or can't use your authenticator app.
|
||||
Make sure to store them in a safe place.
|
||||
`,
|
||||
setup2fa_5_step_heading: 'Confirm 2FA setup',
|
||||
setup2fa_5_confirmation_1: 'I have saved my recovery codes in a secure location',
|
||||
setup2fa_5_confirmation_2: 'I am ready to enable 2FA',
|
||||
setup2fa_5_button: 'Enable 2FA',
|
||||
setup2fa_password_instructions: 'Enter your password to set up 2FA.',
|
||||
setup2fa_code_expired: 'That code has expired. Enter the current code from your authenticator app to finish.',
|
||||
setup2fa_step_scan: 'Scan',
|
||||
setup2fa_step_backup: 'Backup',
|
||||
setup2fa_step_verify: 'Verify',
|
||||
@@ -849,7 +764,6 @@ const en = {
|
||||
login2fa_recovery_title: 'Enter a recovery code',
|
||||
login2fa_recovery_instructions: 'Enter one of your recovery codes to access your account.',
|
||||
login2fa_use_recovery_code: 'Use a recovery code',
|
||||
login2fa_recovery_back: 'Back',
|
||||
login2fa_recovery_placeholder: 'XXXXXXXX',
|
||||
|
||||
// Sharing
|
||||
@@ -918,7 +832,6 @@ const en = {
|
||||
'billing.accelerated': 'Accelerated',
|
||||
'billing.enjoy_msg': 'Enjoy %% of Cloud Storage plus other benefits.',
|
||||
|
||||
'too_many_attempts': 'Too many attempts. Please try again later.',
|
||||
'server_timeout': 'The server took too long to respond. Please try again.',
|
||||
'signup_error': 'An error occurred during signup. Please try again.',
|
||||
'auth_error_generic': 'Authentication failed. Please try again.',
|
||||
@@ -969,18 +882,13 @@ const en = {
|
||||
'window_title_open': 'Open',
|
||||
'window_title_change_password': 'Change Password',
|
||||
'window_title_select_font': 'Select font…',
|
||||
'window_title_session_list': 'Session List!',
|
||||
'window_title_set_new_password': 'Set New Password',
|
||||
'window_title_publish_website': 'Publish Website',
|
||||
'window_title_publish_worker': 'Publish Worker',
|
||||
'window_title_authenticating': 'Authenticating...',
|
||||
'window_title_refer_friend': 'Refer a friend!',
|
||||
|
||||
// Desktop UI
|
||||
'desktop_exit_full_screen': 'Exit Full Screen',
|
||||
'desktop_enter_full_screen': 'Enter Full Screen',
|
||||
// Item UI
|
||||
'item_shared_with_you': 'A user has shared this item with you.',
|
||||
'item_shared_by_you': 'You have shared this item with at least one other user.',
|
||||
'item_shortcut': 'Shortcut',
|
||||
'item_already_exists': '%strong% already exists.',
|
||||
@@ -998,9 +906,6 @@ const en = {
|
||||
'window_click_to_go_forward': 'Click to go forward.',
|
||||
'window_click_to_go_up': 'Click to go one directory up.',
|
||||
'window_click_to_change_layout': 'Click to change the layout.',
|
||||
'window_title_public': 'Public',
|
||||
'window_title_videos': 'Videos',
|
||||
'window_title_pictures': 'Pictures',
|
||||
'window_title_puter': 'Puter',
|
||||
'window_folder_empty': 'This folder is empty',
|
||||
|
||||
@@ -1054,15 +959,11 @@ const en = {
|
||||
'enable_push_footnote': 'You can turn them off anytime in Settings.',
|
||||
|
||||
'error_user_or_path_not_found': 'User or path not found.',
|
||||
'error_invalid_username': 'Invalid username.',
|
||||
|
||||
// Auth token
|
||||
auth_token: 'Auth Token',
|
||||
token_copied: 'Token copied',
|
||||
copy_auth_token: 'Copy Auth Token',
|
||||
approve: 'Approve',
|
||||
copy_token_message: 'Your authentication token is shown below. Keep it secret \u2014 anyone with this token can access your account.',
|
||||
copy_token_description: 'View and copy your authentication token',
|
||||
|
||||
// API tokens (named, revocable, full API access \u2014 no account management)
|
||||
api_token: 'API Token',
|
||||
@@ -1088,10 +989,8 @@ const en = {
|
||||
// AuthMe dialog
|
||||
authorization_required: 'Authorization Required',
|
||||
external_site_auth_request: 'An app is requesting access to your account.',
|
||||
authme_security_warning: 'Your authentication token will be shared with this app to complete sign-in.',
|
||||
redirect_destination: 'Redirect Destination',
|
||||
will_be_shared: 'Will be shared',
|
||||
your_auth_token: 'Your authentication token',
|
||||
authorization_cancelled: 'Authorization Cancelled',
|
||||
authorization_cancelled_desc: 'You have declined the authorization request.',
|
||||
authorization_cancelled_message: 'The app will not receive access to your account. You can close this window safely.',
|
||||
|
||||
@@ -38,7 +38,6 @@ const es = {
|
||||
allow: 'Permitir',
|
||||
ascending: 'Ascendiente',
|
||||
associated_websites: 'Sitios Web Asociados',
|
||||
auto_arrange: 'Organización Automática',
|
||||
cancel: 'Cancelar',
|
||||
change_email: 'Cambiar Correo Electrónico',
|
||||
change_language: 'Cambiar Idioma',
|
||||
@@ -48,21 +47,13 @@ const es = {
|
||||
close_all_windows_and_log_out: 'Cerrar ventanas y cerrar sesión',
|
||||
change_always_open_with: '¿Quieres abrir siempre este tipo de archivos con',
|
||||
confirm: 'Confirmar',
|
||||
confirm_2fa_setup: 'He añadido el código a mi aplicación de autenticación',
|
||||
confirm_2fa_recovery:
|
||||
'He guardado mis códigos de recuperación en un lugar seguro',
|
||||
confirm_account_for_free_referral_storage_c2a:
|
||||
'Crea una cuenta y confirma tu correo electrónico para recibir 1 GB de almacenamiento gratuito. Tu amigo recibirá 1 GB de almacenamiento gratuito también.',
|
||||
confirm_code_generic_incorrect: 'Código incorrecto.',
|
||||
confirm_code_generic_too_many_requests:
|
||||
'Too many requests. Please wait a few minutes.',
|
||||
confirm_code_generic_submit: 'Enviar código',
|
||||
confirm_code_generic_try_again: 'Intenta nuevamente',
|
||||
confirm_code_generic_title: 'Enter Confirmation Code',
|
||||
confirm_code_2fa_instruction:
|
||||
'Ingresa los 6 dígitos de tu aplicación de autenticación.',
|
||||
confirm_code_2fa_submit_btn: 'Enviar',
|
||||
confirm_code_2fa_title: 'Ingrese el código de 2FA',
|
||||
confirm_delete_multiple_items:
|
||||
'¿Estás seguro de que quieres eliminar permanentemente estos elementos?',
|
||||
confirm_delete_single_item:
|
||||
@@ -76,8 +67,6 @@ const es = {
|
||||
confirm_session_revoke: '¿Estás seguro de que quieres revocar esta sesión?',
|
||||
confirm_your_email_address: 'Confirma tu dirección de correo electrónico',
|
||||
contact_us: 'Contáctanos',
|
||||
contact_us_verification_required:
|
||||
'Debes tener un correo electrónico verificado para usar esto.',
|
||||
continue: 'Continuar',
|
||||
copy: 'Copiar',
|
||||
copy_link: 'Copiar Enlace',
|
||||
@@ -99,17 +88,13 @@ const es = {
|
||||
deploy_as_app: 'Desplegar como una aplicación',
|
||||
descending: 'Descendiente',
|
||||
desktop: 'Escritorio',
|
||||
desktop_background_fit: 'Ajustar',
|
||||
developers: 'Desarrolladores',
|
||||
dir_published_as_website: '%strong% ha sido publicado en:',
|
||||
disable_2fa: 'Deshabilitar 2FA',
|
||||
disable_2fa_confirm: '¿Estás seguro que quieres deshabilitar 2FA?',
|
||||
disable_2fa_instructions: 'Ingresa tu contraseña para deshabilitar 2FA.',
|
||||
documents: 'Documentos',
|
||||
dont_allow: 'No permitir',
|
||||
download: 'Descargar',
|
||||
download_file: 'Descargar archivo',
|
||||
downloading: 'Descargando',
|
||||
email: 'Correo electrónico',
|
||||
email_change_confirmation_sent:
|
||||
'Se ha enviado un mensaje de confirmación a tu nueva dirección de correo electrónico. Por favor, revisa tu bandeja de entrada y sigue las instrucciónes para completar el proceso.',
|
||||
@@ -138,13 +123,10 @@ const es = {
|
||||
forgot_pass_c2a: '¿Olvidaste tu contraseña?',
|
||||
from: 'De',
|
||||
general: 'General',
|
||||
get_a_copy_of_on_puter: '¡Consigue una copia de \'%%\' en Puter.com!',
|
||||
get_copy_link: 'Copiar el enlace',
|
||||
home: 'Inicio',
|
||||
html_document: 'Documento HTML',
|
||||
hue: 'Hue',
|
||||
incorrect_password: 'Contraseña incorrecta',
|
||||
invite_link: 'Enlace de invitación',
|
||||
item: 'elemento',
|
||||
items_in_trash_cannot_be_renamed: 'Este elemento no se puede renombrar porque está en la papelera. Para cambiar el nombre de este archivo, primero extráelo fuera de la misma.',
|
||||
jpeg_image: 'Imagen JPEG',
|
||||
@@ -155,7 +137,6 @@ const es = {
|
||||
loading: 'Cargando',
|
||||
log_in: 'Iniciar sesión',
|
||||
log_out: 'Cerrar sesión',
|
||||
looks_good: 'Se ve bien!',
|
||||
manage_sessions: 'Administrar sesión',
|
||||
modified: 'Modified',
|
||||
move: 'Mover',
|
||||
@@ -181,7 +162,6 @@ const es = {
|
||||
open_with: 'Abrir con',
|
||||
original_name: 'Nombre original',
|
||||
original_path: 'Ruta original',
|
||||
oss_code_and_content: 'Software y contenido de código abierto',
|
||||
password: 'Contraseña',
|
||||
password_changed: 'Contraseña cambiada.',
|
||||
password_recovery_rate_limit:
|
||||
@@ -198,27 +178,20 @@ const es = {
|
||||
paste: 'Pegar',
|
||||
paste_into_folder: 'Pegar en la Carpeta',
|
||||
path: 'Ruta',
|
||||
personalization: 'Personalización',
|
||||
pick_name_for_website: 'Escoge un nombre para tu página web:',
|
||||
pictures: 'Imagenes',
|
||||
plural_suffix: 's',
|
||||
powered_by_puter_js: 'Creado por {{link=docs}}Puter.js{{/link}}',
|
||||
preparing: 'Preparando...',
|
||||
preparing_for_upload: 'Preparando para la subida...',
|
||||
print: 'Imprimir',
|
||||
privacy: 'Privacidad',
|
||||
proceed_to_login: 'Procede a iniciar sesión',
|
||||
proceed_with_account_deletion: 'Procede con la eliminación de la cuenta',
|
||||
properties: 'Propiedades',
|
||||
public: 'Publico',
|
||||
publish: 'Publicar',
|
||||
publish_as_website: 'Publicar como página web',
|
||||
puter_description: 'Puter es un servicio de nube personal enfocado en privacidad que mantiene tus archivos, aplicaciónes, y juegos en un solo lugar, accesible desde cualquier lugar en cualquier momento.',
|
||||
reading_file: 'Leyendo %strong%',
|
||||
recover_password: 'Recuperar Contraseña',
|
||||
refer_friends_c2a:
|
||||
'Consigue 1 GB por cada amigo que cree y confirme una cuenta en Puter ¡Tu amigo recibirá 1GB también!',
|
||||
refer_friends_social_media_c2a: '¡Consigue 1 GB de almacenamiento gratuito en Puter.com!',
|
||||
refresh: 'Refrescar',
|
||||
rename: 'Renombrar',
|
||||
replace: 'Remplazar',
|
||||
@@ -228,12 +201,10 @@ const es = {
|
||||
save: 'Guardar',
|
||||
saturation: 'Saturación',
|
||||
save_account: 'Guardar cuenta',
|
||||
save_account_to_get_copy_link: 'Por favor, crea una cuenta para continuar.',
|
||||
save_account_to_publish: 'Por favor, crea una cuenta para continuar.',
|
||||
save_session: 'Guardar sesión',
|
||||
save_session_c2a:
|
||||
'Crea una cuenta para guardar tu sesión actual y evitar así perder tu trabajo.',
|
||||
scan_qr_2fa: 'Escanee el codigo QR con su aplicación de autenticación',
|
||||
search: 'Buscar',
|
||||
seconds: 'segundos',
|
||||
security: 'Seguridad',
|
||||
@@ -252,13 +223,11 @@ const es = {
|
||||
show_hidden: 'Mostrar ocultos',
|
||||
sign_in_with_puter: 'Inicia sesión con Puter',
|
||||
sign_up: 'Registrarse',
|
||||
signing_in: 'Registrándose…',
|
||||
size: 'Tamaño',
|
||||
skip: 'Saltar',
|
||||
something_went_wrong: 'Algo salió mal.',
|
||||
sort_by: 'Ordenar Por',
|
||||
status: 'Estado',
|
||||
storage_usage: 'Uso del almacenamiento',
|
||||
storage_puter_used: 'Usado por Puter',
|
||||
taking_longer_than_usual:
|
||||
'Tardando un poco más de lo habitual. Por favor, espere...',
|
||||
@@ -288,31 +257,24 @@ const es = {
|
||||
videos: 'Videos',
|
||||
visibility: 'Visibilidad',
|
||||
yes: 'Si',
|
||||
you_have_been_referred_to_puter_by_a_friend:
|
||||
'¡Has sido invitado a Puter por un amigo!',
|
||||
zip: 'Zip',
|
||||
zipping_file: 'Compriminendo %strong%',
|
||||
|
||||
// === 2FA Setup ===
|
||||
setup2fa_1_step_heading: 'Abre tu aplicación de autenticación',
|
||||
setup2fa_1_instructions: `
|
||||
Puedes usar cualquier aplicación de autenticación que soporte el protocolo de Time-based One-time (TOTP).
|
||||
Hay muchos para elegir, pero si no estas seguro
|
||||
<a target="_blank" href="https://authy.com/download">Authy</a>
|
||||
es una opción segura para Android y iOS.
|
||||
`,
|
||||
setup2fa_2_step_heading: 'Escanea el código QR',
|
||||
setup2fa_3_step_heading: 'Ingresa el código de 6 dígitos',
|
||||
setup2fa_4_step_heading: 'Copiar tus códigos de recuperación',
|
||||
setup2fa_4_instructions: `
|
||||
Estos códigos de recuperación son la única forma de acceder a tu cuenta, si pierdes tu teléfono o no puedes usar la aplicación de autenticación.
|
||||
Asegurate de guardarlos en un lugar seguro.
|
||||
`,
|
||||
setup2fa_5_step_heading: 'Confirmar la configuración de 2FA',
|
||||
setup2fa_5_confirmation_1:
|
||||
'He guardado mis códigos de recuperación en un lugar seguro',
|
||||
setup2fa_5_confirmation_2: 'Estoy listo para habilitar 2FA',
|
||||
setup2fa_5_button: 'Habilitar 2FA',
|
||||
|
||||
// === 2FA Login ===
|
||||
login2fa_otp_title: 'Ingresar el código 2FA',
|
||||
@@ -322,7 +284,6 @@ const es = {
|
||||
login2fa_recovery_instructions:
|
||||
'Ingresa uno de tus códigos de recuperación para acceder a tu cuenta.',
|
||||
login2fa_use_recovery_code: 'Usar un código de recuperación',
|
||||
login2fa_recovery_back: 'Atras',
|
||||
login2fa_recovery_placeholder: 'XXXXXXXX',
|
||||
|
||||
change: 'cambiar', // In English: "Change"
|
||||
@@ -399,20 +360,13 @@ const es = {
|
||||
'billing.enjoy_msg':
|
||||
'Disfruta %% de almacenamiento en la nube junto con otros beneficios.', // In English: "Enjoy %% of Cloud Storage plus other benefits."
|
||||
|
||||
'choose_publishing_option': 'Elige cómo quieres publicar tu sitio web:', // In English: "Choose how you want to publish your website:"
|
||||
'create_desktop_shortcut': 'Crear un atajo (Escritorio)', // In English: "Create Shortcut (Desktop)"
|
||||
'create_desktop_shortcut_s': 'Crear atajos (Escritorio)', // In English: "Create Shortcuts (Desktop)"
|
||||
'create_shortcut_s': 'Crear atajos', // In English: "Create Shortcuts"
|
||||
'minimize': 'Minimizar', // In English: "Minimize"
|
||||
'reload_app': 'Recargar la Aplicación', // In English: "Reload App"
|
||||
'publish_as_serverless_worker': 'Publicar como un Worker', // In English: "Publish as Worker"
|
||||
'toolbar.enter_fullscreen': 'Abrir pantalla completa', // In English: "Enter Full Screen"
|
||||
'toolbar.github': 'GitHub', // In English: "GitHub"
|
||||
'toolbar.refer': 'Invitar', // In English: "Refer"
|
||||
'used_of': '{{used}} en uso. {{available}} disponible', // In English: "{{used}} used of {{available}}"
|
||||
'worker': 'Worker', // In English: "Worker"
|
||||
'billing.offering.basic': 'Básico', // In English: "Basic"
|
||||
'too_many_attempts': 'Demasiados intentos. Por favor, intenta más tarde', // In English: "Too many attempts. Please try again later."
|
||||
'server_timeout': 'El servidor ha tardado mucho en responder. Intenta nuevamente', // In English: "The server took too long to respond. Please try again."
|
||||
'signup_error': 'Ocurrió un error durante el registro. Intente nuevamente', // In English: "An error occurred during signup. Please try again."
|
||||
'alert_error_title': '¡Error!', // In English: "Error!"
|
||||
@@ -430,15 +384,10 @@ const es = {
|
||||
'window_title_open': 'Abrir', // In English: "Open"
|
||||
'window_title_change_password': 'Cambiar contraseña', // In English: "Change Password"
|
||||
'window_title_select_font': 'Seleccionar fuente…', // In English: "Select font…"
|
||||
'window_title_session_list': '¡Lista de sesiones!', // In English: "Session List!"
|
||||
'window_title_set_new_password': 'Establecer nueva contraseña', // In English: "Set New Password"
|
||||
'window_title_publish_website': 'Publicar sitio web', // In English: "Publish Website"
|
||||
'window_title_publish_worker': 'Publicar Worker', // In English: "Publish Worker"
|
||||
'window_title_authenticating': 'Autenticando...', // In English: "Authenticating..."
|
||||
'window_title_refer_friend': '¡Invitar a un amigo!', // In English: "Refer a friend!"
|
||||
'desktop_exit_full_screen': 'Salir de Pantalla Completa', // In English: "Exit Full Screen"
|
||||
'desktop_enter_full_screen': 'Abrir Pantalla Completa', // In English: "Enter Full Screen"
|
||||
'item_shared_with_you': 'Un usuario compartió este elemento contigo.', // In English: "A user has shared this item with you."
|
||||
'item_shared_by_you': 'Has compartido este elemento con otro usuario', // In English: "You have shared this item with at least one other user."
|
||||
'item_shortcut': 'Atajo', // In English: "Shortcut"
|
||||
'item_associated_websites': 'Sitio web Asociado', // In English: "Associated website"
|
||||
@@ -447,9 +396,6 @@ const es = {
|
||||
'window_click_to_go_back': 'Click para regresar', // In English: "Click to go back."
|
||||
'window_click_to_go_forward': 'Click para avanzar', // In English: "Click to go forward."
|
||||
'window_click_to_go_up': 'Click para ir al directorio superior', // In English: "Click to go one directory up."
|
||||
'window_title_public': 'Público', // In English: "Public"
|
||||
'window_title_videos': 'Videos', // In English: "Videos"
|
||||
'window_title_pictures': 'Imágenes', // In English: "Pictures"
|
||||
'window_title_puter': 'Puter', // In English: "Puter"
|
||||
'window_folder_empty': 'Esta carpeta está vacía', // In English: "This folder is empty"
|
||||
},
|
||||
|
||||
@@ -31,7 +31,6 @@ const fa = {
|
||||
allow: 'اجازه دسترسی',
|
||||
ascending: 'صعودی',
|
||||
associated_websites: 'وب سایت های مرتبط',
|
||||
auto_arrange: 'ترتیب خودکار',
|
||||
cancel: 'لغو',
|
||||
change: 'تغییر',
|
||||
change_always_open_with: 'آیا میخواهید همیشه این نوع فایل را با ... باز کنید؟',
|
||||
@@ -42,19 +41,13 @@ const fa = {
|
||||
close: 'بستن',
|
||||
close_all_windows_and_log_out: 'بستن پنجرهها و خروج',
|
||||
confirm: 'تایید',
|
||||
confirm_2fa_setup: 'کد را به برنامه تأیید هویت خود اضافه کردهام',
|
||||
confirm_2fa_recovery: 'کدهای بازیابی خود را در یک مکان امن ذخیره کردهام',
|
||||
confirm_account_for_free_referral_storage_c2a:
|
||||
'حساب کاربری خود را ایجاد کرده و آدرس ایمیل خود را تأیید کنید تا 1 گیگابایت فضای ذخیره سازی رایگان دریافت کنید. دوست شما هم 1 گیگابایت فضای ذخیره سازی رایگان دریافت خواهد کرد.',
|
||||
confirm_code_generic_incorrect: 'کد نادرست است',
|
||||
confirm_code_generic_too_many_requests:
|
||||
'تعداددرخواستها زیاداست. لطفاً چند دقیقه صبر کنید',
|
||||
confirm_code_generic_submit: 'ثبت کد',
|
||||
confirm_code_generic_try_again: 'دوباره امتحان کنید',
|
||||
confirm_code_2fa_instruction:
|
||||
'کد ۶ رقمی را از برنامه تأیید هویت خود وارد کنید',
|
||||
confirm_code_2fa_submit_btn: 'ثبت',
|
||||
confirm_code_2fa_title: 'کد احراز هویت دو مرحله ای را وارد کنید',
|
||||
confirm_delete_multiple_items:
|
||||
'آیا مطمئن هستید که میخواهید این موارد را برای همیشه حذف کنید؟',
|
||||
confirm_delete_single_item:
|
||||
@@ -69,8 +62,6 @@ const fa = {
|
||||
'آیا مطمئن هستید که می خواهید این نشست را لغو کنید؟', // TN: It's better to use session instead ofنشست
|
||||
confirm_your_email_address: 'ایمیل خود را تأیید کنید',
|
||||
contact_us: 'تماس با ما',
|
||||
contact_us_verification_required:
|
||||
'شما باید یک آدرس ایمیل تأیید شده داشته باشید تا بتوانید از این استفاده کنید ',
|
||||
continue: 'ادامه',
|
||||
copy: 'کپی',
|
||||
copy_link: 'کپی لینک',
|
||||
@@ -92,19 +83,14 @@ const fa = {
|
||||
deploy_as_app: 'نصب به عنوان برنامه',
|
||||
descending: 'نزولی',
|
||||
desktop: 'دسکتاپ',
|
||||
desktop_background_fit: 'متناسب',
|
||||
developers: 'تولیدکنندگان نرم افزار',
|
||||
dir_published_as_website: '%strong% منتشر شده به:',
|
||||
disable_2fa: 'غیر فعال کردن احراز هویت دو مرحله ای',
|
||||
disable_2fa_confirm:
|
||||
'آیا مطمئن هستید که میخواهید احراز هویت دو مرحله ای را غیرفعال کنید؟',
|
||||
disable_2fa_instructions:
|
||||
'برای غیرفعال کردن احراز هویت دو مرحله ای ،رمز عبور خود را وارد کنید',
|
||||
documents: 'اسناد',
|
||||
dont_allow: 'عدم اجازه',
|
||||
download: 'دانلود',
|
||||
download_file: 'دانلود فایل',
|
||||
downloading: 'دانلود',
|
||||
email: 'ایمیل',
|
||||
email_change_confirmation_sent:
|
||||
'یک ایمیل تاییدیه به آدرس ایمیل جدید شما ارسال شده است. لطفاً صندوق ایمیلهای دریافتی خود را بررسی کرده و دستورالعملها را برای تکمیل فرایند دنبال کنید.',
|
||||
@@ -133,13 +119,10 @@ const fa = {
|
||||
forgot_pass_c2a: 'رمز عبور را فراموش کرده اید؟',
|
||||
from: 'از',
|
||||
general: 'عمومی',
|
||||
get_a_copy_of_on_puter: 'یک نسخه از \'%%\' را در Puter.com بگیرید!',
|
||||
get_copy_link: 'گرفتن لینک کپی',
|
||||
home: 'خانه',
|
||||
html_document: 'سند HTML',
|
||||
hue: 'رنگ',
|
||||
incorrect_password: 'رمز عبور نادرست است',
|
||||
invite_link: 'لینک دعوت',
|
||||
item: 'مورد',
|
||||
items_in_trash_cannot_be_renamed: 'این مورد نمی تواند تغییر نام دهد زیرا در سطل زباله است. برای تغییر نام این مورد، ابتدا آن را از سطل زباله بیرون بکشید.',
|
||||
jpeg_image: 'تصویر JPEG',
|
||||
@@ -150,7 +133,6 @@ const fa = {
|
||||
loading: 'در حال بارگذاری',
|
||||
log_in: 'ورود',
|
||||
log_out: 'خروج',
|
||||
looks_good: 'خوب به نظر میرسد!',
|
||||
manage_sessions: 'مدیریت نشستها',
|
||||
modified: 'تغییر داده شده',
|
||||
move: 'انتقال',
|
||||
@@ -175,7 +157,6 @@ const fa = {
|
||||
open_with: 'باز کردن با',
|
||||
original_name: 'نام اصلی',
|
||||
original_path: 'مسیر اصلی',
|
||||
oss_code_and_content: 'نرمافزار و محتوای متنباز',
|
||||
password: 'رمز عبور',
|
||||
password_changed: 'رمز عبور تغییر یافت.',
|
||||
password_recovery_rate_limit:
|
||||
@@ -192,29 +173,21 @@ const fa = {
|
||||
paste: 'چسباندن',
|
||||
paste_into_folder: 'چسباندن در پوشه',
|
||||
path: 'مسیر',
|
||||
personalization: 'شخصی سازی',
|
||||
pick_name_for_website: 'یک نام برای وبسایت خود انتخاب کنید:',
|
||||
pictures: 'تصاویر',
|
||||
plural_suffix: 'ها',
|
||||
powered_by_puter_js: 'پشتیبانی شده توسط {{link=docs}}Puter.js{{/link}}',
|
||||
preparing: 'در حال آماده سازی...',
|
||||
preparing_for_upload: 'آماده سازی برای بارگذاری...',
|
||||
print: 'چاپ',
|
||||
privacy: 'حریم خصوصی',
|
||||
proceed_to_login: 'ادامه به ورود',
|
||||
proceed_with_account_deletion: 'ادامه به حذف حساب کاربری',
|
||||
properties: 'ویژگی ها',
|
||||
public: 'عمومی',
|
||||
publish: 'انتشار',
|
||||
publish_as_website: 'انتشار به عنوان وبسایت',
|
||||
puter_description:
|
||||
'پیوتر یک کلاود با اولویت حفظ حریم خصوصی است که همه فایلها، برنامهها و بازیهای شما را در یک فضای امن نگه میدارد که از هر جا و هر زمان قابل دسترسی است',
|
||||
reading: '%strong%درحال خواندن',
|
||||
writing: '%strong%درحال نوشتن',
|
||||
recover_password: 'بازیابی رمز عبور',
|
||||
refer_friends_c2a:
|
||||
'برای هر دوستی که حساب کاربری Puter ایجاد و تأیید کند، 1 گیگابایت دریافت کنید. دوست شما هم 1 گیگابایت دریافت خواهد کرد!',
|
||||
refer_friends_social_media_c2a: '1 گیگابایت فضای ذخیره سازی رایگان را در Puter.com بگیرید!',
|
||||
refresh: 'تازه کردن',
|
||||
rename: 'تغییر نام',
|
||||
replace: 'جایگزین کردن',
|
||||
@@ -224,12 +197,10 @@ const fa = {
|
||||
save: 'ذخیره',
|
||||
saturation: 'اشباع رنگ',
|
||||
save_account: 'ذخیره حساب',
|
||||
save_account_to_get_copy_link: 'لطفا برای ادامه یک حساب کاربری ایجاد کنید.',
|
||||
save_account_to_publish: 'لطفا برای ادامه یک حساب کاربری ایجاد کنید.',
|
||||
save_session: 'ذخیره نشست', // TN:better to use session instead of نشست
|
||||
save_session_c2a:
|
||||
'برای ذخیره جلسه فعلی و جلوگیری از از دست دادن کار خود یک حساب کاربری ایجاد کنید.',
|
||||
scan_qr_2fa: ' بارکد را با برنامه تایید هویت خود اسکن کنید',
|
||||
search: 'جستجو',
|
||||
seconds: 'ثانیه',
|
||||
security: 'امنیت',
|
||||
@@ -247,13 +218,11 @@ const fa = {
|
||||
show_hidden: 'نمایش مخفی',
|
||||
sign_in_with_puter: 'ورود با Puter',
|
||||
sign_up: 'ثبت نام',
|
||||
signing_in: 'ورود…',
|
||||
size: 'اندازه',
|
||||
skip: 'رد کردن',
|
||||
something_went_wrong: 'مشکلی پیش آمد',
|
||||
sort_by: 'مرتب سازی بر اساس',
|
||||
status: 'وضعیت',
|
||||
storage_usage: 'میزان استفاده شده از فضای ذخیره سازی',
|
||||
storage_puter_used: 'استفاده شده توسط Puter',
|
||||
taking_longer_than_usual: 'کمی بیشتر از معمول طول می کشد. لطفا صبر کنید...',
|
||||
terms: 'شرایط',
|
||||
@@ -283,26 +252,19 @@ const fa = {
|
||||
videos: 'ویدیو ها',
|
||||
visibility: 'قابلیت دیده شدن',
|
||||
yes: 'بله',
|
||||
you_have_been_referred_to_puter_by_a_friend:
|
||||
'شما توسط یک دوست به Puter معرفی شده اید!',
|
||||
zip: 'فشرده سازی',
|
||||
sequencing: '%strong%ترتیب بندی',
|
||||
zipping: '%strong%درحال فشرده سازی',
|
||||
|
||||
// === 2FA Setup ===
|
||||
setup2fa_1_step_heading: 'برنامه تأیید هویت خود را باز کنید',
|
||||
setup2fa_1_instructions:
|
||||
"شما میتوانید از هر برنامه تأیید هویتی که از پروتکل رمز یکبار مصرف مبتنی بر زمان (TOTP) پشتیبانی میکند استفاده کنید. اگر مطمئن نیستید، <a target='_blank' href='https://authy.com/download'>Authy</a> یک انتخاب مناسب برای اندروید و iOS است.",
|
||||
setup2fa_2_step_heading: ' بارکد را اسکن کنید ',
|
||||
setup2fa_3_step_heading: 'کد ۶ رقمی را وارد کنید',
|
||||
setup2fa_4_step_heading: 'کدهای بازیابی خود را کپی کنید',
|
||||
setup2fa_4_instructions:
|
||||
'این کدهای بازیابی تنها راه دسترسی به حساب شما هستند در صورتی که تلفن خود را گم کنید یا نتوانید از برنامه تأیید هویت استفاده کنید. مطمئن شوید که آنها را در مکانی امن ذخیره کردهاید.',
|
||||
setup2fa_5_step_heading: 'تنظیمات احراز هویت دو مرحله ای را تایید کنید',
|
||||
setup2fa_5_confirmation_1:
|
||||
'من کدهای بازیابی خود را در مکانی امن ذخیره کردهام',
|
||||
setup2fa_5_confirmation_2: 'آماده فعال کردن احراز هویت دو مرحله ای هستم',
|
||||
setup2fa_5_button: 'فعالسازی احراز هویت دو مرحلهای',
|
||||
// === 2FA Login ===
|
||||
login2fa_otp_title: 'کد احراز هویت دو مرحلهای را وارد کنید',
|
||||
login2fa_otp_instructions:
|
||||
@@ -311,7 +273,6 @@ const fa = {
|
||||
login2fa_recovery_instructions:
|
||||
'یکی از کدهای بازیابی خود را برای دسترسی به حساب خود وارد کنید',
|
||||
login2fa_use_recovery_code: 'از کد بازیابی استفاده کنید',
|
||||
login2fa_recovery_back: 'بازگشت',
|
||||
login2fa_recovery_placeholder: 'XXXXXXX',
|
||||
|
||||
// Sharing
|
||||
@@ -372,21 +333,13 @@ const fa = {
|
||||
'billing.expanded': 'گسترش یافته',
|
||||
'billing.accelerated': 'تسریع شده',
|
||||
'billing.enjoy_msg': 'از %% فضای ذخیرهسازی ابری به همراه سایر مزایا لذت ببرید.',
|
||||
'confirm_code_generic_title': 'کد تأیید را وارد کنید',
|
||||
'choose_publishing_option': 'انتخاب کنید که چگونه میخواهید وبسایت خود را منتشر کنید:',
|
||||
'create_desktop_shortcut': 'ایجاد میانبر (دسکتاپ)',
|
||||
'create_desktop_shortcut_s': 'ایجاد میانبرها (دسکتاپ)',
|
||||
'create_shortcut_s': 'ایجاد میانبرها',
|
||||
'minimize': 'کوچککردن',
|
||||
'reload_app': 'بارگذاری دوباره برنامه',
|
||||
'publish_as_serverless_worker': 'انتشار بهعنوان کارگر',
|
||||
'toolbar.enter_fullscreen': 'ورود به تمامصفحه',
|
||||
'toolbar.github': 'گیتهاب',
|
||||
'toolbar.refer': 'معرفی',
|
||||
'used_of': '{{used}} استفاده شده از {{available}}',
|
||||
'worker': 'کارگر',
|
||||
'billing.offering.basic': 'پایه',
|
||||
'too_many_attempts': 'تعداد تلاشها بیش از حد است. لطفاً بعداً دوباره امتحان کنید.',
|
||||
'server_timeout': 'پاسخ سرور بیش از حد طول کشید. لطفاً دوباره امتحان کنید.',
|
||||
'signup_error': 'خطایی هنگام ثبتنام رخ داد. لطفاً دوباره امتحان کنید.',
|
||||
'alert_error_title': 'خطا!',
|
||||
@@ -404,15 +357,10 @@ const fa = {
|
||||
'window_title_open': 'باز کردن',
|
||||
'window_title_change_password': 'تغییر رمز عبور',
|
||||
'window_title_select_font': 'انتخاب فونت…',
|
||||
'window_title_session_list': 'لیست نشستها!',
|
||||
'window_title_set_new_password': 'تنظیم رمز عبور جدید',
|
||||
'window_title_publish_website': 'انتشار وبسایت',
|
||||
'window_title_publish_worker': 'انتشار کارگر',
|
||||
'window_title_authenticating': 'در حال احراز هویت...',
|
||||
'window_title_refer_friend': 'معرفی یک دوست!',
|
||||
'desktop_exit_full_screen': 'خروج از تمامصفحه',
|
||||
'desktop_enter_full_screen': 'ورود به تمامصفحه',
|
||||
'item_shared_with_you': 'یک کاربر این مورد را با شما به اشتراک گذاشته است.',
|
||||
'item_shared_by_you': 'شما این مورد را با حداقل یک کاربر دیگر به اشتراک گذاشتهاید.',
|
||||
'item_shortcut': 'میانبر',
|
||||
'item_associated_websites': 'وبسایت مرتبط',
|
||||
@@ -421,9 +369,6 @@ const fa = {
|
||||
'window_click_to_go_back': 'برای بازگشت کلیک کنید.',
|
||||
'window_click_to_go_forward': 'برای رفتن به جلو کلیک کنید.',
|
||||
'window_click_to_go_up': 'برای رفتن به یک پوشه بالاتر کلیک کنید.',
|
||||
'window_title_public': 'عمومی',
|
||||
'window_title_videos': 'ویدئوها',
|
||||
'window_title_pictures': 'تصاویر',
|
||||
'window_title_puter': 'Puter',
|
||||
'window_folder_empty': 'این پوشه خالی است',
|
||||
},
|
||||
|
||||
@@ -37,7 +37,6 @@ const fi = {
|
||||
|
||||
ascending: 'Nouseva',
|
||||
associated_websites: 'Tähän liittyvät verkkosivustot',
|
||||
auto_arrange: 'Järjestä automaattisesti',
|
||||
cancel: 'Peruuta',
|
||||
change_email: 'Vaihda sähköpostiosoite',
|
||||
change_language: 'Vaihda kieli',
|
||||
@@ -48,21 +47,13 @@ const fi = {
|
||||
change_always_open_with:
|
||||
'Haluatko aina avata tämän tyyppisen tiedoston sovelluksella',
|
||||
confirm: 'Vahvista',
|
||||
confirm_2fa_setup: 'Olen lisännyt koodin todennussovellukseeni',
|
||||
confirm_2fa_recovery:
|
||||
'Olen tallentanut palautuskoodini turvalliseen paikkaan',
|
||||
confirm_account_for_free_referral_storage_c2a:
|
||||
'Luo tili ja vahvista sähköpostiosoitteesi saadaksesi 1 Gt ilmaista tallennustilaa. Myös kaverisi saa 1 Gt:n ilmaista tallennustilaa.',
|
||||
confirm_code_generic_incorrect: 'Väärä koodi.',
|
||||
confirm_code_generic_too_many_requests:
|
||||
'Liikaa pyyntöjä. Ole hyvä ja odota muutama minuutti.',
|
||||
confirm_code_generic_submit: 'Lähetä koodi',
|
||||
confirm_code_generic_try_again: 'Yritä uudelleen',
|
||||
confirm_code_generic_title: 'Syötä vahvistuskoodi',
|
||||
confirm_code_2fa_instruction:
|
||||
'Syötä kuusinumeroinen koodi todennussovelluksestasi.',
|
||||
confirm_code_2fa_submit_btn: 'Lähetä',
|
||||
confirm_code_2fa_title: 'Syötä kaksivaiheisen tunnistautumisen koodi',
|
||||
confirm_delete_multiple_items:
|
||||
'Haluatko varmasti poistaa nämä kohteet pysyvästi?',
|
||||
confirm_delete_single_item: 'Haluatko poistaa tämän kohteen pysyvästi?',
|
||||
@@ -75,8 +66,6 @@ const fi = {
|
||||
confirm_session_revoke: 'Haluatko varmasti peruuttaa tämän istunnon?',
|
||||
confirm_your_email_address: 'Vahvista sähköpostiosoitteesi',
|
||||
contact_us: 'Ota yhteyttä',
|
||||
contact_us_verification_required:
|
||||
'Sinulla on oltava vahvistettu sähköpostiosoite, jotta voit käyttää tätä.',
|
||||
// "inside(a house)" => "Sisällä" - probably more appropriate
|
||||
// "contain within" => "Sisältää"
|
||||
|
||||
@@ -110,19 +99,14 @@ const fi = {
|
||||
deploy_as_app: 'Ota käyttöön sovelluksena',
|
||||
descending: 'Laskeva',
|
||||
desktop: 'Työpöytä',
|
||||
desktop_background_fit: 'Sovita',
|
||||
developers: 'Kehittäjät',
|
||||
dir_published_as_website: '%strong% on julkaistu osoitteessa:',
|
||||
disable_2fa: 'Ota kaksivaiheinen tunnistautuminen pois käytöstä',
|
||||
disable_2fa_confirm:
|
||||
'Haluatko varmasti poistaa kaksivaiheisen tunnistautumisen käytöstä?',
|
||||
disable_2fa_instructions:
|
||||
'Syötä salasanasi poistaaksesi kaksivaihesen tunnistautumisen käytöstä.',
|
||||
documents: 'Dokumentit',
|
||||
dont_allow: 'Älä salli',
|
||||
download: 'Lataa',
|
||||
download_file: 'Lataa tiedosto',
|
||||
downloading: 'Ladataan',
|
||||
email: 'Sähköpostiosoite',
|
||||
email_change_confirmation_sent:
|
||||
'Vahvistusviesti on lähetetty uuteen sähköpostiosoitteeseesi. Tarkista postilaatikkosi ja viimeistele prosessi seuraamalla ohjeita.',
|
||||
@@ -160,9 +144,7 @@ const fi = {
|
||||
// "general (about something)" => "Yleistä" or
|
||||
// "military general" => "Kenraali"
|
||||
|
||||
get_a_copy_of_on_puter: 'Hanki \'%%\' -kopio Puter.com-sivustolta!', // TODO: Very difficult ambiguity due to different case suffix for any possible word that you can substitue here. Can stay as is, but it's not exactly correct.
|
||||
|
||||
get_copy_link: 'Hanki kopiolinkki', // TODO: Ambiguous meaning
|
||||
// 'get a copy of a link' => 'Ota Kopio Linkkiin' or
|
||||
// 'get a link to the copy' => 'Ota Linkki Kopioon' - More probable, just want to be sure
|
||||
|
||||
@@ -170,7 +152,6 @@ const fi = {
|
||||
html_document: 'HTML-dokumentti',
|
||||
hue: 'Sävy',
|
||||
incorrect_password: 'Väärä salasana',
|
||||
invite_link: 'Kutsulinkki',
|
||||
item: 'kohde',
|
||||
items_in_trash_cannot_be_renamed: 'Tätä kohdetta ei voi nimetä uudelleen, koska se on roskakorissa. Jos haluat nimetä kohteen uudelleen, palauta se ensin roskakorista.',
|
||||
jpeg_image: 'JPEG-kuva',
|
||||
@@ -181,7 +162,6 @@ const fi = {
|
||||
loading: 'Ladataan',
|
||||
log_in: 'Kirjaudu Sisään',
|
||||
log_out: 'Kirjaudu ulos',
|
||||
looks_good: 'Näyttää hyvältä!',
|
||||
manage_sessions: 'Hallitse istuntoja',
|
||||
modified: 'Muokattu',
|
||||
move: 'Siirrä',
|
||||
@@ -217,7 +197,6 @@ const fi = {
|
||||
|
||||
original_name: 'Alkuperäinen nimi',
|
||||
original_path: 'Alkuperäinen polku',
|
||||
oss_code_and_content: 'Avoimen lähdekoodin ohjelmisto ja sisältö',
|
||||
password: 'Salasana',
|
||||
password_changed: 'Salasana vaihdettu.',
|
||||
password_recovery_rate_limit:
|
||||
@@ -234,27 +213,20 @@ const fi = {
|
||||
paste: 'Liitä',
|
||||
paste_into_folder: 'Liitä kansioon',
|
||||
path: 'Polku',
|
||||
personalization: 'Personointi',
|
||||
pick_name_for_website: 'Valitse nimi verkkosivustollesi:',
|
||||
pictures: 'Kuvat',
|
||||
plural_suffix: 't',
|
||||
powered_by_puter_js: 'Palvelun tarjoaa {{link=docs}}Puter.js{{/link}}',
|
||||
preparing: 'Valmistellaan...',
|
||||
preparing_for_upload: 'Valmistellaan latausta...',
|
||||
print: 'Tulosta',
|
||||
privacy: 'Yksityisyys',
|
||||
proceed_to_login: 'Jatka sisäänkirjautumiseen',
|
||||
proceed_with_account_deletion: 'Jatka tilin poistamista',
|
||||
properties: 'Ominaisuudet',
|
||||
public: 'Julkinen',
|
||||
publish: 'Julkaise',
|
||||
publish_as_website: 'Julkaise verkkosivustona',
|
||||
puter_description: 'Puter on yksityisyyttä korostava henkilökohtainen pilvipalvelu, jossa voit säilyttää kaikki tiedostosi, sovelluksesi ja pelisi yhdessä turvallisessa paikassa, ja jotka ovat saatavilla mistä tahansa milloin tahansa.',
|
||||
reading_file: 'Luetaan %strong%',
|
||||
recover_password: 'Palauta salasanasi',
|
||||
refer_friends_c2a:
|
||||
'Saat 1 Gt ilmaista tallennustilaa jokaisesta ystävästä, joka luo ja vahvistaa tilin Puterissa. Myös ystäväsi saa 1 Gt:n ilmaista tallennustilaa!',
|
||||
refer_friends_social_media_c2a: 'Hanki 1 Gt ilmaista tallennustilaa Puter.comista!',
|
||||
refresh: 'Päivitä',
|
||||
|
||||
// "get rid of" => "Oletko varma, että haluat luovuttaa tämän osoitteen?" or
|
||||
@@ -268,12 +240,10 @@ const fi = {
|
||||
save: 'Tallenna',
|
||||
saturation: 'Kylläisyys',
|
||||
save_account: 'Tallenna tili',
|
||||
save_account_to_get_copy_link: 'Luo tili jatkaaksesi.',
|
||||
save_account_to_publish: 'Luo tili jatkaaksesi.',
|
||||
save_session: 'Tallenna istunto',
|
||||
save_session_c2a:
|
||||
'Luo tili tallentaaksesi nykyisen istuntosi ja välttääksesi työsi menettämisen.',
|
||||
scan_qr_2fa: 'Skannaa QR-koodi todennussovelluksellasi',
|
||||
search: 'Etsi',
|
||||
seconds: 'sekuntia',
|
||||
security: 'Turvallisuus',
|
||||
@@ -295,13 +265,11 @@ const fi = {
|
||||
show_hidden: 'Näytä piilotetut',
|
||||
sign_in_with_puter: 'Kirjaudu sisään Puterilla',
|
||||
sign_up: 'Rekisteröidy',
|
||||
signing_in: 'Kirjaudutaan sisään…',
|
||||
size: 'Koko',
|
||||
skip: 'Ohita',
|
||||
something_went_wrong: 'Jokin meni pieleen.',
|
||||
sort_by: 'Lajittele',
|
||||
status: 'Tila',
|
||||
storage_usage: 'Tallennustilan käyttö',
|
||||
storage_puter_used: 'Puterin käyttämä',
|
||||
taking_longer_than_usual:
|
||||
'Kestää hieman tavallista kauemmin. Ole hyvä ja odota...',
|
||||
@@ -338,32 +306,24 @@ const fi = {
|
||||
videos: 'Videot',
|
||||
visibility: 'Näkyvyys',
|
||||
yes: 'Kyllä',
|
||||
you_have_been_referred_to_puter_by_a_friend:
|
||||
'Kaverisi on kutsunut sinut Puteriin!',
|
||||
zip: 'Zip',
|
||||
zipping_file: 'Zipataan %strong%',
|
||||
|
||||
// === 2FA Setup ===
|
||||
setup2fa_1_step_heading: 'Avaa todennussovelluksesi',
|
||||
setup2fa_1_instructions: `
|
||||
Voit käyttää mitä tahansa todennussovellusta, joka tukee aikaperusteista kertakirjautumissalasanaa (TOTP-protokollaa).
|
||||
Valittavanasi on monia sovelluksia, mutta jos et ole varma,
|
||||
<a target="_blank" href="https://authy.com/download">Authy</a> on hyvä valinta Androidille ja iOS:lle.
|
||||
`,
|
||||
setup2fa_2_step_heading: 'Skannaa QR-koodi',
|
||||
setup2fa_3_step_heading: 'Syötä kuusinumeroinen koodi',
|
||||
setup2fa_4_step_heading: 'Kopioi palautuskoodisi',
|
||||
setup2fa_4_instructions: `
|
||||
Nämä palautuskoodit ovat ainoa tapa päästä tiliisi, jos menetät puhelimesi tai et voi käyttää todennussovellustasi.
|
||||
Varmista, että säilytät ne turvallisessa paikassa.
|
||||
`,
|
||||
setup2fa_5_step_heading:
|
||||
'Vahvista kaksivaiheisen tunnistautumisen asetukset',
|
||||
setup2fa_5_confirmation_1:
|
||||
'Olen tallentanut palautuskoodini turvalliseen paikkaan',
|
||||
setup2fa_5_confirmation_2:
|
||||
'Olen valmis ottamaan kaksivaiheisen tunnistautumisen käyttöön',
|
||||
setup2fa_5_button: 'Ota kaksivaiheinen tunnistautuminen käyttöön',
|
||||
|
||||
// === 2FA Login ===
|
||||
login2fa_otp_title: 'Syötä kaksivaiheisen tunnistautumisen koodi',
|
||||
@@ -373,7 +333,6 @@ const fi = {
|
||||
login2fa_recovery_instructions:
|
||||
'Syötä yksi palautuskoodeistasi saadaksesi pääsy tilillesi.',
|
||||
login2fa_use_recovery_code: 'Käytä palautuskoodi',
|
||||
login2fa_recovery_back: 'Takaisin',
|
||||
login2fa_recovery_placeholder: 'XXXXXXXX',
|
||||
|
||||
change: 'muutos', // In English: "Change"
|
||||
@@ -439,20 +398,13 @@ const fi = {
|
||||
'billing.accelerated': 'Nopeutettu', // In English: "Accelerated"
|
||||
'billing.enjoy_msg': 'Nauti %% pilvitallennustilasta ja muista eduista.', // In English: "Enjoy %% of Cloud Storage plus other benefits."
|
||||
|
||||
'choose_publishing_option': 'Valitse, miten haluat julkaista verkkosivustosi:',
|
||||
'create_desktop_shortcut': 'Luo pikakuvake (Työpöydälle)',
|
||||
'create_desktop_shortcut_s': 'Luo pikakuvakkeita (Työpöydälle)',
|
||||
'create_shortcut_s': 'Luo pikakuvakkeita',
|
||||
'minimize': 'Pienennä',
|
||||
'reload_app': 'Lataa sovellus uudelleen',
|
||||
'publish_as_serverless_worker': 'Julkaise työntekijänä',
|
||||
'toolbar.enter_fullscreen': 'Koko näyttöön',
|
||||
'toolbar.github': 'GitHub',
|
||||
'toolbar.refer': 'Suosittele',
|
||||
'used_of': '{{used}} käytetty {{available}}:sta',
|
||||
'worker': 'Työntekijä',
|
||||
'billing.offering.basic': 'Perus',
|
||||
'too_many_attempts': 'Liian monta yritystä. Yritä myöhemmin uudelleen.',
|
||||
'server_timeout': 'Palvelimen vastaus kesti liian kauan. Yritä uudelleen.',
|
||||
'signup_error': 'Rekisteröitymisen aikana tapahtui virhe. Yritä uudelleen.',
|
||||
'alert_error_title': 'Virhe!',
|
||||
@@ -470,15 +422,10 @@ const fi = {
|
||||
'window_title_open': 'Avaa',
|
||||
'window_title_change_password': 'Vaihda salasana',
|
||||
'window_title_select_font': 'Valitse fontti…',
|
||||
'window_title_session_list': 'Istuntolista',
|
||||
'window_title_set_new_password': 'Aseta uusi salasana',
|
||||
'window_title_publish_website': 'Julkaise verkkosivusto',
|
||||
'window_title_publish_worker': 'Julkaise työntekijä',
|
||||
'window_title_authenticating': 'Todennetaan...',
|
||||
'window_title_refer_friend': 'Suosittele ystävälle!',
|
||||
'desktop_exit_full_screen': 'Poistu koko näytöstä',
|
||||
'desktop_enter_full_screen': 'Koko näyttöön',
|
||||
'item_shared_with_you': 'Käyttäjä on jakanut tämän kohteen kanssasi.',
|
||||
'item_shared_by_you': 'Olet jakanut tämän kohteen ainakin yhden muun käyttäjän kanssa.',
|
||||
'item_shortcut': 'Pikakuvake',
|
||||
'item_associated_websites': 'Liittyvä verkkosivusto',
|
||||
@@ -487,9 +434,6 @@ const fi = {
|
||||
'window_click_to_go_back': 'Napsauta palataksesi takaisin.',
|
||||
'window_click_to_go_forward': 'Napsauta siirtyäksesi eteenpäin.',
|
||||
'window_click_to_go_up': 'Napsauta siirtyäksesi yhtä kansiotasoa ylöspäin.',
|
||||
'window_title_public': 'Julkinen',
|
||||
'window_title_videos': 'Videot',
|
||||
'window_title_pictures': 'Kuvat',
|
||||
'window_title_puter': 'Puter',
|
||||
'window_folder_empty': 'Tämä kansio on tyhjä',
|
||||
},
|
||||
|
||||
@@ -31,7 +31,6 @@ const fil = {
|
||||
allow: 'Payagan',
|
||||
ascending: 'Pataas',
|
||||
associated_websites: 'Mga kaugnay na website',
|
||||
auto_arrange: 'Ayusin nang awtomatiko',
|
||||
cancel: 'Kanselahin',
|
||||
change_email: 'Baguhin ang email',
|
||||
change_language: 'Baguhin ang wika',
|
||||
@@ -41,18 +40,11 @@ const fil = {
|
||||
close_all_windows_and_log_out: 'Isara ang mga window at mag-log out',
|
||||
change_always_open_with: 'Gusto mo bang laging buksan ang ganitong file gamit ang',
|
||||
confirm: 'Kumpirmahin',
|
||||
confirm_2fa_setup: 'Naidagdag ko na ang code sa authenticator app ko',
|
||||
confirm_2fa_recovery: 'Naitago ko na ang mga recovery code sa ligtas na lugar',
|
||||
confirm_code_generic_incorrect: 'Maling code.',
|
||||
confirm_code_generic_too_many_requests:
|
||||
'Sobrang daming request. Maghintay ng ilang minuto.',
|
||||
confirm_code_generic_submit: 'Isumite ang code',
|
||||
confirm_code_generic_try_again: 'Subukan ulit',
|
||||
confirm_code_generic_title: 'Ilagay ang confirmation code',
|
||||
confirm_code_2fa_instruction:
|
||||
'Ilagay ang 6-digit na code mula sa authenticator app mo.',
|
||||
confirm_code_2fa_submit_btn: 'Isumite',
|
||||
confirm_code_2fa_title: 'Ilagay ang 2FA code',
|
||||
confirm_delete_multiple_items:
|
||||
'Permanenteng tatanggalin mo ba ang mga item na ito?',
|
||||
confirm_delete_single_item: 'Permanenteng tatanggalin mo ba ang item na ito?',
|
||||
@@ -65,8 +57,6 @@ const fil = {
|
||||
confirm_session_revoke: 'Sigurado ka bang babawiin ang session na ito?',
|
||||
confirm_your_email_address: 'Kumpirmahin ang email mo',
|
||||
contact_us: 'Makipag-ugnayan',
|
||||
contact_us_verification_required:
|
||||
'Kailangan ng naberipikang email para magamit ito.',
|
||||
continue: 'Magpatuloy',
|
||||
copy: 'Kopyahin',
|
||||
copy_link: 'Kopyahin ang link',
|
||||
@@ -88,17 +78,13 @@ const fil = {
|
||||
deploy_as_app: 'I-deploy bilang app',
|
||||
descending: 'Pababa',
|
||||
desktop: 'Desktop',
|
||||
desktop_background_fit: 'Pagkakasya',
|
||||
developers: 'Mga developer',
|
||||
dir_published_as_website: 'Na-publish ang %strong% sa:',
|
||||
disable_2fa: 'I-disable ang 2FA',
|
||||
disable_2fa_confirm: 'I-disable mo ba ang 2FA?',
|
||||
disable_2fa_instructions: 'Ilagay ang password mo para i-disable ang 2FA.',
|
||||
documents: 'Mga dokumento',
|
||||
dont_allow: 'Huwag payagan',
|
||||
download: 'I-download',
|
||||
download_file: 'I-download ang file',
|
||||
downloading: 'Dina-download',
|
||||
email: 'Email',
|
||||
email_change_confirmation_sent:
|
||||
'Napadala na ang confirmation email sa bago mong email. Buksan ang inbox at sundin ang mga hakbang para matapos ang proseso.',
|
||||
@@ -127,13 +113,10 @@ const fil = {
|
||||
forgot_pass_c2a: 'Nakalimutan ang password?',
|
||||
from: 'Mula kay',
|
||||
general: 'Pangkalahatan',
|
||||
get_a_copy_of_on_puter: 'Kumuha ng kopya ng \'%%\' sa Puter.com!',
|
||||
get_copy_link: 'Kunin ang copy link',
|
||||
home: 'Home',
|
||||
html_document: 'HTML na dokumento',
|
||||
hue: 'Hue',
|
||||
incorrect_password: 'Maling password',
|
||||
invite_link: 'Invite link',
|
||||
item: 'item',
|
||||
items_in_trash_cannot_be_renamed: 'Hindi mapalitan ang pangalan ng item na ito dahil nasa Trash. Ilabas muna ito sa Trash.',
|
||||
jpeg_image: 'JPEG na larawan',
|
||||
@@ -144,7 +127,6 @@ const fil = {
|
||||
loading: 'Naglo-load',
|
||||
log_in: 'Mag-log in',
|
||||
log_out: 'Mag-log out',
|
||||
looks_good: 'Ayos na!',
|
||||
manage_sessions: 'Pamahalaan ang mga session',
|
||||
modified: 'Binago',
|
||||
move: 'Ilipat',
|
||||
@@ -169,7 +151,6 @@ const fil = {
|
||||
open_with: 'Buksan gamit ang',
|
||||
original_name: 'Orihinal na pangalan',
|
||||
original_path: 'Orihinal na lokasyon',
|
||||
oss_code_and_content: 'Open source na software at content',
|
||||
password: 'Password',
|
||||
password_changed: 'Napalitan na ang password.',
|
||||
password_recovery_rate_limit:
|
||||
@@ -185,24 +166,17 @@ const fil = {
|
||||
paste: 'I-paste',
|
||||
paste_into_folder: 'I-paste sa folder',
|
||||
path: 'Lokasyon',
|
||||
personalization: 'Personalization',
|
||||
pick_name_for_website: 'Pumili ng pangalan para sa website mo:',
|
||||
pictures: 'Mga larawan',
|
||||
plural_suffix: '',
|
||||
powered_by_puter_js: 'Pinapagana ng {{link=docs}}Puter.js{{/link}}',
|
||||
preparing: 'Inihahanda...',
|
||||
preparing_for_upload: 'Inihahanda ang pag-upload...',
|
||||
print: 'I-print',
|
||||
privacy: 'Privacy',
|
||||
proceed_to_login: 'Magpatuloy sa pag-log in',
|
||||
proceed_with_account_deletion: 'Ituloy ang pagbura ng account',
|
||||
properties: 'Mga katangian',
|
||||
public: 'Pampubliko',
|
||||
publish: 'I-publish',
|
||||
publish_as_website: 'I-publish bilang website',
|
||||
puter_description: 'Ang Puter ay isang privacy-first na personal cloud para sa mga file, app, at laro mo, sa isang ligtas na lugar, kahit saan at kahit kailan.',
|
||||
recover_password: 'I-recover ang password',
|
||||
refer_friends_social_media_c2a: 'Makakuha ng 1 GB na libreng storage sa Puter.com!',
|
||||
refresh: 'I-refresh',
|
||||
rename: 'Palitan ang pangalan',
|
||||
replace: 'Palitan',
|
||||
@@ -212,12 +186,10 @@ const fil = {
|
||||
save: 'I-save',
|
||||
saturation: 'Saturation',
|
||||
save_account: 'I-save ang account',
|
||||
save_account_to_get_copy_link: 'Gumawa ng account para makakuha ng copy link.',
|
||||
save_account_to_publish: 'Gumawa ng account para makapagpatuloy.',
|
||||
save_session: 'I-save ang session',
|
||||
save_session_c2a:
|
||||
'Gumawa ng account para ma-save ang session na ito at hindi mawala ang ginagawa mo.',
|
||||
scan_qr_2fa: 'I-scan ang QR code gamit ang authenticator app mo',
|
||||
search: 'Hanapin',
|
||||
seconds: 'segundo',
|
||||
security: 'Seguridad',
|
||||
@@ -235,13 +207,11 @@ const fil = {
|
||||
show_hidden: 'Ipakita ang nakatago',
|
||||
sign_in_with_puter: 'Mag-sign in gamit ang Puter',
|
||||
sign_up: 'Mag-sign up',
|
||||
signing_in: 'Nagla-log in…',
|
||||
size: 'Laki',
|
||||
skip: 'Laktawan',
|
||||
something_went_wrong: 'May nangyaring mali.',
|
||||
sort_by: 'Ayusin ayon sa',
|
||||
status: 'Status',
|
||||
storage_usage: 'Gamit na storage',
|
||||
storage_puter_used: 'ginagamit ng Puter',
|
||||
taking_longer_than_usual:
|
||||
'Medyo mas matagal kaysa karaniwan. Maghintay...',
|
||||
@@ -270,11 +240,8 @@ const fil = {
|
||||
videos: 'Mga video',
|
||||
visibility: 'Visibility',
|
||||
yes: 'Oo',
|
||||
you_have_been_referred_to_puter_by_a_friend:
|
||||
'Ni-refer ka ng isang kaibigan sa Puter!',
|
||||
zip: 'I-zip',
|
||||
|
||||
setup2fa_1_step_heading: 'Buksan ang authenticator app mo',
|
||||
setup2fa_1_instructions: `
|
||||
Puwede ang kahit anong authenticator app na sumusuporta sa Time-based One-Time Password (TOTP).
|
||||
Maraming pagpipilian, pero kung hindi ka sigurado,
|
||||
@@ -282,18 +249,14 @@ const fil = {
|
||||
<a target="_blank" href="https://authy.com/download">Authy</a>
|
||||
para sa Android at iOS.
|
||||
`,
|
||||
setup2fa_2_step_heading: 'I-scan ang QR code',
|
||||
setup2fa_3_step_heading: 'Ilagay ang 6 na digit',
|
||||
setup2fa_4_step_heading: 'Kopyahin ang mga recovery code mo',
|
||||
setup2fa_4_instructions: `
|
||||
Ang mga recovery code na ito ang tanging paraan para makapasok sa account mo kung mawala ang phone mo o hindi mo magamit ang authenticator app.
|
||||
Itago ang mga ito sa ligtas na lugar.
|
||||
`,
|
||||
setup2fa_5_step_heading: 'Kumpirmahin ang setup ng 2FA',
|
||||
setup2fa_5_confirmation_1:
|
||||
'Naitago ko na ang mga recovery code sa ligtas na lugar',
|
||||
setup2fa_5_confirmation_2: 'Handa na akong i-enable ang 2FA',
|
||||
setup2fa_5_button: 'I-enable ang 2FA',
|
||||
|
||||
login2fa_otp_title: 'Ilagay ang 2FA code',
|
||||
login2fa_otp_instructions: 'Ilagay ang 6 na digit mula sa authenticator app mo.',
|
||||
@@ -301,7 +264,6 @@ const fil = {
|
||||
login2fa_recovery_instructions:
|
||||
'Ilagay ang isa sa mga recovery code mo para makapasok sa account.',
|
||||
login2fa_use_recovery_code: 'Gumamit ng recovery code',
|
||||
login2fa_recovery_back: 'Bumalik',
|
||||
login2fa_recovery_placeholder: 'XXXXXXXX',
|
||||
|
||||
'change': 'Baguhin',
|
||||
@@ -366,20 +328,13 @@ const fil = {
|
||||
'billing.accelerated': 'Pinabilis',
|
||||
'billing.enjoy_msg': 'Sulitin ang %% na Cloud Storage at ang iba pang benepisyo.',
|
||||
|
||||
'choose_publishing_option': 'Piliin kung paano i-publish ang website mo:',
|
||||
'create_desktop_shortcut': 'Gumawa ng shortcut (Desktop)',
|
||||
'create_desktop_shortcut_s': 'Gumawa ng mga shortcut (Desktop)',
|
||||
'create_shortcut_s': 'Gumawa ng mga shortcut',
|
||||
'minimize': 'I-minimize',
|
||||
'reload_app': 'I-reload ang app',
|
||||
'publish_as_serverless_worker': 'I-publish bilang worker',
|
||||
'toolbar.enter_fullscreen': 'Pumunta sa full screen',
|
||||
'toolbar.github': 'GitHub',
|
||||
'toolbar.refer': 'Mag-refer',
|
||||
'used_of': '{{used}} ang nagamit sa {{available}}',
|
||||
'worker': 'Worker',
|
||||
'billing.offering.basic': 'Basic',
|
||||
'too_many_attempts': 'Sobrang daming pagsubok. Subukan ulit mamaya.',
|
||||
'server_timeout': 'Matagal sumagot ang server. Subukan ulit.',
|
||||
'signup_error': 'May error habang nag-sign up. Subukan ulit.',
|
||||
'alert_error_title': 'Error!',
|
||||
@@ -397,15 +352,10 @@ const fil = {
|
||||
'window_title_open': 'Buksan',
|
||||
'window_title_change_password': 'Baguhin ang password',
|
||||
'window_title_select_font': 'Pumili ng font…',
|
||||
'window_title_session_list': 'Listahan ng session',
|
||||
'window_title_set_new_password': 'Magtakda ng bagong password',
|
||||
'window_title_publish_website': 'I-publish ang website',
|
||||
'window_title_publish_worker': 'I-publish ang worker',
|
||||
'window_title_authenticating': 'Nag-a-authenticate...',
|
||||
'window_title_refer_friend': 'Mag-refer ng kaibigan!',
|
||||
'desktop_exit_full_screen': 'Lumabas sa full screen',
|
||||
'desktop_enter_full_screen': 'Pumunta sa full screen',
|
||||
'item_shared_with_you': 'May user na nagbahagi ng item na ito sa iyo.',
|
||||
'item_shared_by_you': 'Ibinahagi mo ang item na ito sa kahit isang ibang user.',
|
||||
'item_shortcut': 'Shortcut',
|
||||
'item_associated_websites': 'Kaugnay na website',
|
||||
@@ -414,9 +364,6 @@ const fil = {
|
||||
'window_click_to_go_back': 'I-click para bumalik.',
|
||||
'window_click_to_go_forward': 'I-click para sumulong.',
|
||||
'window_click_to_go_up': 'I-click para umakyat ng isang directory.',
|
||||
'window_title_public': 'Pampubliko',
|
||||
'window_title_videos': 'Mga video',
|
||||
'window_title_pictures': 'Mga larawan',
|
||||
'window_title_puter': 'Puter',
|
||||
'window_folder_empty': 'Walang laman ang folder na ito',
|
||||
},
|
||||
|
||||
@@ -31,9 +31,7 @@ const fr = {
|
||||
allow: 'Autoriser',
|
||||
ascending: 'Ascendant',
|
||||
associated_websites: 'Sites associés',
|
||||
auto_arrange: 'Organisation automatique',
|
||||
browser: 'Navigateur',
|
||||
browser_version: 'Version du navigateur',
|
||||
captcha_required: 'Veuillez compléter la vérification CAPTCHA',
|
||||
cancel: 'Annuler',
|
||||
change: 'Changer',
|
||||
@@ -42,21 +40,13 @@ const fr = {
|
||||
change_language: 'Changer de langue',
|
||||
change_password: 'Changer le mot de passe',
|
||||
change_username: "Changer le nom d'utilisateur",
|
||||
color_depth: 'Profondeur de couleur',
|
||||
close: 'Fermer',
|
||||
close_all_windows_and_log_out: 'Fermer les fenêtres et se déconnecter',
|
||||
confirm: 'Confirmer',
|
||||
confirm_2fa_setup: "J'ai ajouté le code à mon application d'authentification",
|
||||
confirm_2fa_recovery: "J'ai enregistré mes codes de récupération dans un emplacement sécurisé",
|
||||
confirm_account_for_free_referral_storage_c2a: 'Créez un compte et confirmez votre adresse e-mail pour recevoir 1 Go de stockage gratuit. Votre ami bénéficiera également de 1 Go de stockage gratuit.',
|
||||
confirm_code_generic_incorrect: 'Code incorrect.',
|
||||
confirm_code_generic_too_many_requests: 'Trop de demandes. Veuillez patienter quelques minutes.',
|
||||
confirm_code_generic_submit: 'Envoyer le code',
|
||||
confirm_code_generic_try_again: 'Réessayer',
|
||||
confirm_code_generic_title: 'Entrez le code de confirmation',
|
||||
confirm_code_2fa_instruction: "Saisissez le code à 6 chiffres de votre application d'authentification.",
|
||||
confirm_code_2fa_submit_btn: 'Valider',
|
||||
confirm_code_2fa_title: 'Entrez le code A2F',
|
||||
confirm_delete_multiple_items: 'Êtes-vous sûr de vouloir supprimer définitivement ces éléments ?',
|
||||
confirm_delete_single_item: 'Voulez-vous supprimer définitivement cet élément ?',
|
||||
confirm_open_apps_log_out: 'Vous avez des applications ouvertes. Êtes-vous sûr de vouloir vous déconnecter ?',
|
||||
@@ -65,26 +55,20 @@ const fr = {
|
||||
confirm_delete_user_title: 'Supprimer le compte ?',
|
||||
confirm_session_revoke: 'Êtes-vous sûr de vouloir révoquer cette session ?',
|
||||
confirm_your_email_address: 'Confirmez votre adresse e-mail',
|
||||
choose_publishing_option: 'Choisissez comment vous voulez publier votre site web:',
|
||||
contact_us: 'Nous contacter',
|
||||
contact_us_verification_required: "Vous devez disposer d'une adresse e-mail vérifiée pour pouvoir utiliser ceci.",
|
||||
continue: 'Continuer',
|
||||
copy: 'Copier',
|
||||
copy_link: 'Copier le lien',
|
||||
copying: 'Copie...',
|
||||
copying_file: 'Copie de %%...',
|
||||
cpu_cores: 'Cœurs CPU',
|
||||
cpu: 'CPU',
|
||||
create_account: 'Créer un compte',
|
||||
create_free_account: 'Créer un compte gratuitement',
|
||||
create_desktop_shortcut: 'Créer un raccourci (Bureau)',
|
||||
create_desktop_shortcut_s: 'Créer des raccourcis (Bureau)',
|
||||
create_shortcut: 'Créer un raccourci',
|
||||
create_shortcut_s: 'Créer des raccourcis',
|
||||
credits: 'Crédits',
|
||||
current_password: 'Mot de passe actuel',
|
||||
cut: 'Couper',
|
||||
client_information: 'Informations client',
|
||||
close_all: 'Fermer tout',
|
||||
created: 'Créé',
|
||||
date_modified: 'Date de modification',
|
||||
@@ -95,21 +79,13 @@ const fr = {
|
||||
deploy_as_app: "Déployer en tant qu'application",
|
||||
descending: 'Descendant',
|
||||
desktop: 'Bureau',
|
||||
desktop_background_fit: 'Ajuster',
|
||||
developers: 'Développeurs',
|
||||
dir_published_as_website: '%strong% a été publié sur :',
|
||||
disable_2fa: "Désactiver l'A2F",
|
||||
disable_2fa_confirm: "Êtes-vous sûr de vouloir désactiver l'A2F ?",
|
||||
disable_2fa_instructions: "Entrez votre mot de passe pour désactiver l'A2F.",
|
||||
disk_storage: 'Stockage disque',
|
||||
documents: 'Documents',
|
||||
dont_allow: 'Ne pas autoriser',
|
||||
download: 'Télécharger',
|
||||
confirm_download_file_to_desktop: 'Êtes-vous sûr de vouloir télécharger %% sur votre bureau ?',
|
||||
download_file: 'Télécharger le fichier',
|
||||
downloading: 'Téléchargement en cours',
|
||||
downloading_file: 'Téléchargement de %%',
|
||||
error_download_failed: 'Échec du téléchargement du fichier',
|
||||
email: 'E-mail',
|
||||
email_change_confirmation_sent: 'Un e-mail de confirmation a été envoyé à votre nouvelle adresse e-mail. Veuillez vérifier votre boîte de réception et suivre les instructions pour terminer le processus.',
|
||||
email_invalid: 'L\'e-mail n\'est pas valide.',
|
||||
@@ -134,13 +110,10 @@ const fr = {
|
||||
forgot_pass_c2a: 'Mot de passe oublié ?',
|
||||
from: 'Depuis',
|
||||
general: 'Général',
|
||||
get_a_copy_of_on_puter: 'Obtenez une copie de \'%%\' sur Puter.com !',
|
||||
get_copy_link: 'Obtenir le lien de copie',
|
||||
home: 'Accueil',
|
||||
html_document: 'Document HTML',
|
||||
hue: 'Teinte',
|
||||
incorrect_password: 'Mot de passe incorrect',
|
||||
invite_link: "Lien d'invitation",
|
||||
item: 'élément',
|
||||
items_in_trash_cannot_be_renamed: 'Cet élément ne peut pas être renommé car il se trouve dans la corbeille. Pour renommer cet élément, faites-le d\'abord glisser hors de la corbeille.',
|
||||
jpeg_image: 'Image JPEG',
|
||||
@@ -151,7 +124,6 @@ const fr = {
|
||||
loading: 'Chargement',
|
||||
log_in: 'Se connecter',
|
||||
log_out: 'Se déconnecter',
|
||||
looks_good: "Ça a l'air bien !",
|
||||
manage_sessions: 'Gérer les sessions',
|
||||
modified: 'Modifié',
|
||||
move: 'Déplacer',
|
||||
@@ -180,8 +152,6 @@ const fr = {
|
||||
original_name: "Nom d'origine",
|
||||
original_path: "Chemin d'origine",
|
||||
os: 'Système d\'exploitation',
|
||||
oss_code_and_content: 'Logiciels et contenu open source',
|
||||
os_version: 'Version du système d\'exploitation',
|
||||
password: 'Mot de passe',
|
||||
password_changed: 'Mot de passe modifié.',
|
||||
password_recovery_rate_limit: "Vous avez atteint notre limite de débit ; veuillez patienter quelques minutes. Pour éviter cela à l'avenir, évitez de recharger la page trop de fois.",
|
||||
@@ -193,30 +163,22 @@ const fr = {
|
||||
paste: 'Coller',
|
||||
paste_into_folder: 'Coller dans le dossier',
|
||||
path: 'Chemin',
|
||||
personalization: 'Personnalisation',
|
||||
pick_name_for_website: 'Choisissez un nom pour votre site internet :',
|
||||
pictures: 'Images',
|
||||
pixel_ratio: 'Ratio de pixels',
|
||||
plural_suffix: 's',
|
||||
powered_by_puter_js: 'Propulsé par {{link=docs}}Puter.js{{/link}}',
|
||||
preparing: 'Préparation...',
|
||||
preparing_for_upload: "Préparation de l'importation...",
|
||||
print: 'Imprimer',
|
||||
privacy: 'Confidentialité',
|
||||
proceed_to_login: 'Procéder à la connexion',
|
||||
proceed_with_account_deletion: 'Procéder à la suppression du compte',
|
||||
properties: 'Propriétés',
|
||||
public: 'Publique',
|
||||
publish: 'Publier',
|
||||
publish_as_website: 'Publier en tant que site internet',
|
||||
publish_as_serverless_worker: 'Publier en tant que Worker',
|
||||
puter_description: 'Puter est un cloud personnel axé sur la confidentialité pour conserver tous vos fichiers, applications et jeux en un seul endroit sécurisé, accessible de partout et à tout moment.',
|
||||
ram: 'RAM',
|
||||
reading: 'lecture de %strong%',
|
||||
writing: 'écriture de %strong%',
|
||||
recover_password: 'Récupérer le mot de passe',
|
||||
refer_friends_c2a: 'Obtenez 1 Go pour chaque ami qui crée et confirme un compte sur Puter. Votre ami recevra également 1 Go !',
|
||||
refer_friends_social_media_c2a: 'Obtenez 1 Go de stockage gratuit sur Puter.com !',
|
||||
refresh: 'Actualiser',
|
||||
rename: 'Renommer',
|
||||
replace: 'Remplacer',
|
||||
@@ -227,12 +189,9 @@ const fr = {
|
||||
save: 'Sauvegarder',
|
||||
saturation: 'Saturation',
|
||||
save_account: 'Enregistrer le compte',
|
||||
save_account_to_get_copy_link: 'Veuillez créer un compte pour continuer.',
|
||||
save_account_to_publish: 'Veuillez créer un compte pour continuer.',
|
||||
save_session: 'Sauvegarder la session',
|
||||
save_session_c2a: 'Créez un compte pour enregistrer votre session actuelle et éviter de perdre votre travail.',
|
||||
scan_qr_2fa: 'Scannez le code QR avec votre application d\'authentification',
|
||||
screen_resolution: 'Résolution d\'écran',
|
||||
search: 'Rechercher',
|
||||
seconds: 'secondes',
|
||||
security: 'Sécurité',
|
||||
@@ -241,7 +200,6 @@ const fr = {
|
||||
sessions: 'Sessions',
|
||||
send: 'Envoyer',
|
||||
send_password_recovery_email: 'Envoyer un e-mail de récupération de mot de passe',
|
||||
server_information: 'Informations serveur',
|
||||
session_saved: "Merci d'avoir créé un compte. Cette session a été sauvegardée.",
|
||||
settings: 'Paramètres',
|
||||
set_new_password: 'Definir un nouveau mot de passe',
|
||||
@@ -251,22 +209,17 @@ const fr = {
|
||||
show_hidden: 'Afficher les fichiers cachés',
|
||||
sign_in_with_puter: 'Se connecter avec Puter',
|
||||
sign_up: "S'inscrire",
|
||||
signing_in: 'Connexion…',
|
||||
size: 'Taille',
|
||||
skip: 'Passer',
|
||||
something_went_wrong: "Quelque chose s'est mal passé.",
|
||||
sort_by: 'Trier par',
|
||||
status: 'Statut',
|
||||
'Storage': 'Stockage',
|
||||
storage_usage: 'Utilisation du stockage',
|
||||
storage_puter_used: 'utilisé par Puter',
|
||||
'your_plan': 'Votre plan',
|
||||
taking_longer_than_usual: "Cela prend un peu plus de temps que d'habitude. Veuillez patienter...",
|
||||
terms: 'Termes',
|
||||
text_document: 'Document texte',
|
||||
'toolbar.enter_fullscreen': 'Passer en plein écran',
|
||||
'toolbar.github': 'GitHub',
|
||||
'toolbar.refer': 'Parrainer',
|
||||
tos_fineprint: 'En cliquant sur "Créer un compte gratuit", vous acceptez les {{link=terms}}Conditions d\'utilisation{{/link}} et la {{link=privacy}}Politique de confidentialité{{/link}} de Puter.',
|
||||
transparency: 'Transparence',
|
||||
trash: 'Corbeille',
|
||||
@@ -285,7 +238,6 @@ const fr = {
|
||||
untarring: 'Extraction de %strong% (.tar)',
|
||||
upload: 'Importer',
|
||||
uploading: 'Importation en cours',
|
||||
uploading_file: 'Importation de %%',
|
||||
upload_here: 'Importer ici',
|
||||
uptime: 'Temps de disponibilité',
|
||||
used_of: '{{used}} utilisé sur {{available}}',
|
||||
@@ -297,7 +249,6 @@ const fr = {
|
||||
videos: 'Vidéos',
|
||||
visibility: 'Visibilité',
|
||||
yes: 'Oui',
|
||||
you_have_been_referred_to_puter_by_a_friend: 'Vous avez été recommandé à Puter par un ami !',
|
||||
zip: 'Compresser',
|
||||
tar: 'Tar',
|
||||
download_as_tar: 'Télécharger comme Tar',
|
||||
@@ -307,24 +258,19 @@ const fr = {
|
||||
tarring: 'Compression en .tar de %strong%',
|
||||
|
||||
// === 2FA Setup ===
|
||||
setup2fa_1_step_heading: 'Ouvrez votre application d\'authentification',
|
||||
setup2fa_1_instructions: `
|
||||
Vous pouvez utiliser n'importe quelle application d'authentification prenant en charge le protocole TOTP (Time-based One-Time Password).
|
||||
Il y a beaucoup de choix, mais si vous n'êtes pas sûr
|
||||
<a target="_blank" href="https://authy.com/download">Authy</a>
|
||||
est un choix solide pour Android et iOS.
|
||||
`,
|
||||
setup2fa_2_step_heading: 'Scannez le code QR',
|
||||
setup2fa_3_step_heading: 'Entrez le code à 6 chiffres',
|
||||
setup2fa_4_step_heading: 'Copiez vos codes de récupération',
|
||||
setup2fa_4_instructions: `
|
||||
Ces codes de récupération sont le seul moyen d'accéder à votre compte si vous perdez votre téléphone ou si vous ne pouvez pas utiliser votre application d'authentification.
|
||||
Assurez-vous de les conserver dans un endroit sûr.
|
||||
`,
|
||||
setup2fa_5_step_heading: 'Confirmer la configuration de l\'A2F',
|
||||
setup2fa_5_confirmation_1: "J'ai enregistré mes codes de récupération dans un emplacement sécurisé",
|
||||
setup2fa_5_confirmation_2: "Je suis prêt à activer l'A2F",
|
||||
setup2fa_5_button: "Activer l'A2F",
|
||||
|
||||
// === 2FA Login ===
|
||||
login2fa_otp_title: 'Entrez le code A2F',
|
||||
@@ -332,7 +278,6 @@ const fr = {
|
||||
login2fa_recovery_title: 'Entrez un code de récupération',
|
||||
login2fa_recovery_instructions: "Entrez l'un de vos codes de récupération pour accéder à votre compte.",
|
||||
login2fa_use_recovery_code: 'Utiliser un code de récupération',
|
||||
login2fa_recovery_back: 'Retour',
|
||||
login2fa_recovery_placeholder: 'XXXXXXXX',
|
||||
|
||||
// Sharing
|
||||
@@ -393,7 +338,6 @@ const fr = {
|
||||
'billing.expanded': 'Étendu',
|
||||
'billing.accelerated': 'Accéléré',
|
||||
'billing.enjoy_msg': "Profitez de %% de stockage Cloud ainsi que d'autres avantages.",
|
||||
'too_many_attempts': 'Trop de tentatives. Veuillez réessayer plus tard.',
|
||||
'server_timeout': 'Le serveur a mis trop de temps à répondre. Veuillez réessayer.',
|
||||
'signup_error': 'Une erreur est survenue lors de l\'inscription. Veuillez réessayer.',
|
||||
|
||||
@@ -421,19 +365,14 @@ const fr = {
|
||||
'window_title_open': 'Ouvrir',
|
||||
'window_title_change_password': 'Changer le mot de passe',
|
||||
'window_title_select_font': 'Sélectionner la police…',
|
||||
'window_title_session_list': 'Liste des sessions !',
|
||||
'window_title_set_new_password': 'Définir un nouveau mot de passe',
|
||||
'window_title_publish_website': 'Publier le site web',
|
||||
'window_title_publish_worker': 'Publier le worker',
|
||||
'window_title_authenticating': 'Authentification en cours...',
|
||||
'window_title_refer_friend': 'Parrainer un ami !',
|
||||
|
||||
// Desktop UI
|
||||
'desktop_exit_full_screen': 'Quitter le mode plein écran',
|
||||
'desktop_enter_full_screen': 'Passer en plein écran',
|
||||
|
||||
// Item UI
|
||||
'item_shared_with_you': 'Un utilisateur a partagé cet élément avec vous.',
|
||||
'item_shared_by_you': 'Vous avez partagé cet élément avec au moins un autre utilisateur.',
|
||||
'item_shortcut': 'Raccourci',
|
||||
'item_associated_websites': 'Site web associé',
|
||||
@@ -444,9 +383,6 @@ const fr = {
|
||||
'window_click_to_go_back': 'Cliquez pour revenir en arrière.',
|
||||
'window_click_to_go_forward': 'Cliquez pour avancer.',
|
||||
'window_click_to_go_up': 'Cliquez pour remonter d\'un répertoire.',
|
||||
'window_title_public': 'Publique',
|
||||
'window_title_videos': 'Vidéos',
|
||||
'window_title_pictures': 'Images',
|
||||
'window_title_puter': 'Puter',
|
||||
'window_folder_empty': 'Ce dossier est vide',
|
||||
|
||||
@@ -461,23 +397,17 @@ const fr = {
|
||||
'perm_subdomains_write': 'gérer vos sous-domaines',
|
||||
|
||||
'error_user_or_path_not_found': 'Utilisateur ou chemin introuvable.',
|
||||
'error_invalid_username': 'Nom d\'utilisateur invalide.',
|
||||
|
||||
// Auth token
|
||||
auth_token: 'Jeton d\'authentification',
|
||||
token_copied: 'Jeton copié',
|
||||
copy_auth_token: 'Copier le jeton d\'auth',
|
||||
approve: 'Approuver',
|
||||
copy_token_message: 'Votre jeton d\'authentification est affiché ci-dessous. Gardez-le secret — toute personne possédant ce jeton peut accéder à votre compte.',
|
||||
copy_token_description: 'Voir et copier votre jeton d\'authentification',
|
||||
|
||||
// AuthMe dialog
|
||||
authorization_required: 'Autorisation requise',
|
||||
external_site_auth_request: 'Une application demande l\'accès à votre compte.',
|
||||
authme_security_warning: 'Votre jeton d\'authentification sera partagé avec cette application pour terminer la connexion.',
|
||||
redirect_destination: 'Destination de redirection',
|
||||
will_be_shared: 'Sera partagé',
|
||||
your_auth_token: 'Votre jeton d\'authentification',
|
||||
authorization_cancelled: 'Autorisation annulée',
|
||||
authorization_cancelled_desc: 'Vous avez refusé la demande d\'autorisation.',
|
||||
authorization_cancelled_message: 'L\'application ne recevra pas l\'accès à votre compte. Vous pouvez fermer cette fenêtre en toute sécurité.',
|
||||
|
||||
@@ -31,7 +31,6 @@ const he = {
|
||||
allow: 'להרשות',
|
||||
ascending: 'בסדר עולה',
|
||||
associated_websites: 'אתרים קשורים',
|
||||
auto_arrange: 'סידור אוטומטי',
|
||||
cancel: 'ביטול',
|
||||
change_email: 'שינוי כתובת אימייל',
|
||||
change_language: 'החלפת שפה',
|
||||
@@ -41,19 +40,12 @@ const he = {
|
||||
close_all_windows_and_log_out: 'סגור את החלונות והתנתק',
|
||||
change_always_open_with: 'האם אתה רוצה תמיד לפתוח סוג זה של קובץ עם',
|
||||
confirm: 'לאשר',
|
||||
confirm_2fa_setup: 'הוספתי את הקוד לאפליקצית האימות שלי',
|
||||
confirm_2fa_recovery: 'שמרתי את קודי השחזור שלי במיקום מאובטח',
|
||||
confirm_account_for_free_referral_storage_c2a:
|
||||
'צור חשבון ואשר את כתובת הדוא"ל שלך כדי לקבל 1 גיגה בייט של אחסון בחינם. חברך יקבל גם 1 גיגה בייט של אחסון בחינם.',
|
||||
confirm_code_generic_incorrect: 'קוד שגוי.',
|
||||
confirm_code_generic_too_many_requests:
|
||||
'יותר מדי בקשות. אנא המתינו מספר דקות.',
|
||||
confirm_code_generic_submit: 'שלח קוד',
|
||||
confirm_code_generic_try_again: 'נסה שוב',
|
||||
confirm_code_generic_title: 'הזן קוד אישור',
|
||||
confirm_code_2fa_instruction: 'הזינו את הקוד בן 6 הספרות מאפליקציית המאמת.',
|
||||
confirm_code_2fa_submit_btn: 'שלח',
|
||||
confirm_code_2fa_title: 'הזינו קוד אימות דו-שלבי',
|
||||
confirm_delete_multiple_items:
|
||||
'האם אתה בטוח שברצונך למחוק פריטים אלה לצמיתות?',
|
||||
confirm_delete_single_item: 'האם ברצונך למחוק פריט זה לצמיתות?',
|
||||
@@ -66,8 +58,6 @@ const he = {
|
||||
confirm_session_revoke: '?האם אתה בטוח שברצונך לבטל חיבור פעיל זה',
|
||||
confirm_your_email_address: 'אשר את כתובת האימייל שלך',
|
||||
contact_us: 'צור קשר',
|
||||
contact_us_verification_required:
|
||||
'עליך להיות בעל כתובת אימייל מאומתת כדי להשתמש בזה.',
|
||||
continue: 'המשיך',
|
||||
copy: 'העתק',
|
||||
copy_link: 'העתק קישור',
|
||||
@@ -89,17 +79,13 @@ const he = {
|
||||
deploy_as_app: 'לפרוס כאפליקציה',
|
||||
descending: 'בסדר יורד',
|
||||
desktop: 'שולחן העבודה ',
|
||||
desktop_background_fit: 'התאים',
|
||||
developers: 'מפתחים',
|
||||
dir_published_as_website: '%strong% פורסם ל:',
|
||||
disable_2fa: 'השבתת אימות דו-שלבי',
|
||||
disable_2fa_confirm: 'האם אתם בטוחים שברצונכם להשבית אימות דו-שלבי?',
|
||||
disable_2fa_instructions: 'הזינו את הסיסמה שלכם כדי להשבית אימות דו-שלבי.',
|
||||
documents: 'מסמכים',
|
||||
dont_allow: 'אל תאפשר',
|
||||
download: 'הורדה',
|
||||
download_file: 'הורדת קובץ',
|
||||
downloading: 'מוריד',
|
||||
email: 'אימייל',
|
||||
email_change_confirmation_sent:
|
||||
'אימייל אישור נשלח לכתובת האימייל החדשה שלך. אנא בדוק את תיבת הדואר הנכנס ופעל לפי ההוראות להשלמת התהליך.',
|
||||
@@ -128,13 +114,10 @@ const he = {
|
||||
forgot_pass_c2a: 'שכחת את הסיסמא?',
|
||||
from: 'טופס',
|
||||
general: 'כללי',
|
||||
get_a_copy_of_on_puter: 'קבל עותק של \'%%\' ב Puter.com!',
|
||||
get_copy_link: 'קבל העתק קישור',
|
||||
home: 'בית',
|
||||
html_document: 'מסמך HTML',
|
||||
hue: 'דרגת צבע',
|
||||
incorrect_password: 'סיסמה שגויה',
|
||||
invite_link: 'קישור הזמנה',
|
||||
item: 'פריט',
|
||||
items_in_trash_cannot_be_renamed: 'לא ניתן לשנות את שם הפריט הזה כי הוא נמצא באשפה. כדי לשנות את שם הפריט הזה, תחילה גרור אותו מחוץ לאשפה.',
|
||||
jpeg_image: 'JPEG תמונת',
|
||||
@@ -145,7 +128,6 @@ const he = {
|
||||
loading: 'טוען',
|
||||
log_in: 'התחברות',
|
||||
log_out: 'התנתק',
|
||||
looks_good: 'נראה טוב!',
|
||||
manage_sessions: 'ניהול חיבורים פעילים',
|
||||
modified: 'שונה',
|
||||
move: 'לעבור',
|
||||
@@ -170,7 +152,6 @@ const he = {
|
||||
open_with: 'לפתוח באמצעות',
|
||||
original_name: 'שם מקורי',
|
||||
original_path: 'מסלול מקורי',
|
||||
oss_code_and_content: 'תוכנה ותוכן בקוד פתוח',
|
||||
password: 'סיסמה',
|
||||
password_changed: 'הסיסמה השתנתה.',
|
||||
password_recovery_rate_limit:
|
||||
@@ -185,27 +166,20 @@ const he = {
|
||||
paste: 'הדבק',
|
||||
paste_into_folder: 'הדבק בתיקיה',
|
||||
path: 'מסלול',
|
||||
personalization: 'התאמה אישית',
|
||||
pick_name_for_website: 'בחר שם לאתר האינטרנט שלך:',
|
||||
pictures: 'תמונות',
|
||||
plural_suffix: 's',
|
||||
powered_by_puter_js: 'מונע ע"י {{link=docs}}Puter.js{{/link}}',
|
||||
preparing: 'מכין...',
|
||||
preparing_for_upload: 'מתכוננים להעלאה...',
|
||||
print: 'הדפס',
|
||||
privacy: 'פרטיות',
|
||||
proceed_to_login: 'המשך לכניסה',
|
||||
proceed_with_account_deletion: 'המשך למחיקת חשבון',
|
||||
properties: 'תכונות',
|
||||
public: 'ציבורי',
|
||||
publish: 'פרסם',
|
||||
publish_as_website: 'פרסום כאתר אינטרנט',
|
||||
puter_description: 'הוא ענן אישי ששם את הפרטיות בראש סדר העדיפויות כדי לשמור על כל הקבצים, המשחקים, והיישומים שלך במקום מאובטח אחד, נגיש מכל מקום ובכל זמן Puter',
|
||||
reading_file: 'קורא %strong%',
|
||||
recover_password: 'שחזור סיסמה',
|
||||
refer_friends_c2a:
|
||||
'קבל 1 גיגה בייט עבור כל חבר שיוצר ומאשר חשבון ב Puter. גם החבר שלך יקבל 1 גיגה בייט!',
|
||||
refer_friends_social_media_c2a: 'קבל שטח אחסון של 1 גיגה בייט בחינם Puter.com!',
|
||||
refresh: 'רענן',
|
||||
rename: 'שנה שם',
|
||||
replace: 'החלף',
|
||||
@@ -215,12 +189,10 @@ const he = {
|
||||
save: 'שמירה',
|
||||
saturation: 'סטורציה',
|
||||
save_account: 'שמירת חשבון',
|
||||
save_account_to_get_copy_link: 'אנא צור חשבון כדי להמשיך.',
|
||||
save_account_to_publish: 'אנא צור חשבון כדי להמשיך.',
|
||||
save_session: 'שמירת חיבור',
|
||||
save_session_c2a:
|
||||
'צור חשבון כדי לשמור את החיבור הנוכחי שלך ולהימנע מאובדן העבודה שלך.',
|
||||
scan_qr_2fa: 'סרוק את קוד ה- QR באמצעות אפליקציית האימות שלך',
|
||||
search: 'חיפוש',
|
||||
seconds: 'שניות',
|
||||
security: 'אבטחה',
|
||||
@@ -238,13 +210,11 @@ const he = {
|
||||
show_hidden: 'הצג מוסתר',
|
||||
sign_in_with_puter: 'להתחבר עם Puter',
|
||||
sign_up: 'הרשמה',
|
||||
signing_in: 'התחברות…',
|
||||
size: 'גודל',
|
||||
skip: 'דלג',
|
||||
something_went_wrong: 'משהו השתבש.',
|
||||
sort_by: 'מיין לפי',
|
||||
status: 'סטטוס',
|
||||
storage_usage: 'שימוש באחסון',
|
||||
storage_puter_used: 'Puter בשימוש על ידי',
|
||||
taking_longer_than_usual: 'לוקח קצת יותר זמן מהרגיל. חכה בבקשה...',
|
||||
terms: 'תנאים',
|
||||
@@ -272,29 +242,23 @@ const he = {
|
||||
videos: 'סרטונים',
|
||||
visibility: 'נראות',
|
||||
yes: 'כן',
|
||||
you_have_been_referred_to_puter_by_a_friend: 'הופנית אל Puter על ידי חבר!',
|
||||
zip: 'מכווץ',
|
||||
zipping_file: 'מכווץ קובץ %strong%',
|
||||
|
||||
// === 2FA Setup ===
|
||||
setup2fa_1_step_heading: 'פתחו את אפליקציית המאמת',
|
||||
setup2fa_1_instructions: `
|
||||
אתה יכול להשתמש בכל אפליקציית אימות התומכת בפרוטוקול סיסמה חד פעמית מבוססת זמן (TOTP).
|
||||
יש הרבה לבחירה, אבל אם אתה לא בטוח
|
||||
<a target="_blank" href="https://authy.com/download">Authy</a>
|
||||
היא בחירה סולידית עבור אנדרואיד ו- iOS.
|
||||
`,
|
||||
setup2fa_2_step_heading: 'סרוק את קוד ה- QR',
|
||||
setup2fa_3_step_heading: 'הזן את הקוד בן 6 הספרות',
|
||||
setup2fa_4_step_heading: 'העתק את קודי השחזור שלך',
|
||||
setup2fa_4_instructions: `
|
||||
קודי שחזור אלו הם הדרך היחידה לגשת לחשבון שלך במידה של איבוד הטלפון או אי יכולת שימוש באפליקציית המאמת .
|
||||
הקפד לאחסן אותם במקום בטוח.
|
||||
`,
|
||||
setup2fa_5_step_heading: 'אשר את הגדרת האימות הדו-שלבי',
|
||||
setup2fa_5_confirmation_1: 'שמרתי את קודי השחזור שלי במיקום מאובטח',
|
||||
setup2fa_5_confirmation_2: 'אני מוכן להפעיל אימות דו-שלבי',
|
||||
setup2fa_5_button: 'הפעלת אימות דו-שלבי',
|
||||
|
||||
// === 2FA Login ===
|
||||
login2fa_otp_title: 'הזינו קוד אימות דו-שלבי',
|
||||
@@ -303,7 +267,6 @@ const he = {
|
||||
login2fa_recovery_instructions:
|
||||
'הזן אחד מקודי השחזור שלך כדי לגשת לחשבון שלך.',
|
||||
login2fa_use_recovery_code: 'שימוש בקוד שחזור',
|
||||
login2fa_recovery_back: 'לאחור',
|
||||
login2fa_recovery_placeholder: 'XXXXXXXX',
|
||||
|
||||
'change': 'שנה', // In English: "Change"
|
||||
@@ -367,20 +330,13 @@ const he = {
|
||||
'billing.expanded': 'מורחב', // In English: "Expanded"
|
||||
'billing.accelerated': 'מואץ', // In English: "Accelerated"
|
||||
'billing.enjoy_msg': 'תהנו מ %% של אחסון ענן בנוסף להטבות נוספות', // In English: "Enjoy %% of Cloud Storage plus other benefits."
|
||||
'choose_publishing_option': 'בחר כיצד לפרסם את האתר שלך', // In English: "Choose how you want to publish your website:"
|
||||
'create_desktop_shortcut': 'צור קיצור דרך (שולחן עבודה)', // In English: "Create Shortcut (Desktop)"
|
||||
'create_desktop_shortcut_s': 'צור קיצורי דרך (שולחן עבודה)', // In English: "Create Shortcuts (Desktop)"
|
||||
'create_shortcut_s': 'צור קיצורי דרך', // In English: "Create Shortcuts"
|
||||
'minimize': 'מזער', // In English: "Minimize"
|
||||
'reload_app': 'טען מחדש', // In English: "Reload App"
|
||||
'publish_as_serverless_worker': 'פרסם כעובד', // In English: "Publish as Worker"
|
||||
'toolbar.enter_fullscreen': 'מסך מלא', // In English: "Enter Full Screen"
|
||||
'toolbar.github': 'גיטהאב', // In English: "GitHub"
|
||||
'toolbar.refer': 'הפנה', // In English: "Refer"
|
||||
'used_of': '{{available}} משומש מתוך {{used}}', // In English: "{{used}} used of {{available}}"
|
||||
'worker': 'עובד', // In English: "Worker"
|
||||
'billing.offering.basic': 'בסיסי', // In English: "Basic"
|
||||
'too_many_attempts': '.יותר מדי נסיונות. אנא נסה מאוחר יותר', // In English: "Too many attempts. Please try again later."
|
||||
'server_timeout': '.לשרת לקח זמן רב מדי להגיב. אנא נסה שנית', // In English: "The server took too long to respond. Please try again."
|
||||
'signup_error': '.ארעה תקלה בעת ההרשמה. אנא נסה שנית', // In English: "An error occurred during signup. Please try again."
|
||||
'alert_error_title': '!תקלה', // In English: "Error!"
|
||||
@@ -398,15 +354,10 @@ const he = {
|
||||
'window_title_open': 'פתח', // In English: "Open"
|
||||
'window_title_change_password': 'שנה סיסמא', // In English: "Change Password"
|
||||
'window_title_select_font': '...בחר גופן', // In English: "Select font…"
|
||||
'window_title_session_list': 'רשימת חיבורים', // In English: "Session List!"
|
||||
'window_title_set_new_password': 'בחר סיסמא חדשה', // In English: "Set New Password"
|
||||
'window_title_publish_website': 'פרסם אתר', // In English: "Publish Website"
|
||||
'window_title_publish_worker': 'פרסם עובד', // In English: "Publish Worker"
|
||||
'window_title_authenticating': 'מאמת', // In English: "Authenticating..."
|
||||
'window_title_refer_friend': '!הפנה חבר', // In English: "Refer a friend!"
|
||||
'desktop_exit_full_screen': 'בטל מסך מלא', // In English: "Exit Full Screen"
|
||||
'desktop_enter_full_screen': 'הפעל מסך מלא', // In English: "Enter Full Screen"
|
||||
'item_shared_with_you': 'משתמש שיתף עמך פריט זה', // In English: "A user has shared this item with you."
|
||||
'item_shared_by_you': 'שיתפת פריט זה עם לפחות משתמש אחד נוסף', // In English: "You have shared this item with at least one other user."
|
||||
'item_shortcut': 'קיצור דרך', // In English: "Shortcut"
|
||||
'item_associated_websites': 'אתר משויך', // In English: "Associated website"
|
||||
@@ -415,9 +366,6 @@ const he = {
|
||||
'window_click_to_go_back': 'לחץ כדי לחזור', // In English: "Click to go back."
|
||||
'window_click_to_go_forward': 'לחץ כדי להתקדם', // In English: "Click to go forward."
|
||||
'window_click_to_go_up': 'לחץ כדי לעלות ספרייה אחת מעלה', // In English: "Click to go one directory up."
|
||||
'window_title_public': 'ציבורי', // In English: "Public"
|
||||
'window_title_videos': 'סרטונים', // In English: "Videos"
|
||||
'window_title_pictures': 'תמונות', // In English: "Pictures"
|
||||
'window_title_puter': 'Puter', // In English: "Puter"
|
||||
'window_folder_empty': 'תיקייה זו ריקה', // In English: "This folder is empty"
|
||||
},
|
||||
|
||||
@@ -31,7 +31,6 @@ const hi = {
|
||||
allow: 'अनुमति दें',
|
||||
ascending: 'आरोही',
|
||||
associated_websites: 'संबंधित वेबसाइटें',
|
||||
auto_arrange: 'स्वचालित व्यवस्तित',
|
||||
cancel: 'रद्द',
|
||||
change_email: 'ई - मेल बदले',
|
||||
change_language: 'भाषा बदलें',
|
||||
@@ -40,17 +39,10 @@ const hi = {
|
||||
close: 'बंद ',
|
||||
close_all_windows_and_log_out: 'विंडोज़ बंद करें और लॉग आउट करें',
|
||||
change_always_open_with: 'क्या आप इस प्रकार की फ़ाइल को हमेशा खोलना चाहते हैं?',
|
||||
confirm_2fa_setup: 'मैंने अपने प्रमाणक ऐप में कोड जोड़ दिया है',
|
||||
confirm_2fa_recovery: 'मैंने अपने पुनर्प्राप्ति कोड सुरक्षित स्थान पर सहेजे हैं',
|
||||
confirm_account_for_free_referral_storage_c2a: 'एक खाता बनाएं और 1 जीबी निःशुल्क संग्रहण प्राप्त करने के लिए अपने ईमेल पते की पुष्टि करें। आपके दोस्त को भी 1 जीबी मुफ्त स्टोरेज मिलेगा।',
|
||||
confirm_code_generic_incorrect: 'गलत कोड़।',
|
||||
confirm_code_generic_too_many_requests: 'बहुत सारे अनुरोध. कृपया कुछ मिनट प्रतीक्षा करें.',
|
||||
confirm_code_generic_submit: 'कोड जमा करें',
|
||||
confirm_code_generic_try_again: 'पुनः प्रयास करें',
|
||||
confirm_code_generic_title: 'पुष्टि कोड दर्ज करें',
|
||||
confirm_code_2fa_instruction: 'अपने प्रमाणक ऐप से 6 अंकों का कोड दर्ज करें।',
|
||||
confirm_code_2fa_submit_btn: 'जमा करें',
|
||||
confirm_code_2fa_title: '2FA कोड दर्ज करें',
|
||||
confirm_delete_multiple_items: 'क्या आप वाकई इन वस्तुओं को स्थायी रूप से हटाना चाहते हैं?',
|
||||
confirm_delete_single_item: 'क्या आप वाकई इस वस्तु को स्थायी रूप से हटाना चाहते हैं?',
|
||||
confirm_open_apps_log_out: 'आपके पास ऐप्स खुला हैं. क्या आप लॉग आउट करना चाहते हैं?',
|
||||
@@ -60,7 +52,6 @@ const hi = {
|
||||
confirm_session_revoke: 'क्या आप वाकई इस सत्र को रद्द करना चाहते हैं?',
|
||||
confirm_your_email_address: 'अपने ईमेल पते की पुष्टि करें',
|
||||
contact_us: 'संपर्क करें',
|
||||
contact_us_verification_required: 'इसका उपयोग करने के लिए आपके पास एक सत्यापित ईमेल पता होना चाहिए।',
|
||||
continue: 'निरंतर',
|
||||
copy: 'प्रतिलिपि',
|
||||
copy_link: 'लिंक की प्रतिलिपि करें',
|
||||
@@ -82,17 +73,13 @@ const hi = {
|
||||
deploy_as_app: 'ऐप के रूप में तैनात करें',
|
||||
descending: 'अवरोही',
|
||||
desktop: 'डेस्कटॉप',
|
||||
desktop_background_fit: 'उपयुक्त',
|
||||
developers: 'डेवलपर्स',
|
||||
dir_published_as_website: 'निर्देशिका को एक वेबसाइट के रूप में प्रकाशित किया गया है',
|
||||
disable_2fa: '2एफए गायब करें',
|
||||
disable_2fa_confirm: 'क्या आप वाकई 2एफए को गायब करना चाहते हैं?',
|
||||
disable_2fa_instructions: '2एफए को गायब करने के लिए अपना पासवर्ड दर्ज करें।',
|
||||
documents: 'दस्तावेज़',
|
||||
dont_allow: 'अनुमति न दें',
|
||||
download: 'डाउनलोड',
|
||||
download_file: 'डाउनलोड फ़ाइल',
|
||||
downloading: 'डाउनलोड हो रहा है',
|
||||
email: 'ईमेल',
|
||||
email_change_confirmation_sent: 'आपके नए ईमेल पते पर एक पुष्टिकरण ईमेल भेज दिया गया है। कृपया अपना इनबॉक्स जांचें और प्रक्रिया पूरी करने के लिए निर्देशों का पालन करें।',
|
||||
email_invalid: 'ईमेल अमान्य है।',
|
||||
@@ -117,13 +104,10 @@ const hi = {
|
||||
forgot_pass_c2a: 'पासवर्ड भूल गए?',
|
||||
from: 'से',
|
||||
general: 'सामान्य',
|
||||
get_a_copy_of_on_puter: "Purer.com पर '%%' की एक कॉपी प्राप्त करें!",
|
||||
get_copy_link: 'कॉपी लिंक प्राप्त करें',
|
||||
home: 'घर',
|
||||
html_document: 'एचटीएमएल दस्तावेज़',
|
||||
hue: 'रंग',
|
||||
incorrect_password: 'गलत पासवर्ड',
|
||||
invite_link: 'लिंक आमंत्रित करें',
|
||||
item: 'वस्तु',
|
||||
items_in_trash_cannot_be_renamed: 'इस वस्तु का नाम नहीं बदला जा सकता क्योंकि यह कूड़ेदान में है। इस वस्तु का नाम बदलने के लिए, पहले इसे ट्रैश से बाहर खींचें।',
|
||||
jpeg_image: 'जेपीईजी छवि',
|
||||
@@ -134,7 +118,6 @@ const hi = {
|
||||
loading: 'लोड हो रहा है',
|
||||
log_in: 'लॉग इन करें',
|
||||
log_out: 'लॉग आउट',
|
||||
looks_good: 'अच्छा लग रहा है!',
|
||||
manage_sessions: 'सत्र प्रबंधित करें',
|
||||
modified: 'संशोधित',
|
||||
move: 'बदले',
|
||||
@@ -159,7 +142,6 @@ const hi = {
|
||||
open_with: 'के साथ खोलें',
|
||||
original_name: 'वास्तविक नाम',
|
||||
original_path: 'वास्तविक पथ',
|
||||
oss_code_and_content: 'ओपन सोर्स सॉफ्टवेयर और सामग्री',
|
||||
password: 'पासवर्ड',
|
||||
password_changed: 'पासवर्ड बदला गया।',
|
||||
password_recovery_rate_limit: 'आप हमारी दर-सीमा तक पहुंच गए हैं; कृपया कुछ मिनट प्रतीक्षा करें. भविष्य में इसे रोकने के लिए, पृष्ठ को कई बार पुनः लोड करने से बचें।',
|
||||
@@ -171,26 +153,19 @@ const hi = {
|
||||
paste: 'पेस्ट करें',
|
||||
paste_into_folder: 'फ़ोल्डर में पेस्ट करें',
|
||||
path: 'पथ',
|
||||
personalization: 'वैयक्तिकरण',
|
||||
pick_name_for_website: 'अपनी वेबसाइट के लिए एक नाम चुनें:',
|
||||
pictures: 'चित्रों',
|
||||
plural_suffix: 'एस',
|
||||
powered_by_puter_js: '{{link=docs}}Puter.js{{/link}} द्वारा संचालित',
|
||||
preparing: 'तैयार कर रहे हैं...',
|
||||
preparing_for_upload: 'अपलोड करने की तैयारी है...',
|
||||
print: 'छाप',
|
||||
privacy: 'गोपनीयता',
|
||||
proceed_to_login: 'लॉगिन करने के लिए आगे बढ़ें',
|
||||
proceed_with_account_deletion: 'खाता हटाने के साथ आगे बढ़ें',
|
||||
properties: 'गुण',
|
||||
public: 'लोग',
|
||||
publish: 'प्रकाशित',
|
||||
publish_as_website: 'वेबसाइट के रूप में प्रकाशित करें',
|
||||
puter_description: 'पुटर एक गोपनीयता-प्रथम व्यक्तिगत क्लाउड है जो आपकी सभी फ़ाइलों, ऐप्स और गेम को एक सुरक्षित स्थान पर रखता है, जिसे किसी भी समय कहीं से भी एक्सेस किया जा सकता है।',
|
||||
reading_file: 'पढ़ना %strong%',
|
||||
recover_password: 'पासवर्ड वापस लाये',
|
||||
refer_friends_c2a: 'पुटर पर खाता बनाने और पुष्टि करने वाले प्रत्येक मित्र के लिए 1 जीबी प्राप्त करें। आपके दोस्त को भी मिलेगा 1 जीबी!',
|
||||
refer_friends_social_media_c2a: 'Purer.com पर 1 जीबी निःशुल्क स्टोरेज प्राप्त करें!',
|
||||
refresh: 'ताजा करना ',
|
||||
rename: 'नाम बदलें',
|
||||
replace: 'प्रतिस्थापित करें',
|
||||
@@ -200,11 +175,9 @@ const hi = {
|
||||
save: 'सहेजें',
|
||||
saturation: 'परिपूर्णता',
|
||||
save_account: 'खाता सहेजें',
|
||||
save_account_to_get_copy_link: 'कृपया आगे बढ़ने के लिए एक खाता बनाएँ।',
|
||||
save_account_to_publish: 'कृपया आगे बढ़ने के लिए एक खाता बनाएँ।',
|
||||
save_session: 'सत्र को बचाए',
|
||||
save_session_c2a: 'अपने वर्तमान सत्र को सहेजने और अपना काम खोने से बचने के लिए एक खाता बनाएं।',
|
||||
scan_qr_2fa: 'अपने प्रमाणक ऐप से क्यूआर कोड को स्कैन करें',
|
||||
search: 'खोजे',
|
||||
seconds: 'सेकंड',
|
||||
security: 'सुरक्षा',
|
||||
@@ -222,13 +195,11 @@ const hi = {
|
||||
show_hidden: 'छिपा हुआ दिखाएं',
|
||||
sign_in_with_puter: 'पुटर के साथ साइन इन करें',
|
||||
sign_up: 'साइन अप करें',
|
||||
signing_in: 'साइन कर रहे हैं…',
|
||||
size: 'आकार',
|
||||
skip: 'छोडना',
|
||||
something_went_wrong: 'कुछ गलत हो गया।',
|
||||
sort_by: 'इसके अनुसार क्रमबद्ध करें',
|
||||
status: 'स्थिति',
|
||||
storage_usage: 'भंडारण उपयोग',
|
||||
storage_puter_used: 'पुटर द्वारा उपयोग किया गया',
|
||||
taking_longer_than_usual: 'सामान्य से थोड़ा अधिक समय लग रहा है. कृपया प्रतीक्षा करें...',
|
||||
terms: 'Terms',
|
||||
@@ -256,21 +227,15 @@ const hi = {
|
||||
videos: 'वीडियो',
|
||||
visibility: 'दृश्यता',
|
||||
yes: 'हाँ',
|
||||
you_have_been_referred_to_puter_by_a_friend: 'आपको एक मित्र ने पुटर के बारे में बताया है!',
|
||||
zip: 'ज़िप',
|
||||
zipping_file: 'ज़िपिंग %strong%',
|
||||
|
||||
// === 2FA Setup ===
|
||||
setup2fa_1_step_heading: 'अपना प्रमाणक ऐप खोलें',
|
||||
setup2fa_1_instructions: "आप किसी भी प्रमाणक ऐप का उपयोग कर सकते हैं जो टाइम-आधारित वन-टाइम पासवर्ड (टीओटीपी) प्रोटोकॉल का समर्थन करता है।चुनने के लिए बहुत कुछ है, लेकिन यदि आप अनिश्चित हैं <a target='_blank' href='https://authy.com/download'>Authy</a>Android और iOS के लिए एक ठोस विकल्प है",
|
||||
setup2fa_2_step_heading: 'क्यूआर कोड को स्कैन करें',
|
||||
setup2fa_3_step_heading: '6 अंकीय कोड दर्ज करें',
|
||||
setup2fa_4_step_heading: 'अपने पुनर्प्राप्ति कोड कॉपी करें',
|
||||
setup2fa_4_instructions: 'यदि आप अपना फ़ोन खो देते हैं या अपने प्रमाणक ऐप का उपयोग नहीं कर पाते हैं तो ये पुनर्प्राप्ति कोड आपके खाते तक पहुंचने का एकमात्र तरीका हैं।उन्हें सुरक्षित स्थान पर संग्रहित करना सुनिश्चित करें।',
|
||||
setup2fa_5_step_heading: '2एफए सेटअप की पुष्टि करें',
|
||||
setup2fa_5_confirmation_1: 'मैंने अपने पुनर्प्राप्ति कोड सुरक्षित स्थान पर सहेजे हैं',
|
||||
setup2fa_5_confirmation_2: 'मैं 2एफए सक्षम करने के लिए तैयार हूं',
|
||||
setup2fa_5_button: '2एफए सक्षम करें',
|
||||
|
||||
// === 2FA Login ===
|
||||
login2fa_otp_title: '2एफए कोड दर्ज करें',
|
||||
@@ -278,7 +243,6 @@ const hi = {
|
||||
login2fa_recovery_title: 'एक पुनर्प्राप्ति कोड दर्ज करें',
|
||||
login2fa_recovery_instructions: 'अपने खाते तक पहुंचने के लिए अपना एक पुनर्प्राप्ति कोड दर्ज करें।',
|
||||
login2fa_use_recovery_code: 'पुनर्प्राप्ति कोड का उपयोग करें',
|
||||
login2fa_recovery_back: 'पीछे',
|
||||
login2fa_recovery_placeholder: 'XXXXXXXX',
|
||||
|
||||
'change': 'बदलें', // In English: "Change"
|
||||
@@ -344,20 +308,13 @@ const hi = {
|
||||
'billing.accelerated': 'त्वरित ', // In English: "Accelerated"
|
||||
'billing.enjoy_msg': '%% क्लाउड स्टोरेज का आनंद लें और अन्य लाभ प्राप्त करें।', // In English: "Enjoy %% of Cloud Storage plus other benefits."
|
||||
|
||||
'choose_publishing_option': 'अपनी वेबसाइट को कैसे प्रकाशित करना चाहते हैं, चुनें:', // In English: "Choose how you want to publish your website:"
|
||||
'create_desktop_shortcut': 'शॉर्टकट बनाएँ (डेस्कटॉप)', // In English: "Create Shortcut (Desktop)"
|
||||
'create_desktop_shortcut_s': 'शॉर्टकट्स बनाएँ (डेस्कटॉप)', // In English: "Create Shortcuts (Desktop)"
|
||||
'create_shortcut_s': 'शॉर्टकट्स बनाएँ', // In English: "Create Shortcuts"
|
||||
'minimize': 'मिनिमाइज़ करें', // In English: "Minimize"
|
||||
'reload_app': 'ऐप पुनः लोड करें', // In English: "Reload App"
|
||||
'publish_as_serverless_worker': 'वर्कर के रूप में प्रकाशित करें', // In English: "Publish as Worker"
|
||||
'toolbar.enter_fullscreen': 'पूर्ण स्क्रीन में जाएँ', // In English: "Enter Full Screen"
|
||||
'toolbar.github': 'GitHub', // In English: "GitHub"
|
||||
'toolbar.refer': 'रेफ़र', // In English: "Refer"
|
||||
'used_of': '{{available}} में से {{used}} उपयोग', // In English: "{{used}} used of {{available}}"
|
||||
'worker': 'वर्कर', // In English: "Worker"
|
||||
'billing.offering.basic': 'मूल', // In English: "Basic"
|
||||
'too_many_attempts': 'बहुत अधिक प्रयास। कृपया बाद में पुनः प्रयास करें।', // In English: "Too many attempts. Please try again later."
|
||||
'server_timeout': 'सर्वर को उत्तर देने में बहुत समय लगा। कृपया फिर से प्रयास करें।', // In English: "The server took too long to respond. Please try again."
|
||||
'signup_error': 'साइन अप करते समय एक त्रुटि हुई। कृपया पुनः प्रयास करें।', // In English: "An error occurred during signup. Please try again."
|
||||
'alert_error_title': 'त्रुटि!', // In English: "Error!"
|
||||
@@ -375,15 +332,10 @@ const hi = {
|
||||
'window_title_open': 'खोलें', // In English: "Open"
|
||||
'window_title_change_password': 'पासवर्ड बदलें', // In English: "Change Password"
|
||||
'window_title_select_font': 'फ़ॉन्ट चुनें…', // In English: "Select font…"
|
||||
'window_title_session_list': 'सत्र सूची!', // In English: "Session List!"
|
||||
'window_title_set_new_password': 'नया पासवर्ड सेट करें', // In English: "Set New Password"
|
||||
'window_title_publish_website': 'वेबसाइट प्रकाशित करें', // In English: "Publish Website"
|
||||
'window_title_publish_worker': 'वर्कर प्रकाशित करें', // In English: "Publish Worker"
|
||||
'window_title_authenticating': 'प्रमाणित किया जा रहा है...', // In English: "Authenticating..."
|
||||
'window_title_refer_friend': 'मित्र को रेफ़र करें!', // In English: "Refer a friend!"
|
||||
'desktop_exit_full_screen': 'पूर्ण स्क्रीन से बाहर निकलें', // In English: "Exit Full Screen"
|
||||
'desktop_enter_full_screen': 'पूर्ण स्क्रीन में जाएँ', // In English: "Enter Full Screen"
|
||||
'item_shared_with_you': 'एक उपयोगकर्ता ने यह वस्तु आपके साथ साझा की है।', // In English: "A user has shared this item with you."
|
||||
'item_shared_by_you': 'आपने यह वस्तु कम से कम एक अन्य उपयोगकर्ता के साथ साझा की है।', // In English: "You have shared this item with at least one other user."
|
||||
'item_shortcut': 'शॉर्टकट', // In English: "Shortcut"
|
||||
'item_associated_websites': 'संबद्ध वेबसाइट', // In English: "Associated website"
|
||||
@@ -392,9 +344,6 @@ const hi = {
|
||||
'window_click_to_go_back': 'वापस जाने के लिए क्लिक करें।', // In English: "Click to go back."
|
||||
'window_click_to_go_forward': 'आगे जाने के लिए क्लिक करें।', // In English: "Click to go forward."
|
||||
'window_click_to_go_up': 'एक निर्देशिका ऊपर जाने के लिए क्लिक करें।', // In English: "Click to go one directory up."
|
||||
'window_title_public': 'सार्वजनिक', // In English: "Public"
|
||||
'window_title_videos': 'वीडियो', // In English: "Videos"
|
||||
'window_title_pictures': 'चित्र', // In English: "Pictures"
|
||||
'window_title_puter': 'Puter', // In English: "Puter"
|
||||
'window_folder_empty': 'यह फ़ोल्डर खाली है', // In English: "This folder is empty"
|
||||
},
|
||||
|
||||
@@ -31,7 +31,6 @@ const hu = {
|
||||
allow: 'Engedélyez',
|
||||
ascending: 'Növekvő',
|
||||
associated_websites: 'Kapcsolódó weboldalak',
|
||||
auto_arrange: 'Automatikus elrendezés',
|
||||
cancel: 'Mégsem',
|
||||
change_email: 'Email módosítása',
|
||||
change_language: 'Nyelv módosítása',
|
||||
@@ -41,17 +40,10 @@ const hu = {
|
||||
close_all_windows_and_log_out: 'Ablakok bezárása és kijelentkezés',
|
||||
change_always_open_with: 'Mindig ezzel az alkalmazással nyitja meg ezt a fájlt?',
|
||||
confirm: 'Megerősít',
|
||||
confirm_2fa_setup: 'A kódot hozzáadtam a hitelesítő alkalmazásomhoz',
|
||||
confirm_2fa_recovery: 'A helyreállítási kódokat biztonságos helyen tároltam',
|
||||
confirm_account_for_free_referral_storage_c2a: 'Hozz létre egy fiókot és erősítsd meg email címedet, hogy 1 GB ingyenes tárhelyet kapj. A barátod is kap 1 GB ingyenes tárhelyet.',
|
||||
confirm_code_generic_incorrect: 'Hibás kód.',
|
||||
confirm_code_generic_too_many_requests: 'Túl sok kérés. Kérlek, várj néhány percet.',
|
||||
confirm_code_generic_submit: 'Kód beküldése',
|
||||
confirm_code_generic_try_again: 'Próbáld újra',
|
||||
confirm_code_generic_title: 'Megerősítő kód megadása',
|
||||
confirm_code_2fa_instruction: 'Add meg a 6-jegyű kódot a hitelesítő alkalmazásodból.',
|
||||
confirm_code_2fa_submit_btn: 'Beküldés',
|
||||
confirm_code_2fa_title: '2FA kód megadása',
|
||||
confirm_delete_multiple_items: 'Biztosan véglegesen törölni akarod ezeket az elemeket?',
|
||||
confirm_delete_single_item: 'Biztosan véglegesen törölni akarod ezt az elemet?',
|
||||
confirm_open_apps_log_out: 'Nyitott alkalmazásaid vannak. Biztosan ki akarsz jelentkezni?',
|
||||
@@ -61,7 +53,6 @@ const hu = {
|
||||
confirm_session_revoke: 'Biztosan visszavonod ezt a munkamenetet?',
|
||||
confirm_your_email_address: 'Email címed megerősítése',
|
||||
contact_us: 'Kapcsolat',
|
||||
contact_us_verification_required: 'A használathoz érvényesített email címmel kell rendelkezned.',
|
||||
continue: 'Folytatás',
|
||||
copy: 'Másolás',
|
||||
copy_link: 'Link másolása',
|
||||
@@ -83,17 +74,13 @@ const hu = {
|
||||
deploy_as_app: 'Alkalmazásként telepít',
|
||||
descending: 'Csökkenő',
|
||||
desktop: 'Asztal',
|
||||
desktop_background_fit: 'Illesztés',
|
||||
developers: 'Fejlesztők',
|
||||
dir_published_as_website: '%strong% közzétéve a következő címen:',
|
||||
disable_2fa: '2FA letiltása',
|
||||
disable_2fa_confirm: 'Biztosan letiltod a 2FA-t?',
|
||||
disable_2fa_instructions: 'Add meg a jelszavad a 2FA letiltásához.',
|
||||
documents: 'Dokumentumok',
|
||||
dont_allow: 'Nem engedélyez',
|
||||
download: 'Letöltés',
|
||||
download_file: 'Fájl letöltése',
|
||||
downloading: 'Letöltés',
|
||||
email: 'Email',
|
||||
email_change_confirmation_sent: 'Megerősítő emailt küldtünk az új email címedre. Kérlek, ellenőrizd a postaládádat és kövesd az utasításokat a folyamat befejezéséhez.',
|
||||
email_invalid: 'Érvénytelen email cím.',
|
||||
@@ -118,13 +105,10 @@ const hu = {
|
||||
forgot_pass_c2a: 'Elfelejtetted a jelszavad?',
|
||||
from: 'Tól',
|
||||
general: 'Általános',
|
||||
get_a_copy_of_on_puter: "Szerezz egy példányt a(z) '%%' Puter.com-on!",
|
||||
get_copy_link: 'Másolási link megszerzése',
|
||||
home: 'Otthon',
|
||||
html_document: 'HTML dokumentum',
|
||||
hue: 'Színárnyalat',
|
||||
incorrect_password: 'Helytelen jelszó',
|
||||
invite_link: 'Meghívó link',
|
||||
item: 'elem',
|
||||
items_in_trash_cannot_be_renamed: 'Ez az elem nem nevezhető át, mert a kukában van. A név megváltoztatásához először húzd ki a Kukából.',
|
||||
jpeg_image: 'JPEG kép',
|
||||
@@ -135,7 +119,6 @@ const hu = {
|
||||
loading: 'Betöltés',
|
||||
log_in: 'Bejelentkezés',
|
||||
log_out: 'Kijelentkezés',
|
||||
looks_good: 'Jól néz ki!',
|
||||
manage_sessions: 'Munkamenetek kezelése',
|
||||
modified: 'Módosítva',
|
||||
move: 'Mozgatás',
|
||||
@@ -160,7 +143,6 @@ const hu = {
|
||||
open_with: 'Megnyitás ezzel',
|
||||
original_name: 'Eredeti név',
|
||||
original_path: 'Eredeti útvonal',
|
||||
oss_code_and_content: 'Nyílt forráskódú szoftver és tartalom',
|
||||
password: 'Jelszó',
|
||||
password_changed: 'Jelszó megváltoztatva.',
|
||||
password_recovery_rate_limit: 'Elérted a korlátunkat; kérlek, várj néhány percet. A jövőben kerüld az oldal túl sokszori újratöltését.',
|
||||
@@ -172,26 +154,19 @@ const hu = {
|
||||
paste: 'Beillesztés',
|
||||
paste_into_folder: 'Beillesztés a mappába',
|
||||
path: 'Útvonal',
|
||||
personalization: 'Személyre szabás',
|
||||
pick_name_for_website: 'Válassz nevet a weboldaladnak:',
|
||||
pictures: 'Képek',
|
||||
plural_suffix: 'k',
|
||||
powered_by_puter_js: 'A Puter.js hajtja',
|
||||
preparing: 'Előkészítés...',
|
||||
preparing_for_upload: 'Feltöltés előkészítése...',
|
||||
print: 'Nyomtatás',
|
||||
privacy: 'Adatvédelem',
|
||||
proceed_to_login: 'Folytatás a bejelentkezéshez',
|
||||
proceed_with_account_deletion: 'Fiók törlésének folytatása',
|
||||
properties: 'Tulajdonságok',
|
||||
public: 'Nyilvános',
|
||||
publish: 'Közzététel',
|
||||
publish_as_website: 'Közzététel weboldalként',
|
||||
puter_description: 'A Puter egy adatvédelmi elsőként kezelt személyes felhő, amelyben minden fájlodat, alkalmazásodat és játékodat egy biztonságos helyen tárolhatod, bárhonnan, bármikor elérhetően.',
|
||||
reading_file: 'Fájl olvasása: %strong%',
|
||||
recover_password: 'Jelszó visszaállítása',
|
||||
refer_friends_c2a: 'Kapj 1 GB-ot minden barátodért, aki létrehoz és megerősít egy fiókot a Puteren. A barátod is kap 1 GB-ot!',
|
||||
refer_friends_social_media_c2a: 'Kapj 1 GB ingyenes tárhelyet a Puter.com-on!',
|
||||
refresh: 'Frissítés',
|
||||
rename: 'Átnevezés',
|
||||
replace: 'Csere',
|
||||
@@ -201,11 +176,9 @@ const hu = {
|
||||
save: 'Mentés',
|
||||
saturation: 'Telítettség',
|
||||
save_account: 'Fiók mentése',
|
||||
save_account_to_get_copy_link: 'A folytatáshoz kérlek, hozz létre egy fiókot.',
|
||||
save_account_to_publish: 'A folytatáshoz kérlek, hozz létre egy fiókot.',
|
||||
save_session: 'Munkamenet mentése',
|
||||
save_session_c2a: 'Hozz létre egy fiókot, hogy mentsd az aktuális munkamenetedet és elkerüld a munkád elvesztését.',
|
||||
scan_qr_2fa: 'Olvasd be a QR-kódot a hitelesítő alkalmazásoddal',
|
||||
search: 'Keresés',
|
||||
seconds: 'másodperc',
|
||||
security: 'Biztonság',
|
||||
@@ -223,13 +196,11 @@ const hu = {
|
||||
show_hidden: 'Rejtett megjelenítése',
|
||||
sign_in_with_puter: 'Bejelentkezés Puterrel',
|
||||
sign_up: 'Regisztráció',
|
||||
signing_in: 'Bejelentkezés...',
|
||||
size: 'Méret',
|
||||
skip: 'Kihagyás',
|
||||
something_went_wrong: 'Valami hiba történt.',
|
||||
sort_by: 'Rendezés',
|
||||
status: 'Állapot',
|
||||
storage_usage: 'Tárhely használat',
|
||||
storage_puter_used: 'Puter által használt',
|
||||
taking_longer_than_usual: 'Kicsit tovább tart, mint általában. Kérlek várj...',
|
||||
terms: 'Feltételek',
|
||||
@@ -257,21 +228,15 @@ const hu = {
|
||||
videos: 'Videók',
|
||||
visibility: 'Láthatóság',
|
||||
yes: 'Igen',
|
||||
you_have_been_referred_to_puter_by_a_friend: 'Egy barátod ajánlott téged a Puterhez!',
|
||||
zip: 'Zip',
|
||||
zipping_file: 'Tömörítés: %strong%',
|
||||
|
||||
// === 2FA Setup ===
|
||||
setup2fa_1_step_heading: 'Nyisd meg a hitelesítő alkalmazásod',
|
||||
setup2fa_1_instructions: "Bármely hitelesítő alkalmazást használhatod, amely támogatja az időalapú egyszeri jelszó (TOTP) protokollt. Sok választási lehetőség van, de ha nem vagy biztos benne, az <a target='_blank' href='https://authy.com/download'>Authy</a> jó választás Android és iOS rendszeren.",
|
||||
setup2fa_2_step_heading: 'Olvasd be a QR-kódot',
|
||||
setup2fa_3_step_heading: 'Add meg a 6-jegyű kódot',
|
||||
setup2fa_4_step_heading: 'Másold le a helyreállítási kódjaidat',
|
||||
setup2fa_4_instructions: 'Ezek a helyreállítási kódok az egyetlen módja annak, hogy hozzáférj a fiókodhoz, ha elveszíted a telefonodat vagy nem tudod használni a hitelesítő alkalmazásodat. Ügyelj arra, hogy biztonságos helyen tárold őket.',
|
||||
setup2fa_5_step_heading: '2FA beállítás megerősítése',
|
||||
setup2fa_5_confirmation_1: 'A helyreállítási kódokat biztonságos helyen tároltam',
|
||||
setup2fa_5_confirmation_2: 'Készen állok a 2FA engedélyezésére',
|
||||
setup2fa_5_button: '2FA engedélyezése',
|
||||
|
||||
// === 2FA Login ===
|
||||
login2fa_otp_title: '2FA kód megadása',
|
||||
@@ -279,7 +244,6 @@ const hu = {
|
||||
login2fa_recovery_title: 'Add meg egy helyreállítási kódot',
|
||||
login2fa_recovery_instructions: 'Add meg az egyik helyreállítási kódodat a fiókhoz való hozzáféréshez.',
|
||||
login2fa_use_recovery_code: 'Használj helyreállítási kódot',
|
||||
login2fa_recovery_back: 'Vissza',
|
||||
login2fa_recovery_placeholder: 'XXXXXXXX',
|
||||
|
||||
'change': 'Módosítás', // In English: "Change"
|
||||
@@ -345,20 +309,13 @@ const hu = {
|
||||
'billing.expanded': 'Bővített', // In English: "Expanded"
|
||||
'billing.accelerated': 'Gyorsított', // In English: "Accelerated"
|
||||
'billing.enjoy_msg': 'Élvezd a %% Felhőtárhelyet és további előnyöket.', // In English: "Enjoy %% of Cloud Storage plus other benefits."
|
||||
'choose_publishing_option': 'Válassza ki, hogyan szeretné közzétenni a webhelyét', // English: "Choose how you want to publish your website"
|
||||
'create_desktop_shortcut': 'Parancsikon létrehozása (Asztal)', // English: "Create Shortcut (Desktop)"
|
||||
'create_desktop_shortcut_s': 'Parancsikonok létrehozása (Asztal)', // English: "Create Shortcuts (Desktop)"
|
||||
'create_shortcut_s': 'Parancsikonok létrehozása', // English: "Create Shortcuts"
|
||||
'minimize': 'Minimalizálás', // English: "Minimize"
|
||||
'reload_app': 'Alkalmazás újratöltése', // English: "Reload App"
|
||||
'publish_as_serverless_worker': 'Munkás közzététele', // English: "Publish as Worker"
|
||||
'toolbar.enter_fullscreen': 'Teljes képernyő', // English: "Enter Full Screen"
|
||||
'toolbar.github': 'GitHub', // English: "GitHub"
|
||||
'toolbar.refer': 'Ajánlás', // English: "Refer"
|
||||
'used_of': '{{used}} használt a {{available}}-ból', // English: "{{used}} used of {{available}}"
|
||||
'worker': 'Munkás', // English: "Worker"
|
||||
'billing.offering.basic': 'Alap', // English: "Basic"
|
||||
'too_many_attempts': 'Túl sok próbálkozás. Kérjük, próbálja meg később.', // English: "Too many attempts. Please try again later."
|
||||
'server_timeout': 'A szerver túl sokáig válaszolt. Kérjük, próbálja meg újra.', // English: "The server took too long to respond. Please try again."
|
||||
'signup_error': 'Hiba történt a regisztráció során. Kérjük, próbálja újra.', // English: "An error occurred during signup. Please try again."
|
||||
'alert_error_title': 'Hiba!', // English: "Error!"
|
||||
@@ -376,15 +333,10 @@ const hu = {
|
||||
'window_title_open': 'Megnyitás', // English: "Open"
|
||||
'window_title_change_password': 'Jelszó módosítása', // English: "Change Password"
|
||||
'window_title_select_font': 'Betű kiválasztása…', // English: "Select font…"
|
||||
'window_title_session_list': 'Munkamenet lista!', // English: "Session List!"
|
||||
'window_title_set_new_password': 'Új jelszó beállítása', // English: "Set New Password"
|
||||
'window_title_publish_website': 'Webhely közzététele', // English: "Publish Website"
|
||||
'window_title_publish_worker': 'Munkás közzététele', // English: "Publish Worker"
|
||||
'window_title_authenticating': 'Hitelesítés...', // English: "Authenticating..."
|
||||
'window_title_refer_friend': 'Barát ajánlása!', // English: "Refer a friend!"
|
||||
'desktop_exit_full_screen': 'Kilépés teljes képernyőből', // English: "Exit Full Screen"
|
||||
'desktop_enter_full_screen': 'Teljes képernyő', // English: "Enter Full Screen"
|
||||
'item_shared_with_you': 'Egy felhasználó megosztotta Önnel ezt az elemet.', // English: "A user has shared this item with you."
|
||||
'item_shared_by_you': 'Legalább egy másik felhasználóval megosztotta ezt az elemet.', // English: "You have shared this item with at least one other user."
|
||||
'item_shortcut': 'Parancsikon', // English: "Shortcut"
|
||||
'item_associated_websites': 'Kapcsolódó webhely', // English: "Associated website"
|
||||
@@ -393,9 +345,6 @@ const hu = {
|
||||
'window_click_to_go_back': 'Kattintson a visszalépéshez.', // English: "Click to go back."
|
||||
'window_click_to_go_forward': 'Kattintson a továbblépéshez.', // English: "Click to go forward."
|
||||
'window_click_to_go_up': 'Kattintson a szülőmappa megnyitásához.', // English: "Click to go one directory up."
|
||||
'window_title_public': 'Nyilvános', // English: "Public"
|
||||
'window_title_videos': 'Videók', // English: "Videos"
|
||||
'window_title_pictures': 'Képek', // English: "Pictures"
|
||||
'window_title_puter': 'Puter', // English: "Puter"
|
||||
'window_folder_empty': 'Ez a mappa üres', // English: "This folder is empty"
|
||||
|
||||
|
||||
@@ -31,7 +31,6 @@ const hy = {
|
||||
allow: 'Թույլատրել',
|
||||
ascending: 'Աճող',
|
||||
associated_websites: 'Կապված կայքեր',
|
||||
auto_arrange: 'Ավտոմատ դասավորել',
|
||||
cancel: 'Չեղարկել',
|
||||
change_email: 'Փոխել էլ. փոստը',
|
||||
change_language: 'Փոխել լեզուն',
|
||||
@@ -41,20 +40,13 @@ const hy = {
|
||||
close_all_windows_and_log_out: 'Փակել պատուհաններն ու դուրս գալ',
|
||||
change_always_open_with: 'Ցանկանու՞մ եք այս տեսակի ֆայլը միշտ բացել',
|
||||
confirm: 'Հաստատել',
|
||||
confirm_2fa_setup: 'Ես ավելացրել եմ կոդը իմ իսկորոշիչ հավելվածում',
|
||||
confirm_2fa_recovery: 'Ես պահել եմ վերականգնման կոդերը ապահով վայրում',
|
||||
confirm_account_for_free_referral_storage_c2a:
|
||||
'Ստեղծեք հաշիվ և հաստատեք ձեր էլ. հասցեն 1 ԳԲ անվճար պահեստ ստանալու համար: Ձեր ընկերը նույնպես կստանա 1 ԳԲ անվճար պահեստ:',
|
||||
confirm_code_generic_incorrect: 'Սխալ կոդ:',
|
||||
confirm_code_generic_too_many_requests:
|
||||
'Չափազանց շատ հարցումներ: Խնդրում ենք սպասել մի քանի րոպե:',
|
||||
confirm_code_generic_submit: 'Հաստատել կոդը',
|
||||
confirm_code_generic_try_again: 'Կրկին փորձեք',
|
||||
confirm_code_generic_title: 'Մուտքագրեք հաստատման կոդը',
|
||||
confirm_code_2fa_instruction:
|
||||
'Մուտքագրեք 6 նիշանոց կոդը ձեր իսկորոշիչ հավելվածից:',
|
||||
confirm_code_2fa_submit_btn: 'Հաստատել',
|
||||
confirm_code_2fa_title: 'Մուտքագրեք 2FA կոդը',
|
||||
confirm_delete_multiple_items:
|
||||
'Վստա՞հ եք, որ ցանկանում եք ընդմիշտ ջնջել այս տարրերը:',
|
||||
confirm_delete_single_item: 'Ցանկանու՞մ եք ընդմիշտ ջնջել այս տարրը:',
|
||||
@@ -67,8 +59,6 @@ const hy = {
|
||||
confirm_session_revoke: 'Վստա՞հ եք, որ ցանկանում եք չեղարկել այս սեսիան:',
|
||||
confirm_your_email_address: 'Հաստատեք ձեր էլ. փոստի հասցեն',
|
||||
contact_us: 'Հետադարձ կապ',
|
||||
contact_us_verification_required:
|
||||
'Սա օգտագործելու համար դուք պետք է ունենաք հաստատված էլ․ հասցե։:',
|
||||
continue: 'Շարունակել',
|
||||
copy: 'Պատճենել',
|
||||
copy_link: 'Պատճենել հղումը',
|
||||
@@ -90,18 +80,14 @@ const hy = {
|
||||
deploy_as_app: 'Տեղադրել որպես հավելված',
|
||||
descending: 'Նվազող',
|
||||
desktop: 'Աշխատասեղան',
|
||||
desktop_background_fit: 'Հարմարեցնել',
|
||||
developers: 'Ծրագրավորողներ',
|
||||
dir_published_as_website: '%strong% հրապարակվել է',
|
||||
disable_2fa: 'Անջատել 2FA',
|
||||
disable_2fa_confirm: 'Վստա՞հ եք, որ ցանկանում եք անջատել 2FA-ն:',
|
||||
disable_2fa_instructions:
|
||||
'Մուտքագրեք ձեր գաղտնաբառը՝ 2FA-ն անջատելու համար:',
|
||||
documents: 'Փաստաթղթեր',
|
||||
dont_allow: 'Թույլ չտալ',
|
||||
download: 'Ներբեռնել',
|
||||
download_file: 'Ներբեռնել ֆայլը',
|
||||
downloading: 'Ներբեռնվում է',
|
||||
email: 'Էլեկտրոնային հասցե',
|
||||
email_change_confirmation_sent:
|
||||
'Հաստատման նամակը ուղարկվել է ձեր նոր էլ. հասցեին։ Խնդրում ենք ստուգեք ձեր փոստարկղը և հետևեք ցուցումներին՝ գործընթացը ավարտելու համար:',
|
||||
@@ -131,13 +117,10 @@ const hy = {
|
||||
forgot_pass_c2a: 'Մոռացե՞լ եք գաղտնաբառը',
|
||||
from: 'Ումից՝',
|
||||
general: 'Ընդհանուր',
|
||||
get_a_copy_of_on_puter: "Ստանալ '%%'-ի պատճենը Puter.com-ում!",
|
||||
get_copy_link: 'Ստանալ պատճենված հղումը',
|
||||
home: 'Գլխավոր',
|
||||
html_document: 'HTML փաստաթուղթ',
|
||||
hue: 'Երանգ',
|
||||
incorrect_password: 'Սխալ գաղտնաբառ',
|
||||
invite_link: 'Հրավերի հղում',
|
||||
item: 'տարր',
|
||||
items_in_trash_cannot_be_renamed:
|
||||
'Այս տարրը չի կարող վերանվանվել, քանի որ այն աղբարկղում է: Այս տարրը վերանվանելու համար նախ տեղափոխեք այն աղբարկղից:',
|
||||
@@ -149,7 +132,6 @@ const hy = {
|
||||
loading: 'Բեռնում',
|
||||
log_in: 'Մուտք գործել',
|
||||
log_out: 'Դուրս գալ',
|
||||
looks_good: 'Լավ է նայվում!',
|
||||
manage_sessions: 'Սեսիաների կառավարում',
|
||||
modified: 'Փոփոխված',
|
||||
move: 'Տեղափոխել',
|
||||
@@ -174,7 +156,6 @@ const hy = {
|
||||
open_with: 'Բացել հավելվածով',
|
||||
original_name: 'սկզբնական անուն',
|
||||
original_path: 'սկզբնական ուղի',
|
||||
oss_code_and_content: 'Բաց կոդով ծրագրակազմ և բովանդակություն',
|
||||
password: 'Գաղտնաբառ',
|
||||
password_changed: 'Գաղտնաբառը փոփոխված է',
|
||||
password_recovery_rate_limit:
|
||||
@@ -191,28 +172,20 @@ const hy = {
|
||||
paste: 'Տեղադրել',
|
||||
paste_into_folder: 'Տեղադրել պանակում',
|
||||
path: 'Ուղի',
|
||||
personalization: 'Անհատականացում',
|
||||
pick_name_for_website: 'Ընտրեք անուն ձեր կայքի համար',
|
||||
pictures: 'Նկարներ',
|
||||
plural_suffix: 'ներ',
|
||||
powered_by_puter_js: 'Աջակցվում է {{link=docs}}Puter.js{{/link}}-ի կողմից',
|
||||
preparing: 'Պատրաստվում է...',
|
||||
preparing_for_upload: 'Պատրաստվում է վերբեռնել...',
|
||||
print: 'Տպել',
|
||||
privacy: 'Գաղտնիություն',
|
||||
proceed_to_login: 'Շարունակել մուտք գործելը',
|
||||
proceed_with_account_deletion: 'Շարունակել հաշվի ջնջումը',
|
||||
properties: 'Հատկություններ',
|
||||
public: 'Հանրային',
|
||||
publish: 'Հրապարակել',
|
||||
publish_as_website: 'Հրապարակել որպես կայք',
|
||||
puter_description:
|
||||
'Փութերը գաղտնիության առաջնահերթություն ունեցող անձնական ամպ է՝ ձեր բոլոր ֆայլերը, հավելվածները և խաղերը մեկ անվտանգ տեղում պահելու համար, որը հասանելի է ցանկացած վայրից ցանկացած ժամանակ:',
|
||||
reading_file: 'Ընթերցում է %strong%',
|
||||
recover_password: 'Վերականգնել գաղտնաբառը',
|
||||
refer_friends_c2a:
|
||||
'Ստացեք 1 ԳԲ յուրաքանչյուր ընկերոջ համար, ով ստեղծում և հաստատում է հաշիվ Փութերում: Ձեր ընկերը նույնպես կստանա 1 ԳԲ!',
|
||||
refer_friends_social_media_c2a: 'Ստացեք 1 ԳԲ անվճար պահեստ Puter.com-ում!',
|
||||
refresh: 'Թարմացնել',
|
||||
rename: 'Վերանվանել',
|
||||
replace: 'Փոխարինել',
|
||||
@@ -222,13 +195,10 @@ const hy = {
|
||||
save: 'Պահպանել',
|
||||
saturation: 'Հագեցվածություն',
|
||||
save_account: 'Պահպանել հաշիվը',
|
||||
save_account_to_get_copy_link:
|
||||
'Շարունակելու համար խնդրում ենք ստեղծել հաշիվ:',
|
||||
save_account_to_publish: 'Շարունակելու համար խնդրում ենք ստեղծել հաշիվ:',
|
||||
save_session: 'Պահպանել սեսիան',
|
||||
save_session_c2a:
|
||||
'Ստեղծեք հաշիվ՝ ձեր ընթացիկ սեսիան պահպանելու և աշխատանքը չկորցնելու համար:',
|
||||
scan_qr_2fa: 'Սկանավորեք QR-կոդը ձեր իսկորոշիչ հավելվածով',
|
||||
search: 'Որոնել',
|
||||
seconds: 'վայրկյաններ',
|
||||
security: 'Անվտանգություն',
|
||||
@@ -248,13 +218,11 @@ const hy = {
|
||||
show_hidden: 'Ցույց տալ թաքնված տարրերը',
|
||||
sign_in_with_puter: 'Մուտք գործել Փութերի միջոցով',
|
||||
sign_up: 'Գրանցվել',
|
||||
signing_in: 'Մուտք է գործում…',
|
||||
size: 'Չափ',
|
||||
skip: 'Բաց թողնել',
|
||||
something_went_wrong: 'Ինչ-որ բան սխալ գնաց:',
|
||||
sort_by: 'Տեսակավորել ըստ՝',
|
||||
status: 'Կարգավիճակ',
|
||||
storage_usage: 'Պահեստի օգտագործում',
|
||||
storage_puter_used: 'օգտագործվում է Փութերի կողմից',
|
||||
taking_longer_than_usual:
|
||||
'Սովորականից մի փոքր ավելի երկար է տևում: Խնդրում ենք սպասել...',
|
||||
@@ -284,31 +252,24 @@ const hy = {
|
||||
videos: 'Տեսանյութեր',
|
||||
visibility: 'Տեսանելիություն',
|
||||
yes: 'Այո',
|
||||
you_have_been_referred_to_puter_by_a_friend:
|
||||
'Դուք ուղղորդվել եք Փութեր ձեր ընկերոջ կողմից!',
|
||||
zip: 'Ավելացնել արխիվում',
|
||||
zipping_file: 'Ավելացվում է արխիվում %strong%-ը',
|
||||
|
||||
// === 2FA Setup ===
|
||||
setup2fa_1_step_heading: 'Բացեք ձեր իսկորոշիչ հավելվածը',
|
||||
setup2fa_1_instructions: `
|
||||
Դուք կարող եք օգտագործել ցանկացած իսկորոշիչ հավելված, որն աջակցում է ժամանակի վրա հիմնված միանգամյա գաղտնաբառ (TOTP) պրոտոկոլը:
|
||||
Կան բազմաթիվ տարբերակներ, բայց եթե վստահ չեք,
|
||||
<a target="_blank" href="https://authy.com/download">Authy</a>
|
||||
լավ ընտրություն է Android-ի և iOS-ի համար:
|
||||
`,
|
||||
setup2fa_2_step_heading: 'Սկանավորեք QR-կոդը',
|
||||
setup2fa_3_step_heading: 'Մուտքագրեք 6 նիշանոց կոդը',
|
||||
setup2fa_4_step_heading: 'Պատճենեք ձեր վերականգնման կոդերը',
|
||||
setup2fa_4_instructions: `
|
||||
Այս վերականգնման կոդերը միակ միջոցն են մուտք գործելու ձեր հաշիվ, եթե կորցնեք ձեր հեռախոսը կամ չկարողանաք օգտագործել ձեր իսկորոշիչ հավելվածը:
|
||||
Պարտադիր դրանք պահեք ապահով վայրում:
|
||||
`,
|
||||
setup2fa_5_step_heading: 'Հաստատեք 2FA կարգավորումը',
|
||||
setup2fa_5_confirmation_1:
|
||||
'Ես իմ վերականգնման կոդերը պահել եմ ապահով վայրում',
|
||||
setup2fa_5_confirmation_2: 'Ես պատրաստ եմ միացնել 2FA',
|
||||
setup2fa_5_button: 'Միացնել 2FA',
|
||||
|
||||
// === 2FA Login ===
|
||||
login2fa_otp_title: 'Մուտքագրեք 2FA կոդը',
|
||||
@@ -318,7 +279,6 @@ const hy = {
|
||||
login2fa_recovery_instructions:
|
||||
'Մուտքագրեք ձեր վերականգնման կոդերից մեկը ձեր հաշիվ մուտք գործելու համար:',
|
||||
login2fa_use_recovery_code: 'Օգտագործել վերականգնման կոդը',
|
||||
login2fa_recovery_back: 'Հետ',
|
||||
login2fa_recovery_placeholder: 'XXXXXXXX',
|
||||
|
||||
change: 'Փոփոխել',
|
||||
@@ -394,20 +354,13 @@ const hy = {
|
||||
'billing.accelerated': 'Արագացված',
|
||||
'billing.enjoy_msg':
|
||||
'Վայելեք %% ամպային պահեստավորում և այլ առավելություններ',
|
||||
choose_publishing_option: 'Ընտրեք ձեր կայքը հրապարակելու եղանակը։',
|
||||
create_desktop_shortcut: 'Ստեղծել դյուրանցում (Աշխատասեղան)',
|
||||
create_desktop_shortcut_s: 'Ստեղծել դյուրանցումներ (Աշխատասեղան)',
|
||||
create_shortcut_s: 'Ստեղծել դյուրանցումներ',
|
||||
minimize: 'Փոքրացնել',
|
||||
reload_app: 'Վերաբեռնել հավելվածը',
|
||||
publish_as_serverless_worker: 'Հրապարակել որպես Worker',
|
||||
'toolbar.enter_fullscreen': 'Լիաէկրան ռեժիմ',
|
||||
'toolbar.github': 'GitHub',
|
||||
'toolbar.refer': 'Հրավիրել',
|
||||
used_of: '{{used}} օգտագործված է {{available}}-ից',
|
||||
worker: 'Worker',
|
||||
'billing.offering.basic': 'Հիմնական',
|
||||
too_many_attempts: 'Չափազանց շատ փորձեր։ Խնդրում ենք փորձել ավելի ուշ։',
|
||||
server_timeout:
|
||||
'Սերվերը չի պատասխանել ժամանակին։ Խնդրում ենք կրկին փորձել։',
|
||||
signup_error:
|
||||
@@ -427,15 +380,10 @@ const hy = {
|
||||
window_title_open: 'Բացել',
|
||||
window_title_change_password: 'Փոխել գաղտնաբառը',
|
||||
window_title_select_font: 'Ընտրել տառատեսակ…',
|
||||
window_title_session_list: 'Սեսիաների ցանկ',
|
||||
window_title_set_new_password: 'Սահմանել նոր գաղտնաբառ',
|
||||
window_title_publish_website: 'Հրապարակել կայք',
|
||||
window_title_publish_worker: 'Հրապարակել Worker',
|
||||
window_title_authenticating: 'Նույնականացում…',
|
||||
window_title_refer_friend: 'Հրավիրել ընկերոջը',
|
||||
desktop_exit_full_screen: 'Ելք լիաէկրան ռեժիմից',
|
||||
desktop_enter_full_screen: 'Լիաէկրան ռեժիմ',
|
||||
item_shared_with_you: 'Օգտատերը կիսվել է այս տարրով ձեզ հետ.',
|
||||
item_shared_by_you:
|
||||
'Դուք կիսվել եք այս տարրով առնվազն մեկ այլ օգտատիրոջ հետ.',
|
||||
item_shortcut: 'Դյուրանցում',
|
||||
@@ -445,9 +393,6 @@ const hy = {
|
||||
window_click_to_go_back: 'Սեղմեք՝ վերադառնալու համար.',
|
||||
window_click_to_go_forward: 'Սեղմեք՝ առաջ անցնելու համար.',
|
||||
window_click_to_go_up: 'Սեղմեք՝ մեկ պանակ վեր բարձրանալու համար.',
|
||||
window_title_public: 'Հրապարակային',
|
||||
window_title_videos: 'Տեսանյութեր',
|
||||
window_title_pictures: 'Նկարներ',
|
||||
window_title_puter: 'Puter',
|
||||
window_folder_empty: 'Այս պանակը դատարկ է',
|
||||
},
|
||||
|
||||
@@ -31,7 +31,6 @@ const id = {
|
||||
allow: 'Izinkan',
|
||||
ascending: 'Menaik',
|
||||
associated_websites: 'Situs Web Terkait',
|
||||
auto_arrange: 'Atur Otomatis',
|
||||
cancel: 'Batal',
|
||||
change_email: 'Ubah Email',
|
||||
change_language: 'Ubah Bahasa',
|
||||
@@ -41,20 +40,13 @@ const id = {
|
||||
close_all_windows_and_log_out: 'Tutup Jendela dan Keluar',
|
||||
change_always_open_with: 'Apakah Anda ingin selalu membuka jenis file ini dengan',
|
||||
confirm: 'Konfirmasi',
|
||||
confirm_2fa_setup: 'Saya telah menambahkan kode ke aplikasi autentikator saya',
|
||||
confirm_2fa_recovery: 'Saya telah menyimpan kode pemulihan saya di tempat yang aman',
|
||||
confirm_account_for_free_referral_storage_c2a:
|
||||
'Buat akun dan konfirmasi alamat email Anda untuk menerima 1 GB kapasitas penyimpanan gratis. Teman Anda juga akan mendapatkan 1 GB kapasitas penyimpanan gratis.',
|
||||
confirm_code_generic_incorrect: 'Kode Salah.',
|
||||
confirm_code_generic_too_many_requests:
|
||||
'Terlalu banyak permintaan. Silakan tunggu beberapa menit.',
|
||||
confirm_code_generic_submit: 'Kirim Kode',
|
||||
confirm_code_generic_try_again: 'Coba Lagi',
|
||||
confirm_code_generic_title: 'Masukkan Kode Konfirmasi',
|
||||
confirm_code_2fa_instruction:
|
||||
'Masukkan kode 6-digit dari aplikasi autentikator Anda.',
|
||||
confirm_code_2fa_submit_btn: 'Kirim',
|
||||
confirm_code_2fa_title: 'Masukkan Kode 2FA',
|
||||
confirm_delete_multiple_items:
|
||||
'Apakah Anda yakin ingin menghapus barang-barang ini secara permanen?',
|
||||
confirm_delete_single_item: 'Apakah Anda ingin menghapus barang ini secara permanen?',
|
||||
@@ -67,8 +59,6 @@ const id = {
|
||||
confirm_session_revoke: 'Apakah Anda yakin ingin mencabut sesi ini?',
|
||||
confirm_your_email_address: 'Konfirmasi Alamat Email Anda',
|
||||
contact_us: 'Hubungi Kami',
|
||||
contact_us_verification_required:
|
||||
'Anda harus memiliki alamat email yang terverifikasi untuk menggunakan ini.',
|
||||
continue: 'Lanjutkan',
|
||||
copy: 'Salin',
|
||||
copy_link: 'Salin Tautan',
|
||||
@@ -90,17 +80,13 @@ const id = {
|
||||
deploy_as_app: 'Pasang sebagai aplikasi',
|
||||
descending: 'Menurun',
|
||||
desktop: 'Desktop',
|
||||
desktop_background_fit: 'Cocokkan',
|
||||
developers: 'Pengembang',
|
||||
dir_published_as_website: '%strong% telah dipublikasikan di:',
|
||||
disable_2fa: 'Nonaktifkan 2FA',
|
||||
disable_2fa_confirm: 'Apakah Anda yakin ingin menonaktifkan 2FA?',
|
||||
disable_2fa_instructions: 'Masukkan kata sandi Anda untuk menonaktifkan 2FA.',
|
||||
documents: 'Dokumen',
|
||||
dont_allow: 'Jangan Izinkan',
|
||||
download: 'Unduh',
|
||||
download_file: 'Unduh File',
|
||||
downloading: 'Mengunduh',
|
||||
email: 'Email',
|
||||
email_change_confirmation_sent:
|
||||
'Email konfirmasi telah dikirim ke alamat email baru Anda. Silakan periksa kotak masuk Anda dan ikuti petunjuk untuk menyelesaikan prosesnya.',
|
||||
@@ -129,13 +115,10 @@ const id = {
|
||||
forgot_pass_c2a: 'Lupa kata sandi?',
|
||||
from: 'Dari',
|
||||
general: 'Umum',
|
||||
get_a_copy_of_on_puter: 'Dapatkan salinan \'%%\' di Puter.com!',
|
||||
get_copy_link: 'Dapatkan Salinan Tautan',
|
||||
home: 'Beranda',
|
||||
html_document: 'Dokumen HTML',
|
||||
hue: 'Hue',
|
||||
incorrect_password: 'Kata sandi salah',
|
||||
invite_link: 'Tautan Undangan',
|
||||
item: 'barang',
|
||||
items_in_trash_cannot_be_renamed: 'Barang ini tidak dapat diganti namanya karena berada di sampah. Untuk mengganti nama barang ini, pindahkan dahulu dari Sampah.',
|
||||
jpeg_image: 'Gambar JPEG',
|
||||
@@ -146,7 +129,6 @@ const id = {
|
||||
loading: 'Memuat',
|
||||
log_in: 'Masuk',
|
||||
log_out: 'Keluar',
|
||||
looks_good: 'Tampak bagus!',
|
||||
manage_sessions: 'Kelola Sesi',
|
||||
modified: 'Dimodifikasi',
|
||||
move: 'Pindahkan',
|
||||
@@ -171,7 +153,6 @@ const id = {
|
||||
open_with: 'Buka Dengan',
|
||||
original_name: 'Nama Asli',
|
||||
original_path: 'Lokasi Asli',
|
||||
oss_code_and_content: 'Perangkat Lunak dan Konten Open Source',
|
||||
password: 'Kata Sandi',
|
||||
password_changed: 'Kata sandi telah diubah.',
|
||||
password_recovery_rate_limit:
|
||||
@@ -187,27 +168,20 @@ const id = {
|
||||
paste: 'Tempel',
|
||||
paste_into_folder: 'Tempel ke dalam Folder',
|
||||
path: 'Lokasi',
|
||||
personalization: 'Personalisasi',
|
||||
pick_name_for_website: 'Pilih nama untuk situs web Anda:',
|
||||
pictures: 'Gambar',
|
||||
plural_suffix: 's',
|
||||
powered_by_puter_js: 'Ditenagai oleh {{link=docs}}Puter.js{{/link}}',
|
||||
preparing: 'Mempersiapkan...',
|
||||
preparing_for_upload: 'Mempersiapkan untuk menggunggah...',
|
||||
print: 'Cetak',
|
||||
privacy: 'Privasi',
|
||||
proceed_to_login: 'Lanjutkan masuk',
|
||||
proceed_with_account_deletion: 'Lanjutkan Penghapusan Akun',
|
||||
properties: 'Properti',
|
||||
public: 'Publik',
|
||||
publish: 'Publikasi',
|
||||
publish_as_website: 'Publikasikan sebagai situs web',
|
||||
puter_description: 'Puter adalah cloud pribadi yang mengutamakan privasi untuk menyimpan semua file, aplikasi, dan permainan Anda di satu tempat yang aman, dapat diakses dari mana pun dan kapan pun.',
|
||||
reading_file: 'Membaca %strong%',
|
||||
recover_password: 'Pulihkan Kata Sandi',
|
||||
refer_friends_c2a:
|
||||
'Dapatkan 1 GB untuk setiap teman yang membuat dan mengonfirmasi akun di Puter. Teman Anda juga akan mendapatkan 1 GB!',
|
||||
refer_friends_social_media_c2a: 'Dapatkan 1 GB penyimpanan gratis di Puter.com!',
|
||||
refresh: 'Muat Ulang',
|
||||
rename: 'Ganti Nama',
|
||||
replace: 'Ganti',
|
||||
@@ -217,12 +191,10 @@ const id = {
|
||||
save: 'Simpan',
|
||||
saturation: 'Saturasi',
|
||||
save_account: 'Simpan akun',
|
||||
save_account_to_get_copy_link: 'Silakan buat akun untuk mendapatkan salinan tautan.',
|
||||
save_account_to_publish: 'Silakan buat akun untuk melanjutkan.',
|
||||
save_session: 'Simpan sesi',
|
||||
save_session_c2a:
|
||||
'Buat akun untuk menyimpan sesi Anda saat ini agar yang Anda kerjakan tidak hilang.',
|
||||
scan_qr_2fa: 'Pindai kode QR dengan aplikasi autentikator Anda',
|
||||
search: 'Pencarian',
|
||||
seconds: 'detik',
|
||||
security: 'Keamanan',
|
||||
@@ -240,13 +212,11 @@ const id = {
|
||||
show_hidden: 'Tampilkan yang tersembunyi',
|
||||
sign_in_with_puter: 'Masuk dengan Puter',
|
||||
sign_up: 'Daftar',
|
||||
signing_in: 'Masuk…',
|
||||
size: 'Ukuran',
|
||||
skip: 'Lewatkan',
|
||||
something_went_wrong: 'Terjadi kesalahan.',
|
||||
sort_by: 'Urutkan berdasarkan',
|
||||
status: 'Status',
|
||||
storage_usage: 'Penggunaan Penyimpanan',
|
||||
storage_puter_used: 'digunakan oleh Puter',
|
||||
taking_longer_than_usual:
|
||||
'Memakan waktu sedikit lebih lama dari biasanya. Silakan tunggu...',
|
||||
@@ -275,31 +245,24 @@ const id = {
|
||||
videos: 'Video',
|
||||
visibility: 'Visibilitas',
|
||||
yes: 'Ya',
|
||||
you_have_been_referred_to_puter_by_a_friend:
|
||||
'Anda telah dirujuk ke Puter oleh seorang teman!',
|
||||
zip: 'Zip',
|
||||
zipping_file: 'Mengekstrak %strong%',
|
||||
|
||||
// === 2FA Setup ===
|
||||
setup2fa_1_step_heading: 'Buka aplikasi autentikator Anda',
|
||||
setup2fa_1_instructions: `
|
||||
Anda dapat menggunakan aplikasi autentikator apa pun yang mendukung protokol Time-based One-Time Password (TOTP).
|
||||
Ada banyak pilihan, tetapi jika Anda tidak yakin
|
||||
<a target="_blank" href="https://authy.com/download">Authy</a>
|
||||
adalah pilihan yang solid untuk Android dan iOS.
|
||||
`,
|
||||
setup2fa_2_step_heading: 'Pindai kode QR',
|
||||
setup2fa_3_step_heading: 'Masukkan kode 6 digit',
|
||||
setup2fa_4_step_heading: 'Salin kode pemulihan Anda',
|
||||
setup2fa_4_instructions: `
|
||||
Kode pemulihan ini adalah satu-satunya cara untuk mengakses akun Anda jika Anda kehilangan ponsel atau tidak dapat menggunakan aplikasi autentikator Anda.
|
||||
Pastikan untuk menyimpannya di tempat yang aman.
|
||||
`,
|
||||
setup2fa_5_step_heading: 'Konfirmasi pengaturan 2FA',
|
||||
setup2fa_5_confirmation_1:
|
||||
'Saya telah menyimpan kode pemulihan saya di tempat yang aman',
|
||||
setup2fa_5_confirmation_2: 'Saya siap untuk mengaktifkan 2FA',
|
||||
setup2fa_5_button: 'Aktifkan 2FA',
|
||||
|
||||
// === 2FA Login ===
|
||||
login2fa_otp_title: 'Masukkan Kode 2FA',
|
||||
@@ -308,7 +271,6 @@ const id = {
|
||||
login2fa_recovery_instructions:
|
||||
'Masukkan salah satu kode pemulihan Anda untuk mengakses akun Anda.',
|
||||
login2fa_use_recovery_code: 'Gunakan kode pemulihan',
|
||||
login2fa_recovery_back: 'Kembali',
|
||||
login2fa_recovery_placeholder: 'XXXXXXXX',
|
||||
|
||||
'change': 'Ubah', // In English: "Change"
|
||||
@@ -377,20 +339,13 @@ const id = {
|
||||
// =============================================================
|
||||
// Missing translations
|
||||
// =============================================================
|
||||
'choose_publishing_option': 'Pilih cara untuk memublikasikan situs web Anda:', // In English: "Choose how you want to publish your website:"
|
||||
'create_desktop_shortcut': 'Buat Pintasan (Desktop)', // In English: "Create Shortcut (Desktop)"
|
||||
'create_desktop_shortcut_s': 'Buat Pintasan (Desktop)', // In English: "Create Shortcuts (Desktop)". TL note, there are no plural form of noun in Indonesia. Yes, we can use repetition, but in this case it's more effective this way
|
||||
'create_shortcut_s': 'Buat Pintasan', // In English: "Create Shortcuts"
|
||||
'minimize': 'Kecilkan', // In English: "Minimize"
|
||||
'reload_app': 'Muat Ulang Aplikasi', // In English: "Reload App"
|
||||
'publish_as_serverless_worker': 'Publikasikan sebagai Worker', // In English: "Publish as Worker"
|
||||
'toolbar.enter_fullscreen': 'Masuk ke Layar Penuh', // In English: "Enter Full Screen"
|
||||
'toolbar.github': 'Github', // In English: "GitHub"
|
||||
'toolbar.refer': 'Rujuk', // In English: "Refer"
|
||||
'used_of': 'terpakai {{used}} dari {{available}}', // In English: "{{used}} used of {{available}}"
|
||||
'worker': 'Worker', // In English: "Worker".
|
||||
'billing.offering.basic': 'Basic', // In English: "Basic"
|
||||
'too_many_attempts': 'Terlalu banyak percobaan. Silakan coba kembali nanti', // In English: "Too many attempts. Please try again later."
|
||||
'server_timeout': 'Server terlalu lama merespons. Silakan coba kembali nanti', // In English: "The server took too long to respond. Please try again."
|
||||
'signup_error': 'Terjadi kegagalan saat proses daftar. Silakan coba kembali nanti', // In English: "An error occurred during signup. Please try again."
|
||||
'alert_error_title': 'Galat!', // In English: "Error!"
|
||||
@@ -408,15 +363,10 @@ const id = {
|
||||
'window_title_open': 'buka', // In English: "Open"
|
||||
'window_title_change_password': 'Ubah Kata Sandi', // In English: "Change Password"
|
||||
'window_title_select_font': 'Pilih font...', // In English: "Select font…"
|
||||
'window_title_session_list': 'Daftar Sesi', // In English: "Session List!"
|
||||
'window_title_set_new_password': 'Tentukan Kata Sandi Baru', // In English: "Set New Password"
|
||||
'window_title_publish_website': 'Publikasikan Situs Web', // In English: "Publish Website"
|
||||
'window_title_publish_worker': 'Publikasikan Worker', // In English: "Publish Worker"
|
||||
'window_title_authenticating': 'Proses Autentikasi...', // In English: "Authenticating..."
|
||||
'window_title_refer_friend': 'Ajak Teman!', // In English: "Refer a friend!"
|
||||
'desktop_exit_full_screen': 'Keluar dari Layar Penuh', // In English: "Exit Full Screen"
|
||||
'desktop_enter_full_screen': 'Masuk ke Layar Penuh', // In English: "Enter Full Screen"
|
||||
'item_shared_with_you': 'Pengguna lain berbagi barang ini dengan Anda', // In English: "A user has shared this item with you."
|
||||
'item_shared_by_you': 'Anda telah membagikan barang ini dengan setidaknya satu pengguna lain', // In English: "You have shared this item with at least one other user."
|
||||
'item_shortcut': 'Pintasan', // In English: "Shortcut"
|
||||
'item_associated_websites': 'Situs Web Terkait', // In English: "Associated website"
|
||||
@@ -425,9 +375,6 @@ const id = {
|
||||
'window_click_to_go_back': 'Klik untuk kembali.', // In English: "Click to go back."
|
||||
'window_click_to_go_forward': 'Klik untuk melanjutkan.', // In English: "Click to go forward."
|
||||
'window_click_to_go_up': 'Klik untuk naik satu direktori', // In English: "Click to go one directory up."
|
||||
'window_title_public': 'Publik', // In English: "Public"
|
||||
'window_title_videos': 'Video', // In English: "Videos"
|
||||
'window_title_pictures': 'Gambar', // In English: "Pictures"
|
||||
'window_title_puter': 'Puter', // In English: "Puter"
|
||||
'window_folder_empty': 'Folder ini kosong', // In English: "This folder is empty"
|
||||
|
||||
|
||||
@@ -31,7 +31,6 @@ const ig = {
|
||||
allow: 'ekwe',
|
||||
ascending: 'Na-arịgo',
|
||||
associated_websites: 'Weebụsaịtị Ejikọtara',
|
||||
auto_arrange: 'ndokwa onwe',
|
||||
cancel: 'Kagbuo',
|
||||
change_email: 'ịgbanwe email',
|
||||
change_language: 'ịgbanwe Asụsụ',
|
||||
@@ -41,21 +40,14 @@ const ig = {
|
||||
close_all_windows_and_log_out: 'mmechi Windows na wee pụọ',
|
||||
change_always_open_with: 'Ị chọrọ I na mepee ụdị faịlụ site na',
|
||||
confirm: 'gosi',
|
||||
confirm_2fa_setup: 'Etinyela m koodu ahụ na ngwa nyocha m',
|
||||
confirm_2fa_recovery: 'Echekwala m koodu mgbake m na ebe echedoro',
|
||||
hue: 'Hue',
|
||||
confirm_account_for_free_referral_storage_c2a:
|
||||
'Mepụta akaụntụ wee kwado adreesị ozi-e gị iji nweta 1 GB nke nchekwa efu. Enyi gị ga-enwetakwa 1 GB nke nchekwa efu.',
|
||||
confirm_code_generic_incorrect: 'Koodu ezighi ezi.',
|
||||
confirm_code_generic_too_many_requests:
|
||||
'Ọtụtụ ọchịchọ. Biko chere nkeji ole na ole.',
|
||||
confirm_code_generic_submit: 'Nye koodu',
|
||||
confirm_code_generic_try_again: 'Nwa ọzọ',
|
||||
confirm_code_generic_title: 'Tinye koodu Nkwenye',
|
||||
confirm_code_2fa_instruction:
|
||||
'Tinye koodu ọnụọgụ isi site na ngwa nyocha gị.',
|
||||
confirm_code_2fa_submit_btn: 'tinye',
|
||||
confirm_code_2fa_title: 'Tinye koodu 2FA',
|
||||
confirm_delete_multiple_items:
|
||||
"Ị ji n'aka na ịchọrọ ihichapụ ihe ndị a kpamkpam?",
|
||||
confirm_delete_single_item: 'Ịchọrọ ihichapụ ihe a kpamkpam?',
|
||||
@@ -68,8 +60,6 @@ const ig = {
|
||||
confirm_session_revoke: 'O doro gị anya na ịchọrọ kagbuo nnọkọ a?',
|
||||
confirm_your_email_address: 'Kwenye na adreesị email',
|
||||
contact_us: 'Kpọtụrụ anyị',
|
||||
contact_us_verification_required:
|
||||
'Ị ga-enwerịrị adreesị email ekwenyesiri ike ka ị jiri nke a.',
|
||||
continue: "Gaa n'ihu",
|
||||
copy: 'Detuo',
|
||||
copy_link: 'Detuo njikọ',
|
||||
@@ -91,17 +81,13 @@ const ig = {
|
||||
deploy_as_app: 'Bugharịa dị ka ngwa',
|
||||
descending: 'agbadata',
|
||||
desktop: 'desktọpụ',
|
||||
desktop_background_fit: 'dabara',
|
||||
developers: 'Ndị mme ya',
|
||||
dir_published_as_website: '%strong% e bipụtara ya:',
|
||||
disable_2fa: 'Gbanyụọ 2FA',
|
||||
disable_2fa_confirm: "Ị ji n'aka na ịchọrọ gbanyụọ 2FA?",
|
||||
disable_2fa_instructions: 'Tinye paswọọdụ gị i ji gbanyụọ 2FA.',
|
||||
documents: 'akwụkwọ',
|
||||
dont_allow: 'Ekwela',
|
||||
download: 'Budata',
|
||||
download_file: 'Budata faịlụ',
|
||||
downloading: 'Nbudata',
|
||||
email: 'Email',
|
||||
email_change_confirmation_sent:
|
||||
'ezipula email nkwenye na adreesị ozi-e ọhụrụ gị. Biko lelee igbe mbata gị ma soro ntuziaka ka ịmechaa usoro ahụ.',
|
||||
@@ -130,13 +116,10 @@ const ig = {
|
||||
forgot_pass_c2a: 'Chefuru paswọọdụ?',
|
||||
from: 'si',
|
||||
general: 'Izugbe',
|
||||
get_a_copy_of_on_puter: 'Nweta otu \'%%\' na Puter.com!',
|
||||
get_copy_link: 'Nweta njikọ nke',
|
||||
home: 'ụlọ',
|
||||
html_document: 'akwụkwọ HTML',
|
||||
hue: 'Hue',
|
||||
incorrect_password: 'paswọọdụ ezighi ezi',
|
||||
invite_link: 'Njikọ ịkpọ òkù',
|
||||
item: 'ihe',
|
||||
items_in_trash_cannot_be_renamed: 'Enweghị ike ịnyegharị ihe a aha n\'ihi na ọ nọ na ahịhịa. Iji nyegharịa ihe a aha, buru ụzọ dọrọ ya na ahịhịa.',
|
||||
jpeg_image: 'Foto JPEG',
|
||||
@@ -147,7 +130,6 @@ const ig = {
|
||||
loading: 'Na-ebugo ibu',
|
||||
log_in: 'Banye',
|
||||
log_out: 'pụọ',
|
||||
looks_good: 'Ọ mara mma!',
|
||||
manage_sessions: 'Jikwaa Oge',
|
||||
modified: 'gbanwee',
|
||||
move: 'Bugharịa',
|
||||
@@ -172,7 +154,6 @@ const ig = {
|
||||
open_with: 'Ji Mepee Ya',
|
||||
original_name: 'Aha izizi',
|
||||
original_path: 'Ụzọ izizi',
|
||||
oss_code_and_content: 'Ngwanrọ na ọdịnaya mepere emepe',
|
||||
password: 'paswọọdụ',
|
||||
password_changed: 'gbanwere paswọọdụ.',
|
||||
password_recovery_rate_limit:
|
||||
@@ -189,27 +170,20 @@ const ig = {
|
||||
paste: 'tinye',
|
||||
paste_into_folder: "Tinye n'ime nchekwa",
|
||||
path: 'ụzọ',
|
||||
personalization: 'Nhazi onwe',
|
||||
pick_name_for_website: 'Họrọ aha maka weebụsaịtị gị:',
|
||||
pictures: 'Foto',
|
||||
plural_suffix: 's',
|
||||
powered_by_puter_js: 'Kwadoro site na {{link=docs}}Puter.js{{/link}}',
|
||||
preparing: 'Na-akwado...',
|
||||
preparing_for_upload: 'Na-akwado maka bulite...',
|
||||
print: 'ebipụta',
|
||||
privacy: 'Nzuzo',
|
||||
proceed_to_login: 'Gaba na nbanye',
|
||||
proceed_with_account_deletion: "Gaa n'ihu na ihichapụ akaụntụ",
|
||||
properties: 'Njirimara',
|
||||
public: 'eze',
|
||||
publish: 'Bipụta',
|
||||
publish_as_website: 'Bipụta dị ka webụsaịtị',
|
||||
puter_description: 'Puter bụ igwe ojii nzuzo nke mbụ iji dobe faịlụ gị, ngwa na egwuregwu gị n\'otu ebe echekwara, enwere ike ịnweta ya ebe ọ bụla n\'oge ọ bụla..',
|
||||
reading_file: 'ọgụgụ %strong%',
|
||||
recover_password: 'Weghachite paswọọdụ',
|
||||
refer_friends_c2a:
|
||||
'Nweta 1 GB maka enyi ọ bụla mepụtara ma kwado akaụntụ na Puter. Enyi gị ga-enwetakwa 1 GB!',
|
||||
refer_friends_social_media_c2a: 'Nweta 1 GB nke nchekwa efu na Puter.com!',
|
||||
refresh: 'Weghachite ume',
|
||||
rename: 'Nyegharịa aha',
|
||||
replace: 'Dochie',
|
||||
@@ -219,12 +193,10 @@ const ig = {
|
||||
save: 'chekwa',
|
||||
saturation: 'juputa',
|
||||
save_account: 'Chekwa akaụntụ',
|
||||
save_account_to_get_copy_link: "Biko mepụta akaụntụ iji gaa n'ihu.",
|
||||
save_account_to_publish: "Biko mepụta akaụntụ iji gaa n'ihu.",
|
||||
save_session: 'Chekwa oge',
|
||||
save_session_c2a:
|
||||
"Mepụta akaụntụ iji chekwaa nnọkọ gị ugbu a ma zere ịla n'iyi ọrụ gị.",
|
||||
scan_qr_2fa: 'Jiri ngwa nyocha gị nyochaa QR koodu',
|
||||
search: 'Chọọ',
|
||||
seconds: 'sekọnd',
|
||||
security: 'nche',
|
||||
@@ -242,13 +214,11 @@ const ig = {
|
||||
show_hidden: 'Gosi ihe ezozo',
|
||||
sign_in_with_puter: 'Jiri Puter banye',
|
||||
sign_up: 'Debanye aha',
|
||||
signing_in: 'Ịbanye…',
|
||||
size: 'Nha',
|
||||
skip: 'Mafee',
|
||||
something_went_wrong: 'Ọ nwere ihe adịghị mma.',
|
||||
sort_by: 'Hazie site na',
|
||||
status: 'Ọnọdụ',
|
||||
storage_usage: 'Ojiji Nchekwa',
|
||||
storage_puter_used: 'nke Puter na-ji',
|
||||
taking_longer_than_usual:
|
||||
'Na-ewe obere oge karịa ka ọ dị na mbụ. Biko chere...',
|
||||
@@ -277,29 +247,23 @@ const ig = {
|
||||
videos: 'Vidiyo',
|
||||
visibility: 'Nhụta',
|
||||
yes: 'Ee',
|
||||
you_have_been_referred_to_puter_by_a_friend: 'Otu enyi zigara gị na Puter!',
|
||||
zip: 'Zip',
|
||||
zipping_file: 'Zipping %strong%',
|
||||
|
||||
// === 2FA Setup ===
|
||||
setup2fa_1_step_heading: 'Mepee ngwa nyocha',
|
||||
setup2fa_1_instructions: `
|
||||
Ị nwere ike iji ngwa nyocha ọ bụla na-akwado protocol Paswọdu Otu oge (TOTP) dabere na Oge.
|
||||
Enwere ọtụtụ nhọrọ, mana ọ bụrụ na ị maghị
|
||||
<a target="_blank" href="https://authy.com/download">Authy</a>
|
||||
bụ nhọrọ siri ike maka android na iOS.
|
||||
`,
|
||||
setup2fa_2_step_heading: 'Nyochaa QR koodu',
|
||||
setup2fa_3_step_heading: 'Tinye koodu ọnụọgụ isi',
|
||||
setup2fa_4_step_heading: 'Detuo koodu mgbake gị',
|
||||
setup2fa_4_instructions: `
|
||||
Koodu mgbake ndị a bụ naanị ụzọ ị ga-esi iba akaụntụ gị ma ọ bụrụ na ekwentị gị furu ma ọ bụ enweghị ike iji ngwa nyocha gị..
|
||||
Gbaa mbọ hụ na ịchekwaa ha n'ebe dị mma.
|
||||
`,
|
||||
setup2fa_5_step_heading: 'Kwenye ntọlite 2FA',
|
||||
setup2fa_5_confirmation_1: 'Echekwala m koodu mgbake m na ebe echekwa',
|
||||
setup2fa_5_confirmation_2: 'Adị m njikere i Kwado 2FA',
|
||||
setup2fa_5_button: 'Kwado 2FA',
|
||||
|
||||
// === 2FA Login ===
|
||||
login2fa_otp_title: 'Tinye koodu 2FA',
|
||||
@@ -308,7 +272,6 @@ const ig = {
|
||||
login2fa_recovery_instructions:
|
||||
'Tinye otu koodu mgbake gị i ji eba akaụntụ gị.',
|
||||
login2fa_use_recovery_code: 'Ji koodu mgbake',
|
||||
login2fa_recovery_back: 'Azu',
|
||||
login2fa_recovery_placeholder: 'XXXXXXXX',
|
||||
|
||||
change: 'gbanwee',
|
||||
@@ -379,20 +342,13 @@ const ig = {
|
||||
'billing.expanded': 'Gbasaa', // In English: "Expanded"
|
||||
'billing.accelerated': 'Ọsọ ọsọ', // In English: "Accelerated"
|
||||
'billing.enjoy_msg': 'Nwee obi ụtọ na Nchekwa igwe ojii gbakwunyere uru ndị ọzọ', // In English: "Enjoy %% of Cloud Storage plus other benefits."
|
||||
'choose_publishing_option': 'Họrọ otu ịchọrọ ibipụta weebụsaịtị gị:', // In English: "Choose how you want to publish your website:"
|
||||
'create_desktop_shortcut': 'Mepụta Ụzọ mkpirisi (Desktọpụ)', // In English: "Create Shortcut (Desktop)"
|
||||
'create_desktop_shortcut_s': 'Mepụta Ụzọ mkpirisi (Desktọpụ)', // In English: "Create Shortcuts (Desktop)"
|
||||
'create_shortcut_s': 'Mepụta ụzọ mkpirisi', // In English: "Create Shortcuts"
|
||||
'minimize': 'Wedata', // In English: "Minimize"
|
||||
'reload_app': 'Bugharịa ngwa', // In English: "Reload App"
|
||||
'publish_as_serverless_worker': 'Bipụta dị ka onye ọrụ', // In English: "Publish as Worker"
|
||||
'toolbar.enter_fullscreen': 'Tinye ihuenyo zuru oke', // In English: "Enter Full Screen"
|
||||
'toolbar.github': 'GitHub', // In English: "GitHub"
|
||||
'toolbar.refer': 'Tụtụ aka', // In English: "Refer"
|
||||
'used_of': '{{used}} ejiri {{available}}', // In English: "{{used}} used of {{available}}"
|
||||
'worker': 'Onye ọrụ', // In English: "Worker"
|
||||
'billing.offering.basic': 'Isi', // In English: "Basic"
|
||||
'too_many_attempts': 'Ọtụtụ mbọ. Biko nwaa ọzọ ma emechaa.', // In English: "Too many attempts. Please try again later."
|
||||
'server_timeout': 'Ihe nkesa ahụ were ogologo oge iji zaghachi. Biko nwaa ọzọ.', // In English: "The server took too long to respond. Please try again."
|
||||
'signup_error': "Enwere mperi n'oge ndebanye aha. Biko nwaa ọzọ.", // In English: "An error occurred during signup. Please try again."
|
||||
'alert_error_title': 'Njehie!', // In English: "Error!"
|
||||
@@ -410,15 +366,10 @@ const ig = {
|
||||
'window_title_open': 'Mepee', // In English: "Open"
|
||||
'window_title_change_password': 'Gbanwee okwuntughe', // In English: "Change Password"
|
||||
'window_title_select_font': 'Họrọ font…', // In English: "Select font…"
|
||||
'window_title_session_list': 'Ndepụta Oge!', // In English: "Session List!"
|
||||
'window_title_set_new_password': 'Tọọ okwuntughe ọhụrụ', // In English: "Set New Password"
|
||||
'window_title_publish_website': 'Bipụta Weebụsaịtị', // In English: "Publish Website"
|
||||
'window_title_publish_worker': 'Bipụta Onye Ọrụ', // In English: "Publish Worker"
|
||||
'window_title_authenticating': 'Na-achọpụta...', // In English: "Authenticating..."
|
||||
'window_title_refer_friend': 'Tụgharịa enyi!', // In English: "Refer a friend!"
|
||||
'desktop_exit_full_screen': 'Wepụ ihuenyo zuru oke', // In English: "Exit Full Screen"
|
||||
'desktop_enter_full_screen': 'Tinye ihuenyo zuru oke', // In English: "Enter Full Screen"
|
||||
'item_shared_with_you': 'Onye ọrụ ekenyela gị ihe a.', // In English: "A user has shared this item with you."
|
||||
'item_shared_by_you': 'Ị kekọrịtala ihe a na opekata mpe otu onye ọrụ ọzọ', // In English: " with at least one other user."
|
||||
'item_shortcut': 'Ụzọ mkpirisi', // In English: "Shortcut"
|
||||
'item_associated_websites': 'Weebụsaịtị emetụtara', // In English: "Associated website"
|
||||
@@ -427,9 +378,6 @@ const ig = {
|
||||
'window_click_to_go_back': 'Pịa ka ịlaghachi azụ.', // In English: "Click to go back."
|
||||
'window_click_to_go_forward': "Pịa ka ịga n'ihu.", // In English: "Click to goard."
|
||||
'window_click_to_go_up': 'Pịa ka iwelie elu otu ndekọ.', // In English: "Click to go one directory up."
|
||||
'window_title_public': 'Ọha', // In English: "Public"
|
||||
'window_title_videos': 'Vidiyo', // In English: "Videos"
|
||||
'window_title_pictures': 'Foto', // In English: "Pictures"
|
||||
'window_title_puter': 'Puter', // In English: "Puter"
|
||||
'window_folder_empty': 'Mpempe akwụkwọ a tọgbọ chakoo', // In English: "This folder is empty"
|
||||
},
|
||||
|
||||
@@ -31,7 +31,6 @@ const it = {
|
||||
allow: 'Consenti',
|
||||
ascending: 'Ascendente',
|
||||
associated_websites: 'Siti associati',
|
||||
auto_arrange: 'Organizzazione automatica',
|
||||
cancel: 'Annulla',
|
||||
change_email: 'Modifica Email',
|
||||
change_language: 'Cambia lingua',
|
||||
@@ -41,20 +40,13 @@ const it = {
|
||||
close_all_windows_and_log_out: 'Chiudi tutte le finestre e disconnettiti',
|
||||
change_always_open_with: 'Vuoi sempre aprire questo tipo di file con',
|
||||
confirm: 'Conferma',
|
||||
confirm_2fa_setup: 'Ho aggiunto il codice alla mia app di autenticazione',
|
||||
confirm_2fa_recovery: 'Ho salvato il codice di recupero in un posto sicuro',
|
||||
confirm_account_for_free_referral_storage_c2a:
|
||||
'Crea un account e conferma la tua email per ricevere 1 GB di spazio di archiviazione gratuito. Anche il tuo amico riceverà dello spazio extra!',
|
||||
confirm_code_generic_incorrect: 'Codice errato.',
|
||||
confirm_code_generic_too_many_requests:
|
||||
'Troppe richieste. Attendi qualche minuto.',
|
||||
confirm_code_generic_submit: 'Invia Codice',
|
||||
confirm_code_generic_try_again: 'Riprova',
|
||||
confirm_code_generic_title: 'Inserisci Codice di Conferma',
|
||||
confirm_code_2fa_instruction:
|
||||
'Inserisci il codice a 6 cifre dalla tua app di autenticazione.',
|
||||
confirm_code_2fa_submit_btn: 'Invia',
|
||||
confirm_code_2fa_title: 'Inserisci il Codice 2FA',
|
||||
confirm_delete_multiple_items:
|
||||
'Sei sicuro di voler eliminare definitivamente questi elementi?',
|
||||
confirm_delete_single_item:
|
||||
@@ -68,8 +60,6 @@ const it = {
|
||||
confirm_session_revoke: 'Sei sicuro di voler revocare questa sessione?',
|
||||
confirm_your_email_address: 'Conferma il tuo indirizzo email',
|
||||
contact_us: 'Contattaci',
|
||||
contact_us_verification_required:
|
||||
'Devi verificare il tuo indirizzo email per utilizzare questa funzione.',
|
||||
continue: 'Continua',
|
||||
copy: 'Copia',
|
||||
copy_link: 'Copia il link',
|
||||
@@ -91,18 +81,14 @@ const it = {
|
||||
deploy_as_app: 'Distribuisci come Applicazione',
|
||||
descending: 'Discendente',
|
||||
desktop: 'Scrivania',
|
||||
desktop_background_fit: 'Adatta',
|
||||
developers: 'Sviluppatori',
|
||||
dir_published_as_website: '%strong% è stato pubblicato su:',
|
||||
disable_2fa: 'Disabilita 2FA',
|
||||
disable_2fa_confirm: 'Sei sicuro di voler disabilitare la 2FA?',
|
||||
disable_2fa_instructions:
|
||||
'Inserisci la tua password per disabilitare la 2FA.',
|
||||
documents: 'Documenti',
|
||||
dont_allow: 'Non consentire',
|
||||
download: 'Scarica',
|
||||
download_file: 'Scarica file',
|
||||
downloading: 'Download in corso',
|
||||
email: 'Email',
|
||||
email_change_confirmation_sent:
|
||||
"Ti abbiamo inviato un'email di conferma. Controlla la tua casella di posta e segui le istruzioni per completare il processo.",
|
||||
@@ -131,13 +117,10 @@ const it = {
|
||||
forgot_pass_c2a: 'Password dimenticata?',
|
||||
from: 'Da',
|
||||
general: 'Generale',
|
||||
get_a_copy_of_on_puter: 'Ottieni una copia di \'%%\' su Puter.com!',
|
||||
get_copy_link: 'Ottieni link di copia',
|
||||
home: 'Home',
|
||||
html_document: 'Documento HTML',
|
||||
hue: 'Tonalità',
|
||||
incorrect_password: 'Password errata',
|
||||
invite_link: 'Link d’invito',
|
||||
item: 'elemento',
|
||||
items_in_trash_cannot_be_renamed: 'Impossibile rinominare un elemento nel Cestino. Per rinominarlo, è necessario ripristinarlo.',
|
||||
jpeg_image: 'Immagine JPEG',
|
||||
@@ -148,7 +131,6 @@ const it = {
|
||||
loading: 'Caricamento',
|
||||
log_in: 'Accedi',
|
||||
log_out: 'Disconnettiti',
|
||||
looks_good: 'Sembra buono!',
|
||||
manage_sessions: 'Gestisci le sessioni',
|
||||
modified: 'Modificato',
|
||||
move: 'Sposta',
|
||||
@@ -173,7 +155,6 @@ const it = {
|
||||
open_with: 'Apri con',
|
||||
original_name: 'Nome originale',
|
||||
original_path: 'Percorso originale',
|
||||
oss_code_and_content: 'Contenuto e software Open Source',
|
||||
password: 'Password',
|
||||
password_changed: 'Password modificata.',
|
||||
password_recovery_rate_limit:
|
||||
@@ -190,27 +171,20 @@ const it = {
|
||||
paste: 'Incolla',
|
||||
paste_into_folder: 'Incolla nella cartella',
|
||||
path: 'Percorso',
|
||||
personalization: 'Personalizzazione',
|
||||
pick_name_for_website: 'Scegli un nome per il tuo sito web:',
|
||||
pictures: 'Immagini',
|
||||
plural_suffix: 'i',
|
||||
powered_by_puter_js: 'Realizzato con {{link=docs}}Puter.js{{/link}}',
|
||||
preparing: 'Preparazione in corso...',
|
||||
preparing_for_upload: 'Preparazione per l’upload...',
|
||||
print: 'Stampa',
|
||||
privacy: 'Privacy',
|
||||
proceed_to_login: 'Procedi con il login',
|
||||
proceed_with_account_deletion: "Continua con l'eliminazione dell'account",
|
||||
properties: 'Proprietà',
|
||||
public: 'Pubblico',
|
||||
publish: 'Pubblica',
|
||||
publish_as_website: 'Pubblica come sito web',
|
||||
puter_description: 'Puter è un cloud personale che mette la privacy al primo posto, per conservare tutti i tuoi file, app e giochi in un unico luogo sicuro, accessibile da qualsiasi luogo e in qualsiasi momento.',
|
||||
reading_file: 'Leggendo %strong%',
|
||||
recover_password: 'Ripristina la Password',
|
||||
refer_friends_c2a:
|
||||
'Ottieni 1 GB di spazio di archiviazione per ogni amico che crea un account e conferma l’email su Puter. Anche il tuo amico riceverà dello spazio extra!',
|
||||
refer_friends_social_media_c2a: 'Ottieni 1GB di spazio di spazio di archiviazione gratuito su Puter.com!',
|
||||
refresh: 'Ricarica',
|
||||
rename: 'Rinomina',
|
||||
replace: 'Sostituisci',
|
||||
@@ -220,13 +194,10 @@ const it = {
|
||||
save: 'Salva',
|
||||
saturation: 'Saturazione',
|
||||
save_account: 'Salva Account',
|
||||
save_account_to_get_copy_link:
|
||||
'È necessario creare un account per procedere.',
|
||||
save_account_to_publish: 'È necessario creare un account per procedere.',
|
||||
save_session: 'Salva sessione',
|
||||
save_session_c2a:
|
||||
'Crea un account per salvare la tua sessione e non perdere i tuoi dati.',
|
||||
scan_qr_2fa: 'Scansiona il codice QR con la tua app di autenticazione',
|
||||
search: 'Search',
|
||||
seconds: 'seconds',
|
||||
security: 'Sicurezza',
|
||||
@@ -246,13 +217,11 @@ const it = {
|
||||
show_hidden: 'Mostra nascosti',
|
||||
sign_in_with_puter: 'Accedi con Puter',
|
||||
sign_up: 'Registrati',
|
||||
signing_in: 'Accesso in corso…',
|
||||
size: 'Dimensione',
|
||||
skip: 'Salta',
|
||||
something_went_wrong: 'Qualcosa è andato storto.',
|
||||
sort_by: 'Ordina per',
|
||||
status: 'Stato',
|
||||
storage_usage: 'Utilizzo dello spazio',
|
||||
storage_puter_used: 'utilizzato da Puter',
|
||||
taking_longer_than_usual:
|
||||
'Il processo in corso ci sta mettendo più del solito. Attendere prego...',
|
||||
@@ -282,31 +251,24 @@ const it = {
|
||||
videos: 'Video',
|
||||
visibility: 'Visibilità',
|
||||
yes: 'Sì',
|
||||
you_have_been_referred_to_puter_by_a_friend:
|
||||
'Sei stato invitato su Puter da un amico!',
|
||||
zip: 'File compresso',
|
||||
zipping_file: 'Compressione di %strong%',
|
||||
|
||||
// === 2FA Setup ===
|
||||
setup2fa_1_step_heading: 'Apri la tua app di autenticazione',
|
||||
setup2fa_1_instructions: `
|
||||
Puoi utilizzare qualsiasi app di autenticazione che supporti il protocollo TOTP (Time-based One-Time Password).
|
||||
Ci sono molte opzioni tra cui scegliere, ma se non sei sicuro,
|
||||
<a target="_blank" href="https://authy.com/download">Authy</a>
|
||||
è una scelta valida sia per Android che per iOS.
|
||||
`,
|
||||
setup2fa_2_step_heading: 'Scansiona il codice QR',
|
||||
setup2fa_3_step_heading: 'Inserisci il codice a 6 cifre',
|
||||
setup2fa_4_step_heading: 'Copia i tuoi codici di recupero',
|
||||
setup2fa_4_instructions: `
|
||||
Questi codici di recupero sono l'unico modo per accedere al tuo account se perdi il telefono o non puoi utilizzare la tua app di autenticazione.
|
||||
Assicurati di conservarli in un luogo sicuro.
|
||||
`,
|
||||
setup2fa_5_step_heading: 'Conferma la configurazione del 2FA',
|
||||
setup2fa_5_confirmation_1:
|
||||
'Ho salvato i miei codici di recupero in un luogo sicuro',
|
||||
setup2fa_5_confirmation_2: 'Sono pronto per abilitare la 2FA',
|
||||
setup2fa_5_button: 'Abilita la 2FA',
|
||||
|
||||
// === 2FA Login ===
|
||||
login2fa_otp_title: 'Inserisci il codice 2FA',
|
||||
@@ -316,7 +278,6 @@ const it = {
|
||||
login2fa_recovery_instructions:
|
||||
'Inserisci uno dei tuoi codici di recupero per accedere al tuo account.',
|
||||
login2fa_use_recovery_code: 'Usa un codice di recupero',
|
||||
login2fa_recovery_back: 'Indietro',
|
||||
login2fa_recovery_placeholder: 'XXXXXXXX',
|
||||
|
||||
change: 'Cambia', // In English: "Change"
|
||||
@@ -387,20 +348,13 @@ const it = {
|
||||
'billing.accelerated': 'Accelerato', // In English: "Accelerated"
|
||||
'billing.enjoy_msg': 'Goditi %% di spazio di archiviazione cloud e altri vantaggi.', // In English: "Enjoy %% of Cloud Storage plus other benefits."
|
||||
|
||||
'choose_publishing_option': 'Scegli come vuoi pubblicare il tuo sito web:',
|
||||
'create_desktop_shortcut': 'Crea un collegamento sul desktop',
|
||||
'create_desktop_shortcut_s': 'Crea collegamenti sul desktop',
|
||||
'create_shortcut_s': 'Crea scorciatoie',
|
||||
'minimize': 'Riduci',
|
||||
'reload_app': 'Ricarica app',
|
||||
'publish_as_serverless_worker': 'Pubblica come funzione serverless', // In English: "Publish as Worker"
|
||||
'toolbar.enter_fullscreen': 'Visualizza a schermo intero',
|
||||
'toolbar.github': 'GitHub',
|
||||
'toolbar.refer': 'Invita',
|
||||
'used_of': '{{used}} utilizzati su {{available}}', // In English: "{{used}} used of {{available}}"
|
||||
'worker': 'Worker', // In English: "Worker"
|
||||
'billing.offering.basic': 'Base', // In English: "Basic"
|
||||
'too_many_attempts': 'Troppi tentativi. Riprova più tardi',
|
||||
'server_timeout': 'Il server ha impiegato troppo tempo per rispondere. Riprova.',
|
||||
'signup_error': 'Si è verificato un errore durante la registrazione. Riprova.',
|
||||
'alert_error_title': 'Errore!',
|
||||
@@ -418,15 +372,10 @@ const it = {
|
||||
'window_title_open': 'Apri',
|
||||
'window_title_change_password': 'Cambia password',
|
||||
'window_title_select_font': 'Seleziona il carattere...',
|
||||
'window_title_session_list': 'Lista delle sessioni',
|
||||
'window_title_set_new_password': 'Imposta la nuova password',
|
||||
'window_title_publish_website': 'Pubblica sito web',
|
||||
'window_title_publish_worker': 'Pubblica worker', // In English: "Publish Worker"
|
||||
'window_title_authenticating': 'Autenticazione in corso...',
|
||||
'window_title_refer_friend': 'Invita un amico!',
|
||||
'desktop_exit_full_screen': 'Esci da schermo intero',
|
||||
'desktop_enter_full_screen': 'Visualizza a schermo intero',
|
||||
'item_shared_with_you': 'Un utente ha condiviso questo elemento con te.',
|
||||
'item_shared_by_you': 'Hai condiviso questo elemento con almeno un altro utente',
|
||||
'item_shortcut': 'Scorciatoia',
|
||||
'item_associated_websites': 'Sito web associato',
|
||||
@@ -435,9 +384,6 @@ const it = {
|
||||
'window_click_to_go_back': 'Clicca per tornare indietro.',
|
||||
'window_click_to_go_forward': 'Clicca per andare avanti.',
|
||||
'window_click_to_go_up': 'Clicca per andare alla cartella superiore.', // In English: "Click to go one directory up."
|
||||
'window_title_public': 'Pubblica',
|
||||
'window_title_videos': 'Video', // In Italian there's no translation for "videos", we use "più video" translated in "more videos"; in this case all the OSs use "video"
|
||||
'window_title_pictures': 'Foto',
|
||||
'window_title_puter': 'Puter',
|
||||
'window_folder_empty': 'Questa cartella è vuota',
|
||||
|
||||
|
||||
@@ -31,7 +31,6 @@ const ja = {
|
||||
allow: '許可',
|
||||
ascending: '昇順',
|
||||
associated_websites: '関連ウェブサイト',
|
||||
auto_arrange: '自動配置',
|
||||
cancel: 'キャンセル',
|
||||
change_email: 'メールアドレスを変更',
|
||||
change_language: '言語を変更',
|
||||
@@ -41,17 +40,10 @@ const ja = {
|
||||
close_all_windows_and_log_out: 'ウィンドウを閉じてログアウト',
|
||||
change_always_open_with: 'この種類のファイルを常にこのアプリで開きますか?',
|
||||
confirm: '確認',
|
||||
confirm_2fa_setup: '認証アプリにコードを追加しました',
|
||||
confirm_2fa_recovery: 'リカバリーコードを安全な場所に保存しました',
|
||||
confirm_account_for_free_referral_storage_c2a: 'アカウントを作成してメールアドレスを確認すると、1GBの無料ストレージを獲得できます。友人も1GBの無料ストレージを獲得します。',
|
||||
confirm_code_generic_incorrect: 'コードが間違っています。',
|
||||
confirm_code_generic_too_many_requests: 'リクエストが多すぎます。数分待ってください。',
|
||||
confirm_code_generic_submit: 'コードを送信',
|
||||
confirm_code_generic_try_again: 'もう一度試す',
|
||||
confirm_code_generic_title: '確認コードを入力',
|
||||
confirm_code_2fa_instruction: '認証アプリから6桁のコードを入力してください。',
|
||||
confirm_code_2fa_submit_btn: '送信',
|
||||
confirm_code_2fa_title: '2FAコードを入力',
|
||||
confirm_delete_multiple_items: 'これらの項目を完全に削除してよろしいですか?',
|
||||
confirm_delete_single_item: 'この項目を完全に削除してよろしいですか?',
|
||||
confirm_open_apps_log_out: 'アプリが開いています。ログアウトしてもよろしいですか?',
|
||||
@@ -61,7 +53,6 @@ const ja = {
|
||||
confirm_session_revoke: 'このセッションを取り消してもよろしいですか?',
|
||||
confirm_your_email_address: 'メールアドレスを確認',
|
||||
contact_us: 'お問い合わせ',
|
||||
contact_us_verification_required: 'この機能を使用するには、確認済みのメールアドレスが必要です。',
|
||||
continue: '続行',
|
||||
copy: 'コピー',
|
||||
copy_link: 'リンクをコピー',
|
||||
@@ -83,17 +74,13 @@ const ja = {
|
||||
deploy_as_app: 'アプリとしてデプロイ',
|
||||
descending: '降順',
|
||||
desktop: 'デスクトップ',
|
||||
desktop_background_fit: '画面背景をフィット',
|
||||
developers: '開発者',
|
||||
dir_published_as_website: '%strong% が公開されました:',
|
||||
disable_2fa: '2FAを無効にする',
|
||||
disable_2fa_confirm: '2FAを無効にしてよろしいですか?',
|
||||
disable_2fa_instructions: 'パスワードを入力して2FAを無効にします。',
|
||||
documents: 'ドキュメント',
|
||||
dont_allow: '許可しない',
|
||||
download: 'ダウンロード',
|
||||
download_file: 'ファイルをダウンロード',
|
||||
downloading: 'ダウンロード中',
|
||||
email: 'メール',
|
||||
email_change_confirmation_sent: '確認メールが新しいメールアドレスに送信されました。受信トレイを確認し、指示に従って手続きを完了してください。',
|
||||
email_invalid: 'メールアドレスが無効です。',
|
||||
@@ -118,13 +105,10 @@ const ja = {
|
||||
forgot_pass_c2a: 'パスワードを忘れましたか?',
|
||||
from: '送信者',
|
||||
general: '一般',
|
||||
get_a_copy_of_on_puter: 'Puter.comで \'%%\' のコピーを取得!',
|
||||
get_copy_link: 'コピーリンクを取得',
|
||||
home: 'ホーム',
|
||||
html_document: 'HTML文書',
|
||||
hue: '色合い',
|
||||
incorrect_password: 'パスワードが間違っています',
|
||||
invite_link: '招待リンク',
|
||||
item: 'アイテム',
|
||||
items_in_trash_cannot_be_renamed: 'このアイテムはゴミ箱にあるため、名前を変更できません。このアイテムの名前を変更するには、まずゴミ箱からドラッグしてください。',
|
||||
jpeg_image: 'JPEG画像',
|
||||
@@ -135,7 +119,6 @@ const ja = {
|
||||
loading: '読み込み中',
|
||||
log_in: 'ログイン',
|
||||
log_out: 'ログアウト',
|
||||
looks_good: 'ナイス!',
|
||||
manage_sessions: 'セッションを管理',
|
||||
modified: '変更日時',
|
||||
move: '移動',
|
||||
@@ -160,7 +143,6 @@ const ja = {
|
||||
open_with: 'アプリケーションで開く',
|
||||
original_name: '元の名前',
|
||||
original_path: '元のパス',
|
||||
oss_code_and_content: 'オープンソースソフトウェアとコンテンツ',
|
||||
password: 'パスワード',
|
||||
password_changed: 'パスワードが変更されました。',
|
||||
password_recovery_rate_limit: 'レート制限に達しました。数分待ってください。将来これを防ぐために、ページを何度もリロードしないでください。',
|
||||
@@ -172,26 +154,19 @@ const ja = {
|
||||
paste: '貼り付け',
|
||||
paste_into_folder: 'フォルダーに貼り付け',
|
||||
path: 'パス',
|
||||
personalization: 'パーソナライズ',
|
||||
pick_name_for_website: 'ウェブサイトの名前を選んでください:',
|
||||
pictures: '写真',
|
||||
plural_suffix: '',
|
||||
powered_by_puter_js: '{{link=docs}}Puter.js{{/link}} によって提供されています',
|
||||
preparing: '準備中...',
|
||||
preparing_for_upload: 'アップロードの準備中...',
|
||||
print: '印刷',
|
||||
privacy: 'プライバシー',
|
||||
proceed_to_login: 'ログインに進む',
|
||||
proceed_with_account_deletion: 'アカウントの削除を続行',
|
||||
properties: 'プロパティ',
|
||||
public: '公開',
|
||||
publish: '公開',
|
||||
publish_as_website: 'ウェブサイトとして公開',
|
||||
puter_description: 'Puterは、すべてのファイル、アプリ、およびゲームを一か所に安全に保管し、いつでもどこからでもアクセスできるプライバシー重視の個人用クラウドです。',
|
||||
reading_file: '読み込み中 %strong%',
|
||||
recover_password: 'パスワードを回復',
|
||||
refer_friends_c2a: '友達がPuterでアカウントを作成して確認すると、1GBを獲得できます。友達も1GBを獲得できます!',
|
||||
refer_friends_social_media_c2a: 'Puter.comで1GBの無料ストレージを手に入れよう!',
|
||||
refresh: '更新',
|
||||
rename: '名前を変更',
|
||||
replace: '置換',
|
||||
@@ -201,11 +176,9 @@ const ja = {
|
||||
save: '保存',
|
||||
saturation: '彩度',
|
||||
save_account: 'アカウントを保存',
|
||||
save_account_to_get_copy_link: '続行するにはアカウントを作成してください。',
|
||||
save_account_to_publish: '続行するにはアカウントを作成してください。',
|
||||
save_session: 'セッションを保存',
|
||||
save_session_c2a: '現在のセッションを保存して、作業を失わないようにするにはアカウントを作成してください。',
|
||||
scan_qr_2fa: '認証アプリでQRコードをスキャンしてください',
|
||||
search: '検索',
|
||||
seconds: '秒',
|
||||
security: 'セキュリティ',
|
||||
@@ -223,13 +196,11 @@ const ja = {
|
||||
show_hidden: '隠しファイルを表示',
|
||||
sign_in_with_puter: 'Puterでサインイン',
|
||||
sign_up: 'サインアップ',
|
||||
signing_in: 'サインイン中…',
|
||||
size: 'サイズ',
|
||||
skip: 'スキップ',
|
||||
something_went_wrong: '問題が発生しました。',
|
||||
sort_by: '並べ替え',
|
||||
status: 'ステータス',
|
||||
storage_usage: 'ストレージ使用量',
|
||||
storage_puter_used: 'Puterで使用中',
|
||||
taking_longer_than_usual: 'いつもより少し時間がかかっています。お待ちください...',
|
||||
terms: '利用規約',
|
||||
@@ -257,29 +228,23 @@ const ja = {
|
||||
videos: '動画',
|
||||
visibility: '見え方',
|
||||
yes: 'はい',
|
||||
you_have_been_referred_to_puter_by_a_friend: '友達からPuterに紹介されました!',
|
||||
zip: '圧縮',
|
||||
zipping_file: '圧縮中 %strong%',
|
||||
|
||||
// === 2FA Setup ===
|
||||
setup2fa_1_step_heading: '認証アプリを開く',
|
||||
setup2fa_1_instructions: `
|
||||
Time-based One-Time Password (TOTP) プロトコルをサポートする任意の認証アプリを使用できます。
|
||||
多くの選択肢がありますが、迷った場合は
|
||||
<a target="_blank" href="https://authy.com/download">Authy</a>
|
||||
がAndroidとiOSのおすすめの選択肢です。
|
||||
`,
|
||||
setup2fa_2_step_heading: 'QRコードをスキャンする',
|
||||
setup2fa_3_step_heading: '6桁のコードを入力',
|
||||
setup2fa_4_step_heading: '回復コードをコピーする',
|
||||
setup2fa_4_instructions: `
|
||||
これらの回復コードは、電話を紛失したり認証アプリを使用できない場合にアカウントにアクセスする唯一の方法です。
|
||||
安全な場所に保管してください。
|
||||
`,
|
||||
setup2fa_5_step_heading: '2FA設定を確認',
|
||||
setup2fa_5_confirmation_1: '回復コードを安全な場所に保存しました',
|
||||
setup2fa_5_confirmation_2: '2FAを有効にする準備ができました',
|
||||
setup2fa_5_button: '2FAを有効にする',
|
||||
|
||||
// === 2FA Login ===
|
||||
login2fa_otp_title: '2FAコードを入力',
|
||||
@@ -287,7 +252,6 @@ const ja = {
|
||||
login2fa_recovery_title: '回復コードを入力',
|
||||
login2fa_recovery_instructions: 'アカウントにアクセスするために、回復コードの1つを入力してください。',
|
||||
login2fa_use_recovery_code: '回復コードを使用',
|
||||
login2fa_recovery_back: '戻る',
|
||||
|
||||
login2fa_recovery_placeholder: 'XXXXXXXX',
|
||||
|
||||
@@ -358,20 +322,13 @@ const ja = {
|
||||
// =============================================================
|
||||
// Missing translations
|
||||
// =============================================================
|
||||
'choose_publishing_option': 'Webサイトの公開方法を選択してください:', // In English: "Choose how you want to publish your website:"
|
||||
'create_desktop_shortcut': 'ショートカットを作成(デスクトップ)', // In English: "Create Shortcut (Desktop)"
|
||||
'create_desktop_shortcut_s': 'ショートカットを作成(デスクトップ)', // In English: "Create Shortcuts (Desktop)"
|
||||
'create_shortcut_s': 'ショートカットを作成', // In English: "Create Shortcuts"
|
||||
'minimize': '最小化', // In English: "Minimize"
|
||||
'reload_app': 'アプリを再読み込み', // In English: "Reload App"
|
||||
'publish_as_serverless_worker': 'ワーカーとして公開', // In English: "Publish as Worker"
|
||||
'toolbar.enter_fullscreen': '全画面表示にする', // In English: "Enter Full Screen"
|
||||
'toolbar.github': 'GitHub', // In English: "GitHub"
|
||||
'toolbar.refer': '参照する', // In English: "Refer"
|
||||
'used_of': '{{available}} のうち {{used}} を使用', // In English: "{{used}} used of {{available}}"
|
||||
'worker': 'ワーカー', // In English: "Worker"
|
||||
'billing.offering.basic': 'ベーシック', // In English: "Basic"
|
||||
'too_many_attempts': '試行回数の上限に達しました。時間をおいてからもう一度お試しください。', // In English: "Too many attempts. Please try again later."
|
||||
'server_timeout': 'サーバーからの応答がありません。もう一度お試しください。', // In English: "The server took too long to respond. Please try again."
|
||||
'signup_error': 'サインアップ中にエラーが発生しました。もう一度お試しください。', // In English: "An error occurred during signup. Please try again."
|
||||
'alert_error_title': 'エラー!', // In English: "Error!"
|
||||
@@ -389,15 +346,10 @@ const ja = {
|
||||
'window_title_open': '開く', // In English: "Open"
|
||||
'window_title_change_password': 'パスワードを変更', // In English: "Change Password"
|
||||
'window_title_select_font': 'フォントを選択...', // In English: "Select font…"
|
||||
'window_title_session_list': 'セッション一覧!', // In English: "Session List!"
|
||||
'window_title_set_new_password': '新しいパスワードを設定', // In English: "Set New Password"
|
||||
'window_title_publish_website': 'ウェブサイトを公開', // In English: "Publish Website"
|
||||
'window_title_publish_worker': 'ワーカーを公開', // In English: "Publish Worker"
|
||||
'window_title_authenticating': '認証中...', // In English: "Authenticating..."
|
||||
'window_title_refer_friend': '友達を紹介しよう!', // In English: "Refer a friend!"
|
||||
'desktop_exit_full_screen': '全画面表示を終了', // In English: "Exit Full Screen"
|
||||
'desktop_enter_full_screen': '全画面表示にする', // In English: "Enter Full Screen"
|
||||
'item_shared_with_you': 'ユーザーがこのアイテムをあなたと共有しました。', // In English: "A user has shared this item with you."
|
||||
'item_shared_by_you': 'このアイテムは少なくとも1人以上のユーザーと共有されています。', // In English: "You have shared this item with at least one other user."
|
||||
'item_shortcut': 'ショートカット', // In English: "Shortcut"
|
||||
'item_associated_websites': '関連ウェブサイト', // In English: "Associated website"
|
||||
@@ -406,9 +358,6 @@ const ja = {
|
||||
'window_click_to_go_back': 'クリックして戻る。', // In English: "Click to go back."
|
||||
'window_click_to_go_forward': 'クリックして進む。', // In English: "Click to go forward."
|
||||
'window_click_to_go_up': 'クリックして一つ上のフォルダーに移動。', // In English: "Click to go one directory up."
|
||||
'window_title_public': 'パブリック', // In English: "Public"
|
||||
'window_title_videos': '動画', // In English: "Videos"
|
||||
'window_title_pictures': '写真', // In English: "Pictures"
|
||||
'window_title_puter': 'Puter', // In English: "Puter"
|
||||
'window_folder_empty': 'このフォルダーは空です', // In English: "This folder is empty"
|
||||
},
|
||||
|
||||
@@ -31,7 +31,6 @@ const ko = {
|
||||
allow: '허용',
|
||||
ascending: '오름차순',
|
||||
associated_websites: '연결된 웹사이트',
|
||||
auto_arrange: '자동 정렬',
|
||||
cancel: '취소',
|
||||
change_email: '이메일 변경',
|
||||
change_language: '언어 변경',
|
||||
@@ -41,19 +40,12 @@ const ko = {
|
||||
close_all_windows_and_log_out: '창을 닫고 로그아웃',
|
||||
change_always_open_with: '이 형식의 파일을 항상 이 앱으로 여시겠습니까?',
|
||||
confirm: '확인',
|
||||
confirm_2fa_setup: '코드를 인증 앱에 추가했습니다',
|
||||
confirm_2fa_recovery: '복구 코드를 안전한 위치에 저장했습니다',
|
||||
confirm_account_for_free_referral_storage_c2a:
|
||||
'계정을 만들고 이메일 주소를 확인하면 1GB의 무료 저장 공간을 드립니다. 친구를 초대하면 친구도 1GB를 받을 수 있습니다.',
|
||||
confirm_code_generic_incorrect: '잘못된 코드입니다.',
|
||||
confirm_code_generic_too_many_requests:
|
||||
'요청이 너무 많습니다. 잠시만 기다려주세요.',
|
||||
confirm_code_generic_submit: '코드 제출',
|
||||
confirm_code_generic_try_again: '재시도',
|
||||
confirm_code_generic_title: '인증 코드 입력',
|
||||
confirm_code_2fa_instruction: '인증 앱의 6자리 코드를 입력해주세요.',
|
||||
confirm_code_2fa_submit_btn: '제출',
|
||||
confirm_code_2fa_title: '2FA 코드 입력',
|
||||
confirm_delete_multiple_items:
|
||||
'선택한 항목들을 영구적으로 삭제하시겠습니까?',
|
||||
confirm_delete_single_item: '이 항목을 영구적으로 삭제하시겠습니까?',
|
||||
@@ -65,9 +57,7 @@ const ko = {
|
||||
confirm_delete_user_title: '계정 삭제 확인',
|
||||
confirm_session_revoke: '정말로 이 세션을 해제하시겠습니까?',
|
||||
confirm_your_email_address: '이메일 주소 확인',
|
||||
choose_publishing_option: '웹사이트 게시 방식을 선택하세요.',
|
||||
contact_us: '문의하기',
|
||||
contact_us_verification_required: '이메일 인증이 필요합니다.',
|
||||
continue: '계속',
|
||||
copy: '복사',
|
||||
copy_link: '링크 복사',
|
||||
@@ -75,8 +65,6 @@ const ko = {
|
||||
copying_file: '%% 파일 복사 중',
|
||||
create_account: '계정 생성',
|
||||
create_free_account: '무료 계정 생성',
|
||||
create_desktop_shortcut: '바탕 화면 바로 가기 만들기',
|
||||
create_desktop_shortcut_s: '바탕 화면 바로 가기 만들기',
|
||||
create_shortcut: '바로 가기 만들기',
|
||||
create_shortcut_s: '바로 가기 만들기',
|
||||
credits: '크레딧',
|
||||
@@ -92,17 +80,13 @@ const ko = {
|
||||
deploy_as_app: '앱으로 배포',
|
||||
descending: '내림차순',
|
||||
desktop: '바탕화면',
|
||||
desktop_background_fit: '맞추기',
|
||||
developers: '개발자',
|
||||
dir_published_as_website: '%strong%에 게시되었습니다.',
|
||||
disable_2fa: '2FA 비활성화',
|
||||
disable_2fa_confirm: '정말 2FA를 비활성화하시겠습니까?',
|
||||
disable_2fa_instructions: '2FA를 비활성화하려면 비밀번호를 입력해주세요.',
|
||||
documents: '문서',
|
||||
dont_allow: '허용하지 않음',
|
||||
download: '다운로드',
|
||||
download_file: '파일 다운로드',
|
||||
downloading: '다운로드 중',
|
||||
email: '이메일',
|
||||
email_change_confirmation_sent:
|
||||
'새 이메일 주소로 확인 메일이 전송되었습니다. 받은 편지함을 확인 후 안내에 따라 절차를 완료해주세요.',
|
||||
@@ -131,13 +115,10 @@ const ko = {
|
||||
forgot_pass_c2a: '비밀번호를 잊으셨나요?',
|
||||
from: '보낸 사람',
|
||||
general: '일반',
|
||||
get_a_copy_of_on_puter: 'Puter.com에서 \'%%\'의 사본을 받으세요!',
|
||||
get_copy_link: '링크 복사',
|
||||
home: '홈',
|
||||
html_document: 'HTML 문서',
|
||||
hue: '색조',
|
||||
incorrect_password: '잘못된 비밀번호',
|
||||
invite_link: '초대 링크',
|
||||
item: '항목', //
|
||||
items_in_trash_cannot_be_renamed: '이 항목은 휴지통에 있어 이름을 변경할 수 없습니다. 이름을 변경하려면 먼저 휴지통에서 꺼내야 합니다.',
|
||||
jpeg_image: 'JPEG 이미지',
|
||||
@@ -148,7 +129,6 @@ const ko = {
|
||||
loading: '로드 중',
|
||||
log_in: '로그인',
|
||||
log_out: '로그아웃',
|
||||
looks_good: '좋아요!',
|
||||
manage_sessions: '세션 관리',
|
||||
modified: '수정일',
|
||||
move: '이동',
|
||||
@@ -175,7 +155,6 @@ const ko = {
|
||||
open_with: '다른 앱으로 열기',
|
||||
original_name: '원본 이름',
|
||||
original_path: '원본 경로',
|
||||
oss_code_and_content: '오픈 소스',
|
||||
password: '비밀번호',
|
||||
password_changed: '비밀번호가 변경되었습니다.',
|
||||
password_recovery_rate_limit:
|
||||
@@ -192,29 +171,22 @@ const ko = {
|
||||
paste: '붙여넣기',
|
||||
paste_into_folder: '폴더에 붙여넣기',
|
||||
path: '경로',
|
||||
personalization: '개인 설정',
|
||||
pick_name_for_website: '웹사이트 이름을 선택하세요.',
|
||||
pictures: '사진',
|
||||
plural_suffix: '',
|
||||
powered_by_puter_js: '{{link=docs}}Puter.js{{/link}} 제공',
|
||||
preparing: '준비 중…',
|
||||
preparing_for_upload: '업로드 준비 중…',
|
||||
print: '인쇄',
|
||||
privacy: '개인정보',
|
||||
proceed_to_login: '로그인 진행',
|
||||
proceed_with_account_deletion: '계정 삭제 진행',
|
||||
properties: '속성',
|
||||
public: '공용',
|
||||
publish: '게시',
|
||||
publish_as_website: '웹사이트로 게시',
|
||||
publish_as_serverless_worker: '서버리스 워커로 게시',
|
||||
puter_description: 'Puter는 모든 파일, 앱, 게임을 하나의 안전한 공간에 보관하고 언제 어디서나 접속할 수 있으며 개인 정보 보호를 우선시하는 개인 클라우드입니다. ',
|
||||
reading: '%strong% 읽는 중',
|
||||
writing: '%strong% 작성 중',
|
||||
recover_password: '비밀번호 찾기',
|
||||
refer_friends_c2a:
|
||||
'Puter에 가입하고 이메일 인증을 완료하는 친구 한 명당 1GB의 저장 공간을 드립니다. 친구도 1GB를 받을 수 있습니다!',
|
||||
refer_friends_social_media_c2a: 'Puter.com에서 1GB의 무료 저장 공간을 받아보세요!',
|
||||
refresh: '새로 고침',
|
||||
rename: '이름 변경',
|
||||
replace: '교체',
|
||||
@@ -224,12 +196,10 @@ const ko = {
|
||||
save: '저장',
|
||||
saturation: '채도',
|
||||
save_account: '계정 저장',
|
||||
save_account_to_get_copy_link: '계속하려면 계정을 만들어주세요.',
|
||||
save_account_to_publish: '계속하려면 계정을 만들어주세요.',
|
||||
save_session: '세션 저장',
|
||||
save_session_c2a:
|
||||
'현재 세션을 저장하고 작업을 잃지 않으려면 계정을 만들어주세요.',
|
||||
scan_qr_2fa: '인증 앱으로 QR 코드를 스캔하세요.',
|
||||
search: '검색',
|
||||
seconds: '초',
|
||||
security: '보안',
|
||||
@@ -247,21 +217,16 @@ const ko = {
|
||||
show_hidden: '숨김 항목 표시',
|
||||
sign_in_with_puter: 'Puter로 로그인',
|
||||
sign_up: '가입',
|
||||
signing_in: '로그인 중…',
|
||||
size: '크기',
|
||||
skip: '건너뛰기',
|
||||
something_went_wrong: '문제가 발생했습니다.',
|
||||
sort_by: '정렬',
|
||||
status: '상태',
|
||||
storage_usage: '저장 공간 사용량',
|
||||
storage_puter_used: 'Puter에서 사용 중',
|
||||
taking_longer_than_usual:
|
||||
'평소보다 조금 더 오래 걸리고 있습니다. 잠시만 기다려주세요…',
|
||||
terms: '약관',
|
||||
text_document: '텍스트 문서',
|
||||
'toolbar.enter_fullscreen': '전체 화면으로 전환',
|
||||
'toolbar.github': 'GitHub',
|
||||
'toolbar.refer': '추천',
|
||||
tos_fineprint: '무료 계정 생성을 클릭하면 Puter의 {{link=terms}}서비스 약관{{/link}}과 {{link=privacy}}개인정보 보호정책{{/link}}에 동의하는 것으로 간주됩니다.',
|
||||
transparency: '투명도',
|
||||
trash: '휴지통',
|
||||
@@ -288,30 +253,24 @@ const ko = {
|
||||
videos: '동영상',
|
||||
visibility: '공개 여부',
|
||||
yes: '예',
|
||||
you_have_been_referred_to_puter_by_a_friend: '친구가 Puter를 추천했습니다!',
|
||||
zip: '압축',
|
||||
sequencing: '%strong% 순서 처리 중',
|
||||
worker: '워커',
|
||||
zipping: '%strong% 압축 중',
|
||||
|
||||
// === 2FA Setup ===
|
||||
setup2fa_1_step_heading: '인증 앱을 열어주세요.',
|
||||
setup2fa_1_instructions: `
|
||||
시간 기반 일회용 비밀번호(TOTP) 프로토콜을 지원하는 모든 인증 앱을 사용할 수 있습니다.
|
||||
선택할 수 있는 앱은 많지만, 잘 모르겠다면 안드로이드 및 iOS용
|
||||
<a target="_blank" href="https://authy.com/download">Authy</a>
|
||||
가 좋은 선택입니다.
|
||||
`,
|
||||
setup2fa_2_step_heading: 'QR 코드 스캔',
|
||||
setup2fa_3_step_heading: '6자리 코드를 입력하세요.',
|
||||
setup2fa_4_step_heading: '복구 코드를 복사하세요.',
|
||||
setup2fa_4_instructions: `
|
||||
복구 코드는 휴대전화를 분실하거나 인증 앱을 사용할 수 없을 때 계정에 접속할 수 있는 유일한 방법입니다. 반드시 안전한 장소에 보관하세요.
|
||||
`,
|
||||
setup2fa_5_step_heading: '2FA 설정 확인',
|
||||
setup2fa_5_confirmation_1: '복구 코드를 안전한 위치에 저장했습니다',
|
||||
setup2fa_5_confirmation_2: '2FA를 활성화할 준비가 되었습니다',
|
||||
setup2fa_5_button: '2FA 활성화',
|
||||
|
||||
// === 2FA Login ===
|
||||
login2fa_otp_title: '2FA 코드 입력',
|
||||
@@ -320,7 +279,6 @@ const ko = {
|
||||
login2fa_recovery_instructions:
|
||||
'계정에 접속하려면 복구 코드 중 하나를 입력해주세요.',
|
||||
login2fa_use_recovery_code: '복구 코드 사용',
|
||||
login2fa_recovery_back: '뒤로',
|
||||
login2fa_recovery_placeholder: 'XXXXXXXX',
|
||||
|
||||
// Sharing
|
||||
@@ -383,7 +341,6 @@ const ko = {
|
||||
'billing.expanded': '확장됨',
|
||||
'billing.accelerated': '가속됨',
|
||||
'billing.enjoy_msg': '클라우드 저장 공간 %%와(과) 다른 혜택을 즐겨보세요.',
|
||||
'too_many_attempts': '시도 횟수가 너무 많습니다. 나중에 다시 시도해주세요.',
|
||||
'server_timeout': '서버 응답 시간이 초과되었습니다. 다시 시도해주세요.',
|
||||
'signup_error': '회원가입 중 오류가 발생했습니다. 다시 시도해주세요.',
|
||||
|
||||
@@ -411,18 +368,13 @@ const ko = {
|
||||
'window_title_open': '열기',
|
||||
'window_title_change_password': '비밀번호 변경',
|
||||
'window_title_select_font': '글꼴 선택…',
|
||||
'window_title_session_list': '세션 목록',
|
||||
'window_title_set_new_password': '새 비밀번호 설정',
|
||||
'window_title_publish_website': '웹사이트 게시',
|
||||
'window_title_publish_worker': '워커 게시',
|
||||
'window_title_authenticating': '인증 중…',
|
||||
'window_title_refer_friend': '친구 추천!',
|
||||
|
||||
// Desktop UI
|
||||
'desktop_exit_full_screen': '전체 화면 종료',
|
||||
'desktop_enter_full_screen': '전체 화면 시작',
|
||||
// Item UI
|
||||
'item_shared_with_you': '다른 사용자가 이 항목을 당신과 공유했습니다.',
|
||||
'item_shared_by_you': '이 항목을 한 명 이상의 다른 사용자와 공유했습니다.',
|
||||
'item_shortcut': '바로 가기',
|
||||
'item_associated_websites': '연결된 웹사이트',
|
||||
@@ -433,9 +385,6 @@ const ko = {
|
||||
'window_click_to_go_back': '뒤로 가려면 클릭하세요.',
|
||||
'window_click_to_go_forward': '앞으로 가려면 클릭하세요.',
|
||||
'window_click_to_go_up': '한 디렉토리 위로 가려면 클릭하세요.',
|
||||
'window_title_public': '공용',
|
||||
'window_title_videos': '동영상',
|
||||
'window_title_pictures': '사진',
|
||||
'window_title_puter': 'Puter',
|
||||
'window_folder_empty': '이 폴더는 비어 있습니다',
|
||||
|
||||
|
||||
@@ -31,7 +31,6 @@ const ku = {
|
||||
allow: 'ڕێگەدان',
|
||||
ascending: 'سەرووەی',
|
||||
associated_websites: 'وێبسایتەکان پەیوەندیدار',
|
||||
auto_arrange: 'ڕیزکردنی ئۆتۆماتیکی',
|
||||
cancel: 'ڕەتکردنەوە',
|
||||
change_email: 'گۆڕینی ئیمەیل',
|
||||
change_language: 'گۆڕینی زمان',
|
||||
@@ -41,20 +40,12 @@ const ku = {
|
||||
close_all_windows_and_log_out: 'داخستن و چوونە دەرەوە',
|
||||
change_always_open_with: 'ئەتەوێت هەمیشە ئەم جۆرە فایلە بکرێتەوە بە',
|
||||
confirm: 'پشتڕاستکردنەوە',
|
||||
confirm_2fa_setup: 'کۆدەکە زیادم کردووە بۆ وەرگرەری پشتڕاستکراوەکان',
|
||||
confirm_2fa_recovery:
|
||||
'کۆدەکانی ڕێکخستنەوە پشتڕاست کردووە بۆ مەبەستێکی تایبەتی',
|
||||
confirm_account_for_free_referral_storage_c2a:
|
||||
'هەژمارێک دروست بکە و پەیوەندیدانی ئیمەیلەکەت پشتڕاست بکە بۆ وەرگرتنی 1 گیگابایت بەرەوپێشەوە. هاوڕێتیش 1 گیگابایت بەرەوپێشەوە دەبێت.',
|
||||
confirm_code_generic_incorrect: 'کۆدی هەڵە.',
|
||||
confirm_code_generic_too_many_requests:
|
||||
'داواکاریی زۆر. تکایە چەند خولەکێک چاوەڕوانبە.',
|
||||
confirm_code_generic_submit: 'ناردنی کۆد',
|
||||
confirm_code_generic_try_again: 'دووبارە هەوڵبەرە',
|
||||
confirm_code_generic_title: 'کۆدی پشتڕاستکردنەوە بنووسە',
|
||||
confirm_code_2fa_instruction: 'کۆدی 6 ژمارەیە بنووسە لە ئەپەکەت.',
|
||||
confirm_code_2fa_submit_btn: 'ناردن',
|
||||
confirm_code_2fa_title: 'کۆدی 2FA بنووسە',
|
||||
confirm_delete_multiple_items:
|
||||
'دڵنیایت کە ئەتەوێت ئەم بابەتانە هەمی نابود بکەیتەوە؟',
|
||||
confirm_delete_single_item: 'ئەتەوێت ئەم بابەتە نابود بکەیتەوە؟',
|
||||
@@ -67,8 +58,6 @@ const ku = {
|
||||
confirm_session_revoke: 'دڵنیایت کە ئەتەوێت ئەم دانیشتنە ڕەت بکەیتەوە؟',
|
||||
confirm_your_email_address: 'پشتڕاستکردنەوەی ناونیشانی ئیمەیلەکەت',
|
||||
contact_us: 'پەیوەندی پێوە بکە',
|
||||
contact_us_verification_required:
|
||||
'پێویستە ناونیشانی ئیمەیلەکەت پشتڕاست بکرێت بۆ بەکارهێنان.',
|
||||
continue: 'بەردەوامبوون',
|
||||
copy: 'کۆپی',
|
||||
copy_link: 'کۆپی کردنەوەی بەستەر',
|
||||
@@ -90,17 +79,13 @@ const ku = {
|
||||
deploy_as_app: 'دابەشکردن وەک ئەپ',
|
||||
descending: 'نزەندەی',
|
||||
desktop: 'سەروروومیزی',
|
||||
desktop_background_fit: 'ڕێکخستن',
|
||||
developers: 'پەرەپێدانەران',
|
||||
dir_published_as_website: '%strong% بەشکراوە بۆ:',
|
||||
disable_2fa: 'ناچالاککردنی 2FA',
|
||||
disable_2fa_confirm: 'دڵنیایت کە ئەتەوێت 2FA ناچالاک بکەیت؟',
|
||||
disable_2fa_instructions: 'وشەی تێپەڕی نووسە بۆ ناچالاککردنی 2FA.',
|
||||
documents: 'بەڵگەکان',
|
||||
dont_allow: 'ڕێگەندان',
|
||||
download: 'داگرتن',
|
||||
download_file: 'داگرتنی فایل',
|
||||
downloading: 'داگرتن',
|
||||
email: 'ئیمەیل',
|
||||
email_change_confirmation_sent:
|
||||
'پەیامی پشتڕاستکردنی ئیمەیل بۆ ناونیشانی ئیمەیلە نوێتەوە نێردرا. تکایە پەیامەکانت بپشکنە و ڕێنیشانەکان پەیڕەو بکە بۆ تەواوبوونەوەی ئەم کارە.',
|
||||
@@ -129,13 +114,10 @@ const ku = {
|
||||
forgot_pass_c2a: 'وشەی تێپەڕت لەبیرچووە؟',
|
||||
from: 'لە',
|
||||
general: 'گشتی',
|
||||
get_a_copy_of_on_puter: 'کۆپیێک وەرگرتنەوەی \'%%\' لە پوتەر.com!',
|
||||
get_copy_link: 'کۆپی بەستەر وەرگرتن',
|
||||
home: 'ماڵەوە',
|
||||
html_document: 'بەڵگەی HTML',
|
||||
hue: 'هیو',
|
||||
incorrect_password: 'وشەی تێپەڕ هەڵەیە',
|
||||
invite_link: 'بەستەری بانگکردن',
|
||||
item: 'بابەت',
|
||||
items_in_trash_cannot_be_renamed: 'ئەم بابەتە ناتوانرێت ناونوسێت چونکە لە کوڵەدا هەیە. بۆ ناونوسین، سەبارەکەی لە کوڵەکە دەر بکە.',
|
||||
jpeg_image: 'وێنەی JPEG',
|
||||
@@ -146,7 +128,6 @@ const ku = {
|
||||
loading: 'بارکردنەوە',
|
||||
log_in: 'چوونەژوورەوە',
|
||||
log_out: 'چوونە دەرەوە',
|
||||
looks_good: 'پەیوەندیدارە!',
|
||||
manage_sessions: 'بەڕێوەبردنی دانیشتنەکان',
|
||||
modified: 'گۆڕاو',
|
||||
move: 'جوڵاندن',
|
||||
@@ -171,7 +152,6 @@ const ku = {
|
||||
open_with: 'کردنەوە بە',
|
||||
original_name: 'ناوی ڕەسەن',
|
||||
original_path: 'ڕێکەوتی ڕەسەن',
|
||||
oss_code_and_content: 'کۆدی سەرچاوەیەکی کراو و ناوەڕۆک',
|
||||
password: 'وشەی تێپەڕ',
|
||||
password_changed: 'وشەی تێپەڕ گۆڕدرا.',
|
||||
password_recovery_rate_limit:
|
||||
@@ -188,27 +168,20 @@ const ku = {
|
||||
paste: 'دانان',
|
||||
paste_into_folder: 'دانان لە فۆڵدەرەکە',
|
||||
path: 'ڕێکەوت',
|
||||
personalization: 'بەشداربوون',
|
||||
pick_name_for_website: 'ناوێک دیاربکە بۆ وێبسایتەکەت:',
|
||||
pictures: 'وێنەکان',
|
||||
plural_suffix: 'کان',
|
||||
powered_by_puter_js: 'پێشکەشکراوە لە {{link=docs}}پوتەر.js{{/link}}',
|
||||
preparing: 'ئامادەکردن...',
|
||||
preparing_for_upload: 'ئامادەکردن بۆ بارکردن...',
|
||||
print: 'چاپکردن',
|
||||
privacy: 'تایبەتمەندی',
|
||||
proceed_to_login: 'بەردەوام بوون بۆ چوونەژوورەوە',
|
||||
proceed_with_account_deletion: 'بەردەوام بوون بە سڕینەوەی هەژمار',
|
||||
properties: 'تایبەتمەندیەکان',
|
||||
public: 'گشتی',
|
||||
publish: 'بڵاوکردنەوە',
|
||||
publish_as_website: 'بڵاوکردنەوە وەک وێبسایت',
|
||||
puter_description: 'پوتەر پێشکەشکراوە بۆ پاراستنی تایبەتیە کەسایەتی، جێگایەکی ئازاد بۆ گەیاندنی هەموو فایلەکان، ئەپەکان، و یارییەکان لە هەر شوێنێک بێ هەموو کاتێک.',
|
||||
reading_file: 'خوێندنی %strong%',
|
||||
recover_password: 'ڕێکخستنەوەی وشەی تێپەڕ',
|
||||
refer_friends_c2a:
|
||||
'1 گیگابایت بۆ هەر هاوڕێک دەست بەرکە، پەیوەندیدانی هەژمارێک بۆ پوتەر دروست بکە و پشتڕاست بکە. هاوڕێتیش 1 گیگابایت وەرگرتن دەبێت!',
|
||||
refer_friends_social_media_c2a: '1 گیگابایت پارێزگاکانی پوتەر.com بۆ هەر هاوڕێک بکە!',
|
||||
refresh: 'بوژانەوە',
|
||||
rename: 'ناونانەوە',
|
||||
replace: 'لە نوێکردنەوە',
|
||||
@@ -218,12 +191,10 @@ const ku = {
|
||||
save: 'پاشەکەوت',
|
||||
saturation: 'سەرەخۆشی',
|
||||
save_account: 'پاشەکەوتکردنی هەژمار',
|
||||
save_account_to_get_copy_link: 'تکایە هەژمارێک دروست بکە بۆ بەردەوامبوون.',
|
||||
save_account_to_publish: 'تکایە هەژمارێک دروست بکە بۆ بەردەوامبوون.',
|
||||
save_session: 'پاشەکەوتکردنی دانیشتن',
|
||||
save_session_c2a:
|
||||
'هەژمارێک دروست بکە بۆ پاشەکەوتکردنی دانیشتنەکەت و جلە نبەرینەوەی کاریەکانت.',
|
||||
scan_qr_2fa: 'کۆدی QR پشکنین بە ئەپەکەت',
|
||||
search: 'گەڕان',
|
||||
seconds: 'چرکە',
|
||||
security: 'پاراستن',
|
||||
@@ -241,13 +212,11 @@ const ku = {
|
||||
show_hidden: 'پیشاندانی شاردراوەکان',
|
||||
sign_in_with_puter: 'چوونەژوورەوە بە پوتەر',
|
||||
sign_up: 'خۆتۆمارکردن',
|
||||
signing_in: 'چوونەژوورەوە...',
|
||||
size: 'قەبارە',
|
||||
skip: 'هەڵگرتن',
|
||||
something_went_wrong: 'هەڵەیەکی رووی دا.',
|
||||
sort_by: 'ڕیزکردن بە',
|
||||
status: 'دۆخ',
|
||||
storage_usage: 'بەکاربردنی پارێزگا',
|
||||
storage_puter_used: 'بەکاربردنی لەلایەن پوتەر',
|
||||
taking_longer_than_usual: 'کەمێک زیاتر کەوتە، تکایە چاوەڕوانبە...',
|
||||
terms: 'مەرجەکان',
|
||||
@@ -276,13 +245,10 @@ const ku = {
|
||||
videos: 'ڤیدیۆکان',
|
||||
visibility: 'پیشاندانی',
|
||||
yes: 'بەڵێ',
|
||||
you_have_been_referred_to_puter_by_a_friend:
|
||||
'هاوڕێکت پەیوەندیداری پوتەر کردووە!',
|
||||
zip: 'زیپ',
|
||||
zipping_file: 'زیپ کردنەوەی %strong%',
|
||||
|
||||
// === 2FA Setup ===
|
||||
setup2fa_1_step_heading: 'کردنەوەی ئەپەکەت',
|
||||
setup2fa_1_instructions: `
|
||||
دەتوانیت هەر ئەپێکی پشتڕاستکردنی دووجۆرا بەکاربهێنیت کە پشتگیری
|
||||
Time-based One-Time Password (TOTP) protocol بیکات. هەندێکە زۆرن بۆ
|
||||
@@ -290,18 +256,14 @@ const ku = {
|
||||
<a target="_blank" href="https://authy.com/download">Authy</a>
|
||||
هەڵبژاردنێکی باشە بۆ ئەندرۆید و iOS.
|
||||
`,
|
||||
setup2fa_2_step_heading: 'پشکنینی کۆدی QR',
|
||||
setup2fa_3_step_heading: 'ناردنی کۆدی 6 ژمارە',
|
||||
setup2fa_4_step_heading: 'کۆدی پشتڕاستکردنی نوێ پشکنین',
|
||||
setup2fa_4_instructions: `
|
||||
ئەم کۆدانە تەنها ڕێگا بۆ گەیشتنەوە بە هەژمارەکەت گەر تۆ موبایلەکەت
|
||||
لەبیرچووی یاخود ناتوانی ئەپەکەت بەکاربەریت.
|
||||
دڵنیابە کەیان لە شوێنێکی پاراستنەوەیەکان بنووسیت.
|
||||
`,
|
||||
setup2fa_5_step_heading: 'پشتڕاستکردنی ڕێکخستنەوەی 2FA',
|
||||
setup2fa_5_confirmation_1: 'کۆدای پشتڕاستکردنەوەی مەبەستەکانم بنووسنەوە',
|
||||
setup2fa_5_confirmation_2: 'ئامادەم بۆ چالاککردنی 2FA',
|
||||
setup2fa_5_button: 'چالاککردنی 2FA',
|
||||
|
||||
// === 2FA Login ===
|
||||
login2fa_otp_title: 'ناردنی کۆدی 2FA',
|
||||
@@ -310,7 +272,6 @@ const ku = {
|
||||
login2fa_recovery_instructions:
|
||||
'یەکێک لە کۆدانە پشتڕاستکردنەوە بنووسە بۆ گەیشتنەوە بە هەژمارەکەت.',
|
||||
login2fa_use_recovery_code: 'بەکارهێنانی کۆدی پشتڕاستکردنەوە',
|
||||
login2fa_recovery_back: 'گەڕانەوە',
|
||||
login2fa_recovery_placeholder: 'XXXXXXXX',
|
||||
|
||||
'change': 'بیگۆڕە', // In English: "Change"
|
||||
@@ -374,20 +335,13 @@ const ku = {
|
||||
'billing.expanded': 'بڵاوکراوەتەوە',
|
||||
'billing.accelerated': 'بە خێرایی',
|
||||
'billing.enjoy_msg': '%% لە هەڵگرتنی هەور و سوودی تر وەربگرە',
|
||||
'choose_publishing_option': 'هەڵبژێرە چۆن دەتەوێت وێبسایتەکەت بڵاوبکەیتەوە:', // In English: "Choose how you want to publish your website:"
|
||||
'create_desktop_shortcut': 'دروستکردنی کورتەڕەو (سەڕەکی دێسکتۆپ)', // In English: "Create Shortcut (Desktop)"
|
||||
'create_desktop_shortcut_s': 'دروستکردنی کورتەڕەوەکان (سەڕەکی دێسکتۆپ)', // In English: "Create Shortcuts (Desktop)"
|
||||
'create_shortcut_s': 'دروستکردنی کورتەڕەوەکان', // In English: "Create Shortcuts"
|
||||
'minimize': 'بچووککردنەوە', // In English: "Minimize"
|
||||
'reload_app': 'ئەپلیکەیشن دووبارە بار بکە', // In English: "Reload App"
|
||||
'publish_as_serverless_worker': 'بڵاوکردنەوە وەک کارمەند', // In English: "Publish as Worker"
|
||||
'toolbar.enter_fullscreen': 'بە تەواوی شاشە بچۆرە', // In English: "Enter Full Screen"
|
||||
'toolbar.github': 'GitHub', // In English: "GitHub"
|
||||
'toolbar.refer': 'بانگهێشت بکە', // In English: "Refer"
|
||||
'used_of': '{{used}} بەکارهاتوو لە {{available}}', // In English: "{{used}} used of {{available}}"
|
||||
'worker': 'کارمەند', // In English: "Worker"
|
||||
'billing.offering.basic': 'بنەڕەتی', // In English: "Basic"
|
||||
'too_many_attempts': 'هەوڵی زۆر دراوە. تکایە دواتر دووبارە هەوڵ بدە.', // In English: "Too many attempts. Please try again later."
|
||||
'server_timeout': 'سێرڤەرەکە زۆر ماوەیەکی درێژ وەڵامی نەدا. تکایە دووبارە هەوڵ بدە.', // In English: "The server took too long to respond. Please try again."
|
||||
'signup_error': 'هەڵەیەک ڕووی دا لە کاتی تۆماربووندا. تکایە دووبارە هەوڵبدە.', // In English: "An error occurred during signup. Please try again."
|
||||
'alert_error_title': 'هەڵە', // In English: "Error!"
|
||||
@@ -405,15 +359,10 @@ const ku = {
|
||||
'window_title_open': 'کردنەوە', // In English: "Open"
|
||||
'window_title_change_password': 'گۆڕینی وشەی نهێنی', // In English: "Change Password"
|
||||
'window_title_select_font': 'فۆنت هەڵبژێرە', // In English: "Select font…"
|
||||
'window_title_session_list': 'لیستی دانیشتنەکان!', // In English: "Session List!"
|
||||
'window_title_set_new_password': 'وشەی نهێنی نوێ دابنێ', // In English: "Set New Password"
|
||||
'window_title_publish_website': 'بڵاوکردنەوەی وێبسایت', // In English: "Publish Website"
|
||||
'window_title_publish_worker': 'بڵاوکردنەوەی کارمەند', // In English: "Publish Worker"
|
||||
'window_title_authenticating': 'پەسندکردنەوە', // In English: "Authenticating..."
|
||||
'window_title_refer_friend': 'هاوڕێک بانگهێشت بکە!', // In English: "Refer a friend!"
|
||||
'desktop_exit_full_screen': 'دەرچوون لە شاشەی پڕە', // In English: "Exit Full Screen"
|
||||
'desktop_enter_full_screen': 'چوونە شاشەی پڕە', // In English: "Enter Full Screen"
|
||||
'item_shared_with_you': 'بەکارهێنەرێک ئەم شتەیە لەگەڵ تۆ هاوبەش کردووە.', // In English: "A user has shared this item with you."
|
||||
'item_shared_by_you': 'تۆ ئەم شتە بە هەندێک بەکارهێنەرێکی تر هاوبەش کردووە.', // In English: "You have shared this item with at least one other user."
|
||||
'item_shortcut': 'کورتەڕەو', // In English: "Shortcut"
|
||||
'item_associated_websites': 'وێبسایتێکی پەیوەست', // In English: "Associated website"
|
||||
@@ -422,9 +371,6 @@ const ku = {
|
||||
'window_click_to_go_back': 'کرتە بکە بۆ چوونە دواوە', // In English: "Click to go back."
|
||||
'window_click_to_go_forward': 'کرتە بکە بۆ چوونە پێشەوە', // In English: "Click to go forward."
|
||||
'window_click_to_go_up': 'کرتە بکە بۆ چوونە بوخچەیەکی سەرەوە', // In English: "Click to go one directory up."
|
||||
'window_title_public': 'گشتی', // In English: "Public"
|
||||
'window_title_videos': 'ڤیدیۆ', // In English: "Videos"
|
||||
'window_title_pictures': 'وێنە', // In English: "Pictures"
|
||||
'window_title_puter': 'پوتێر', // In English: "Puter"
|
||||
'window_folder_empty': 'ئەم بوخچەیە بەتاڵە', // In English: "This folder is empty"
|
||||
},
|
||||
|
||||
@@ -31,7 +31,6 @@ const ml = {
|
||||
allow: 'അനുവദിക്കുക',
|
||||
ascending: 'ആരോഹണം',
|
||||
associated_websites: 'ബന്ധപ്പെട്ട വെബ്സൈറ്റുകൾ',
|
||||
auto_arrange: 'സ്വയം ക്രമീകരിക്കുക',
|
||||
cancel: 'റദ്ദാക്കുക',
|
||||
change: 'മാറ്റുക',
|
||||
change_always_open_with: 'ഈ തരത്തിലുള്ള ഫയൽ എപ്പോഴും ഇതുപയോഗിച്ച് തുറക്കണോ',
|
||||
@@ -42,17 +41,10 @@ const ml = {
|
||||
close: 'അടയ്ക്കുക',
|
||||
close_all_windows_and_log_out: 'വിൻഡോകൾ അടച്ച് ലോഗ്ഔട്ട് ചെയ്യുക',
|
||||
confirm: 'സ്ഥിരീകരിക്കുക',
|
||||
confirm_2fa_setup: 'ഞാൻ കോഡ് എന്റെ ഓതന്റിക്കേറ്റർ ആപ്പിലേക്ക് ചേർത്തു',
|
||||
confirm_2fa_recovery: 'ഞാൻ എന്റെ റിക്കവറി കോഡുകൾ സുരക്ഷിതമായി സംരക്ഷിച്ചു',
|
||||
confirm_account_for_free_referral_storage_c2a: '1 GB സൗജന്യ സ്റ്റോറേജ് ലഭിക്കാൻ ഒരു അക്കൗണ്ട് സൃഷ്ടിച്ച് നിങ്ങളുടെ ഇമെയിൽ സ്ഥിരീകരിക്കുക. നിങ്ങളുടെ സുഹൃത്തിനും 1 GB സൗജന്യ സ്റ്റോറേജ് ലഭിക്കും.',
|
||||
confirm_code_generic_incorrect: 'തെറ്റായ കോഡ്.',
|
||||
confirm_code_generic_too_many_requests: 'വളരെയധികം അഭ്യർത്ഥനകൾ. കുറച്ച് മിനിറ്റുകൾ കാത്തിരിക്കുക.',
|
||||
confirm_code_generic_submit: 'കോഡ് സമർപ്പിക്കുക',
|
||||
confirm_code_generic_try_again: 'വീണ്ടും ശ്രമിക്കുക',
|
||||
confirm_code_generic_title: 'സ്ഥിരീകരണ കോഡ് നൽകുക',
|
||||
confirm_code_2fa_instruction: 'നിങ്ങളുടെ ഓതന്റിക്കേറ്റർ ആപ്പിൽ നിന്നുള്ള 6-അക്ക കോഡ് നൽകുക.',
|
||||
confirm_code_2fa_submit_btn: 'സമർപ്പിക്കുക',
|
||||
confirm_code_2fa_title: '2FA കോഡ് നൽകുക',
|
||||
confirm_delete_multiple_items: 'ഈ ഇനങ്ങൾ സ്ഥിരമായി ഇല്ലാതാക്കണമെന്ന് തീർച്ചയാണോ?',
|
||||
confirm_delete_single_item: 'ഈ ഇനം സ്ഥിരമായി ഇല്ലാതാക്കണമെന്ന് ആഗ്രഹിക്കുന്നുവോ?',
|
||||
confirm_open_apps_log_out: 'നിങ്ങൾക്ക് തുറന്ന ആപ്പുകളുണ്ട്. ലോഗ്ഔട്ട് ചെയ്യണമെന്ന് തീർച്ചയാണോ?',
|
||||
@@ -62,7 +54,6 @@ const ml = {
|
||||
confirm_session_revoke: 'ഈ സെഷൻ റദ്ദാക്കണമെന്ന് തീർച്ചയാണോ?',
|
||||
confirm_your_email_address: 'നിങ്ങളുടെ ഇമെയിൽ വിലാസം സ്ഥിരീകരിക്കുക',
|
||||
contact_us: 'ഞങ്ങളെ ബന്ധപ്പെടുക',
|
||||
contact_us_verification_required: 'ഇത് ഉപയോഗിക്കാൻ നിങ്ങൾക്ക് സ്ഥിരീകരിച്ച ഇമെയിൽ വിലാസം ഉണ്ടായിരിക്കണം.',
|
||||
continue: 'തുടരുക',
|
||||
copy: 'പകർത്തുക',
|
||||
copy_link: 'ലിങ്ക് പകർത്തുക',
|
||||
@@ -84,17 +75,13 @@ const ml = {
|
||||
deploy_as_app: 'ആപ്പായി വിന്യസിക്കുക',
|
||||
descending: 'അവരോഹണം',
|
||||
desktop: 'ഡെസ്ക്ടോപ്പ്',
|
||||
desktop_background_fit: 'ഫിറ്റ്',
|
||||
developers: 'ഡെവലപ്പർമാർ',
|
||||
dir_published_as_website: '%strong% എന്നതിലേക്ക് പ്രസിദ്ധീകരിച്ചിരിക്കുന്നു:',
|
||||
disable_2fa: '2FA പ്രവർത്തനരഹിതമാക്കുക',
|
||||
disable_2fa_confirm: '2FA പ്രവർത്തനരഹിതമാക്കണമെന്ന് തീർച്ചയാണോ?',
|
||||
disable_2fa_instructions: '2FA പ്രവർത്തനരഹിതമാക്കാൻ നിങ്ങളുടെ പാസ്വേഡ് നൽകുക.',
|
||||
documents: 'രേഖകൾ',
|
||||
dont_allow: 'അനുവദിക്കരുത്',
|
||||
download: 'ഡൗൺലോഡ്',
|
||||
download_file: 'ഫയൽ ഡൗൺലോഡ് ചെയ്യുക',
|
||||
downloading: 'ഡൗൺലോഡ് ചെയ്യുന്നു',
|
||||
email: 'ഇമെയിൽ',
|
||||
email_change_confirmation_sent: 'നിങ്ങളുടെ പുതിയ ഇമെയിൽ വിലാസത്തിലേക്ക് ഒരു സ്ഥിരീകരണ ഇമെയിൽ അയച്ചിട്ടുണ്ട്. ദയവായി നിങ്ങളുടെ ഇൻബോ',
|
||||
email_invalid: 'ഇമെയിൽ അസാധുവാണ്.',
|
||||
@@ -119,13 +106,10 @@ const ml = {
|
||||
forgot_pass_c2a: 'പാസ്വേഡ് മറന്നുപോയോ?',
|
||||
from: 'എവിടെ നിന്ന്',
|
||||
general: 'പൊതുവായത്',
|
||||
get_a_copy_of_on_puter: 'Puter.com-ൽ \'%%\' എന്നതിന്റെ ഒരു പകർപ്പ് നേടുക!',
|
||||
get_copy_link: 'പകർപ്പ് ലിങ്ക് നേടുക',
|
||||
home: 'ഹോം',
|
||||
html_document: 'HTML ഡോക്യുമെന്റ്',
|
||||
hue: 'ഹ്യൂ',
|
||||
incorrect_password: 'തെറ്റായ പാസ്വേഡ്',
|
||||
invite_link: 'ക്ഷണിക്കൽ ലിങ്ക്',
|
||||
item: 'ഇനം',
|
||||
items_in_trash_cannot_be_renamed: 'ഈ ഇനം ട്രാഷിലായതിനാൽ പേരുമാറ്റാൻ കഴിയില്ല. ഈ ഇനത്തിന്റെ പേരുമാറ്റാൻ, ആദ്യം ഇത് ട്രാഷിൽ നിന്ന് പുറത്തെടുക്കുക.',
|
||||
jpeg_image: 'JPEG ചിത്രം',
|
||||
@@ -136,7 +120,6 @@ const ml = {
|
||||
loading: 'ലോഡ് ചെയ്യുന്നു',
|
||||
log_in: 'ലോഗിൻ',
|
||||
log_out: 'ലോഗ്ഔട്ട്',
|
||||
looks_good: 'നന്നായിരിക്കുന്നു!',
|
||||
manage_sessions: 'സെഷനുകൾ കൈകാര്യം ചെയ്യുക',
|
||||
modified: 'പരിഷ്കരിച്ചത്',
|
||||
move: 'നീക്കുക',
|
||||
@@ -161,7 +144,6 @@ const ml = {
|
||||
open_with: 'ഇതുപയോഗിച്ച് തുറക്കുക',
|
||||
original_name: 'യഥാർത്ഥ പേര്',
|
||||
original_path: 'യഥാർത്ഥ പാത',
|
||||
oss_code_and_content: 'ഓപ്പൺ സോഴ്സ് സോഫ്റ്റ്വെയറും ഉള്ളടക്കവും',
|
||||
password: 'പാസ്വേഡ്',
|
||||
password_changed: 'പാസ്വേഡ് മാറ്റി.',
|
||||
password_recovery_rate_limit: 'നിങ്ങൾ പരിധി കവിഞ്ഞു; ദയവായി കുറച്ച് മിനിറ്റുകൾ കാത്തിരിക്കുക. ഭാവിയിൽ ഇത് ഒഴിവാക്കാൻ, പേജ് വളരെയധികം തവണ റീലോഡ് ചെയ്യുന്നത് ഒഴിവാക്കുക.',
|
||||
@@ -173,27 +155,20 @@ const ml = {
|
||||
paste: 'പേസ്റ്റ്',
|
||||
paste_into_folder: 'ഫോൾഡറിലേക്ക് പേസ്റ്റ് ചെയ്യുക',
|
||||
path: 'പാത',
|
||||
personalization: 'വ്യക്തിഗതമാക്കൽ',
|
||||
pick_name_for_website: 'നിങ്ങളുടെ വെബ്സൈറ്റിന് ഒരു പേര് തിരഞ്ഞെടുക്കുക:',
|
||||
pictures: 'ചിത്രങ്ങൾ',
|
||||
plural_suffix: 'കൾ',
|
||||
powered_by_puter_js: '{{link=docs}}Puter.js{{/link}} ഉപയോഗിച്ച് നിർമ്മിച്ചത്',
|
||||
preparing: 'തയ്യാറാക്കുന്നു...',
|
||||
preparing_for_upload: 'അപ്ലോഡിനായി തയ്യാറാക്കുന്നു...',
|
||||
print: 'പ്രിന്റ്',
|
||||
privacy: 'സ്വകാര്യത',
|
||||
proceed_to_login: 'ലോഗിനിലേക്ക് പോകുക',
|
||||
proceed_with_account_deletion: 'അക്കൗണ്ട് ഇല്ലാതാക്കൽ തുടരുക',
|
||||
properties: 'സവിശേഷതകൾ',
|
||||
public: 'പൊതു',
|
||||
publish: 'പ്രസിദ്ധീകരിക്കുക',
|
||||
publish_as_website: 'വെബ്സൈറ്റായി പ്രസിദ്ധീകരിക്കുക',
|
||||
puter_description: 'പ്യൂട്ടർ എന്നത് നിങ്ങളുടെ എല്ലാ ഫയലുകളും, ആപ്പുകളും, ഗെയിമുകളും ഒരു സുരക്ഷിത സ്ഥലത്ത് സൂക്ഷിക്കാനുള്ള സ്വകാര്യത കേന്ദ്രീകരിച്ച വ്യക്തിഗത ക്ലൗഡ് ആണ്, ഏത് സമയത്തും എവിടെ നിന്നും ആക്സസ് ചെയ്യാൻ കഴിയും.',
|
||||
reading: '%strong% വായിക്കുന്നു',
|
||||
writing: '%strong% എഴുതുന്നു',
|
||||
recover_password: 'പാസ്വേഡ് വീണ്ടെടുക്കുക',
|
||||
refer_friends_c2a: 'അക്കൗണ്ട് സൃഷ്ടിച്ച് സ്ഥിരീകരിക്കുന്ന ഓരോ സുഹൃത്തിനും 1 GB നേടുക. നിങ്ങളുടെ സുഹൃത്തിനും 1 GB ലഭിക്കും!',
|
||||
refer_friends_social_media_c2a: 'Puter.com-ൽ 1 GB സൗജന്യ സ്റ്റോറേജ് നേടുക!',
|
||||
refresh: 'പുതുക്കുക',
|
||||
rename: 'പേരുമാറ്റുക',
|
||||
replace: 'മാറ്റിസ്ഥാപിക്കുക',
|
||||
@@ -203,11 +178,9 @@ const ml = {
|
||||
save: 'സംരക്ഷിക്കുക',
|
||||
saturation: 'സാച്ചുറേഷൻ',
|
||||
save_account: 'അക്കൗണ്ട് സംരക്ഷിക്കുക',
|
||||
save_account_to_get_copy_link: 'തുടരുന്നതിന് ദയവായി ഒരു അക്കൗണ്ട് സൃഷ്ടിക്കുക.',
|
||||
save_account_to_publish: 'തുടരുന്നതിന് ദയവായി ഒരു അക്കൗണ്ട് സൃഷ്ടിക്കുക.',
|
||||
save_session: 'സെഷൻ സംരക്ഷിക്കുക',
|
||||
save_session_c2a: 'നിങ്ങളുടെ നിലവിലെ സെഷൻ സംരക്ഷിക്കാനും ജോലി നഷ്ടപ്പെടുന്നത് ഒഴിവാക്കാനും ഒരു അക്കൗണ്ട് സൃഷ്ടിക്കുക.',
|
||||
scan_qr_2fa: 'നിങ്ങളുടെ ഓതന്റിക്കേറ്റർ ആപ്പ് ഉപയോഗിച്ച് QR കോഡ് സ്കാൻ ചെയ്യുക',
|
||||
search: 'തിരയുക',
|
||||
seconds: 'സെക്കൻഡുകൾ',
|
||||
security: 'സുരക്ഷ',
|
||||
@@ -225,13 +198,11 @@ const ml = {
|
||||
show_hidden: 'മറഞ്ഞിരിക്കുന്നവ കാണിക്കുക',
|
||||
sign_in_with_puter: 'പ്യൂട്ടർ ഉപയോഗിച്ച് സൈൻ ഇൻ ചെയ്യുക',
|
||||
sign_up: 'സൈൻ അപ്പ്',
|
||||
signing_in: 'സൈൻ ഇൻ ചെയ്യുന്നു…',
|
||||
size: 'വലുപ്പം',
|
||||
skip: 'ഒഴിവാക്കുക',
|
||||
something_went_wrong: 'എന്തോ തെറ്റ് സംഭവിച്ചു.',
|
||||
sort_by: 'ഇതനുസരിച്ച് അടുക്കുക',
|
||||
status: 'നില',
|
||||
storage_usage: 'സ്റ്റോറേജ് ഉപയോഗം',
|
||||
storage_puter_used: 'പ്യൂട്ടർ ഉപയോഗിച്ചത്',
|
||||
taking_longer_than_usual: 'സാധാരണയേക്കാൾ കൂടുതൽ സമയമെടുക്കുന്നു. ദയവായി കാത്തിരിക്കുക...',
|
||||
terms: 'നിബന്ധനകൾ',
|
||||
@@ -260,30 +231,24 @@ const ml = {
|
||||
videos: 'വീഡിയോകൾ',
|
||||
visibility: 'ദൃശ്യത',
|
||||
yes: 'അതെ',
|
||||
you_have_been_referred_to_puter_by_a_friend: 'ഒരു സുഹൃത്ത് നിങ്ങളെ പ്യൂട്ടറിലേക്ക് റഫർ ചെയ്തിരിക്കുന്നു!',
|
||||
zip: 'സിപ്പ്',
|
||||
sequencing: '%strong% ക്രമപ്പെടുത്തുന്നു',
|
||||
zipping: '%strong% സിപ്പ് ചെയ്യുന്നു',
|
||||
|
||||
// === 2FA Setup ===
|
||||
setup2fa_1_step_heading: 'നിങ്ങളുടെ ഓതന്റിക്കേറ്റർ ആപ്പ് തുറക്കുക',
|
||||
setup2fa_1_instructions: `
|
||||
നിങ്ങളുടെ അക്കൗണ്ടിൽ ടൈം-ബേസ്ഡ് വൺ-ടൈം പാസ്വേർഡ് (TOTP) പ്രോട്ടോക്കോൾ പിന്തുണക്കുന്ന ഏതെങ്കിലും ഓതന്റിക്കേറ്റർ ആപ്പ് ഉപയോഗിക്കാം.
|
||||
ഉപയോഗിക്കാൻ പറ്റിയവയിൽ നിങ്ങൾക്കു സംശയമുണ്ടെങ്കിൽ,
|
||||
<a target="_blank" href="https://authy.com/download">Authy</a>
|
||||
ആൻഡ്രോയിഡ്, ഐഒഎസ് ഉപയോക്താക്കൾക്ക് നല്ലൊരു തിരഞ്ഞെടുപ്പാണ്.
|
||||
`,
|
||||
setup2fa_2_step_heading: 'QR കോഡ് സ്കാൻ ചെയ്യുക',
|
||||
setup2fa_3_step_heading: '6-അക്കം ഉള്ള കോഡ് നൽകുക',
|
||||
setup2fa_4_step_heading: 'റിക്കവറി കോഡുകൾ പകർത്തുക',
|
||||
setup2fa_4_instructions: `
|
||||
നിങ്ങളുടെ ഫോൺ നഷ്ടപ്പെടുകയോ ഓതന്റിക്കേറ്റർ ആപ്പ് ഉപയോഗിക്കാൻ കഴിയാതാവുകയോ ചെയ്താൽ നിങ്ങളുടെ അക്കൗണ്ടിൽ ആക്സസ് നേടാനുള്ള ഏക മാർഗമാണ് ഈ റിക്കവറി കോഡുകൾ.
|
||||
അവ ഒരു സുരക്ഷിതമായ സ്ഥലത്ത് സൂക്ഷിക്കുക.
|
||||
`,
|
||||
setup2fa_5_step_heading: '2FA സെറ്റപ്പ് സ്ഥിരീകരിക്കുക',
|
||||
setup2fa_5_confirmation_1: 'ഞാൻ എന്റെ റിക്കവറി കോഡുകൾ ഒരു സുരക്ഷിതമായ സ്ഥലത്ത് സൂക്ഷിച്ചു',
|
||||
setup2fa_5_confirmation_2: 'ഞാൻ 2FA പ്രവർത്തനക്ഷമമാക്കാൻ തയ്യാറാണ്',
|
||||
setup2fa_5_button: '2FA പ്രവർത്തനക്ഷമമാക്കുക',
|
||||
|
||||
// === 2FA Login ===
|
||||
login2fa_otp_title: '2FA കോഡ് നൽകുക',
|
||||
@@ -291,7 +256,6 @@ const ml = {
|
||||
login2fa_recovery_title: 'ഒരു റിക്കവറി കോഡ് നൽകുക',
|
||||
login2fa_recovery_instructions: 'നിങ്ങളുടെ അക്കൗണ്ടിൽ ആക്സസ് നേടാൻ നിങ്ങളുടെ ഒരു റിക്കവറി കോഡ് നൽകുക.',
|
||||
login2fa_use_recovery_code: 'റിക്കവറി കോഡ് ഉപയോഗിക്കുക',
|
||||
login2fa_recovery_back: 'തിരികെ',
|
||||
login2fa_recovery_placeholder: 'XXXXXXXX',
|
||||
|
||||
// Sharing
|
||||
|
||||
@@ -38,7 +38,6 @@ const my = {
|
||||
allow: 'Benarkan',
|
||||
ascending: 'Menaik',
|
||||
associated_websites: 'Laman Web Berkaitan',
|
||||
auto_arrange: 'Susunan Automatik',
|
||||
cancel: 'Batal',
|
||||
change: 'Ubah',
|
||||
change_email: 'Tukar Emel',
|
||||
@@ -50,20 +49,13 @@ const my = {
|
||||
change_always_open_with: 'Adakah anda mahu sentiasa membuka jenis fail ini dengan',
|
||||
confirm: 'Sahkan',
|
||||
// Note: `authenticator` is taken directly from the English language as it is more commonly used than its direct Malay translation `pengesahan`
|
||||
confirm_2fa_setup: 'Saya telah menambah kod ke aplikasi authenticator saya',
|
||||
confirm_2fa_recovery: 'Saya telah menyimpan kod pemulihan saya di lokasi yang selamat',
|
||||
confirm_account_for_free_referral_storage_c2a:
|
||||
'Cipta akaun dan sahkan alamat emel anda untuk menerima 1 GB storan percuma. Rakan anda juga akan menerima 1 GB storan percuma.',
|
||||
confirm_code_generic_incorrect: 'Kod Salah.',
|
||||
confirm_code_generic_too_many_requests:
|
||||
'Terlalu banyak permintaan. Sila tunggu beberapa minit.',
|
||||
confirm_code_generic_submit: 'Hantar Kod',
|
||||
confirm_code_generic_try_again: 'Cuba Lagi',
|
||||
confirm_code_generic_title: 'Masukkan Kod Pengesahan',
|
||||
confirm_code_2fa_instruction:
|
||||
'Masukkan kod 6 digit daripada aplikasi authenticator anda.',
|
||||
confirm_code_2fa_submit_btn: 'Hantar',
|
||||
confirm_code_2fa_title: 'Masukkan Kod 2FA',
|
||||
confirm_delete_multiple_items:
|
||||
'Adakah anda yakin mahu menghapuskan item-item ini buat selamanya?',
|
||||
confirm_delete_single_item: 'Adakah anda mahu menghapuskan item ini buat selamanya?',
|
||||
@@ -75,10 +67,7 @@ const my = {
|
||||
confirm_delete_user_title: 'Hapus Akaun?',
|
||||
confirm_session_revoke: 'Adakah anda yakin mahu menamatkan sesi ini?',
|
||||
confirm_your_email_address: 'Sahkan Alamat Emel Anda',
|
||||
choose_publishing_option: 'Pilih cara untuk menerbitkan laman web anda:',
|
||||
contact_us: 'Hubungi Kami',
|
||||
contact_us_verification_required:
|
||||
'Anda perlu memiliki alamat emel yang sah untuk menggunakan ini.',
|
||||
continue: 'Teruskan',
|
||||
copy: 'Salin',
|
||||
copy_link: 'Salin Pautan',
|
||||
@@ -86,8 +75,6 @@ const my = {
|
||||
copying_file: 'Menyalin %%',
|
||||
create_account: 'Cipta Akaun',
|
||||
create_free_account: 'Cipta Akaun Percuma',
|
||||
create_desktop_shortcut: 'Buat Pintasan (Desktop)',
|
||||
create_desktop_shortcut_s: 'Buat Pintasan (Desktop)',
|
||||
create_shortcut: 'Buat Pintasan',
|
||||
create_shortcut_s: 'Buat Pintasan',
|
||||
credits: 'Kredit',
|
||||
@@ -103,17 +90,13 @@ const my = {
|
||||
deploy_as_app: 'Jalankan sebagai aplikasi',
|
||||
descending: 'Menurun',
|
||||
desktop: 'Desktop',
|
||||
desktop_background_fit: 'Suaikan',
|
||||
developers: 'Pembangun',
|
||||
dir_published_as_website: '%strong% telah diterbitkan di:',
|
||||
disable_2fa: 'Menyahaktifkan 2FA',
|
||||
disable_2fa_confirm: 'Adakah anda yakin mahu menyahaktifkan 2FA?',
|
||||
disable_2fa_instructions: 'Masukkan kata laluan anda untuk menyahaktifkan 2FA.',
|
||||
documents: 'Dokumen',
|
||||
dont_allow: 'Tidak Izinkan',
|
||||
download: 'Muat Naik',
|
||||
download_file: 'Muat Naik Fail',
|
||||
downloading: 'Memuat Naik',
|
||||
email: 'Emel',
|
||||
email_change_confirmation_sent:
|
||||
'Emel pengesahan telah dihantar ke alamat emel baharu anda. Sila semak peti emel anda dan ikut arahan terbabit bagi menyelesaikan proses ini.',
|
||||
@@ -139,13 +122,10 @@ const my = {
|
||||
forgot_pass_c2a: 'Lupa kata laluan?',
|
||||
from: 'Dari',
|
||||
general: 'Umum',
|
||||
get_a_copy_of_on_puter: 'Dapatkan salinan \'%%\' di Puter.com!',
|
||||
get_copy_link: 'Dapatkan Salinan Pautan',
|
||||
home: 'Laman Utama',
|
||||
html_document: 'Dokumen HTML',
|
||||
hue: 'Hue',
|
||||
incorrect_password: 'Kata laluan salah',
|
||||
invite_link: 'Pautan Jemputan',
|
||||
item: 'item',
|
||||
items_in_trash_cannot_be_renamed: 'Item ini tidak boleh dinamakan semula kerana berada dalam tong sampah. Untuk menamakan semula item ini, tariknya keluar dari Tong Sampah terlebih dahulu.',
|
||||
jpeg_image: 'Imej JPEG',
|
||||
@@ -156,7 +136,6 @@ const my = {
|
||||
loading: 'Memuatkan',
|
||||
log_in: 'Log Masuk',
|
||||
log_out: 'Log Keluar',
|
||||
looks_good: 'Nampak baik!',
|
||||
manage_sessions: 'Urus Sesi',
|
||||
modified: 'Diubah suai',
|
||||
move: 'Pindah',
|
||||
@@ -183,7 +162,6 @@ const my = {
|
||||
open_with: 'Buka Dengan',
|
||||
original_name: 'Nama Asal',
|
||||
original_path: 'Laluan Asal',
|
||||
oss_code_and_content: 'Perisian dan Kandungan Sumber Terbuka',
|
||||
password: 'Kata Laluan',
|
||||
password_changed: 'Kata laluan ditukar.',
|
||||
password_recovery_rate_limit: 'Anda telah mencapai had kadar kami; sila tunggu beberapa minit. Untuk mengelakkan hal ini pada masa hadapan, elakkan memuat semula halaman terlalu banyak kali.',
|
||||
@@ -195,28 +173,21 @@ const my = {
|
||||
paste: 'Tampal',
|
||||
paste_into_folder: 'Tampal Ke Dalam Folder',
|
||||
path: 'Laluan',
|
||||
personalization: 'Pemperibadian',
|
||||
pick_name_for_website: 'Pilih nama laman web anda:',
|
||||
pictures: 'Gambar',
|
||||
plural_suffix: 's',
|
||||
powered_by_puter_js: 'Dikuasakan oleh {{link=docs}}Puter.js{{/link}}',
|
||||
preparing: 'Menyediakan...',
|
||||
preparing_for_upload: 'Menyediakan untuk muat naik...',
|
||||
print: 'Cetak',
|
||||
privacy: 'Privasi',
|
||||
proceed_to_login: 'Teruskan untuk log masuk',
|
||||
proceed_with_account_deletion: 'Teruskan dengan Penghapusan Akaun',
|
||||
properties: 'Ciri-ciri',
|
||||
public: 'Publik',
|
||||
publish: 'Terbitkan',
|
||||
publish_as_website: 'Terbitkan sebagai laman web',
|
||||
publish_as_serverless_worker: 'Terbitkan sebagai Worker',
|
||||
puter_description: 'Puter ialah storan awan peribadi yang mendahulukan privasi untuk menyimpan semua fail, aplikasi dan permainan anda di satu tempat yang selamat, boleh diakses dari mana sahaja dan pada bila-bila masa.',
|
||||
reading: 'Membaca %strong%',
|
||||
writing: 'Menulis %strong%',
|
||||
recover_password: 'Pulihkan Kata Laluan',
|
||||
refer_friends_c2a: 'Dapatkan 1 GB untuk setiap rakan yang membuat dan mengesahkan akaun di Puter. Rakan anda juga akan mendapat 1 GB!',
|
||||
refer_friends_social_media_c2a: 'Dapatkan 1 GB storan percuma di Puter.com!',
|
||||
refresh: 'Muat Semula',
|
||||
rename: 'Namakan Semula',
|
||||
replace: 'Ganti',
|
||||
@@ -226,11 +197,9 @@ const my = {
|
||||
save: 'Simpan',
|
||||
saturation: 'Ketepuan',
|
||||
save_account: 'Simpan akaun',
|
||||
save_account_to_get_copy_link: 'Sila buat akaun untuk meneruskan.',
|
||||
save_account_to_publish: 'Sila buat akaun untuk meneruskan.',
|
||||
save_session: 'Simpan sesi',
|
||||
save_session_c2a: 'Buat akaun untuk menyimpan sesi ini dan mengelakkan kehilangan kerja anda.',
|
||||
scan_qr_2fa: 'Imbas kod QR dengan aplikasi authenticator anda',
|
||||
search: 'Cari',
|
||||
seconds: 'saat',
|
||||
security: 'Keselamatan',
|
||||
@@ -248,20 +217,15 @@ const my = {
|
||||
show_hidden: 'Tunjukkan yang tersembunyi',
|
||||
sign_in_with_puter: 'Daftar masuk dengan Puter',
|
||||
sign_up: 'Daftar',
|
||||
signing_in: 'Mendaftar masuk…',
|
||||
size: 'Saiz',
|
||||
skip: 'Langkau',
|
||||
something_went_wrong: 'Sesuatu telah berlaku.',
|
||||
sort_by: 'Susun mengikut',
|
||||
status: 'Status',
|
||||
storage_usage: 'Penggunaan Storan',
|
||||
storage_puter_used: 'digunakan oleh Puter',
|
||||
taking_longer_than_usual: 'Mengambil masa lebih lama daripada biasa. Sila tunggu...',
|
||||
terms: 'Terma',
|
||||
text_document: 'Dokumen teks',
|
||||
'toolbar.enter_fullscreen': 'Masuk Skrin Penuh',
|
||||
'toolbar.github': 'GitHub',
|
||||
'toolbar.refer': 'Rujuk',
|
||||
tos_fineprint: 'Dengan mengklik \'Buat Akaun Percuma\' anda bersetuju dengan {{link=terms}}Terma Perkhidmatan{{/link}} dan {{link=privacy}}Dasar Privasi{{/link}} Puter.',
|
||||
transparency: 'Ketelusan',
|
||||
trash: 'Tong Sampah',
|
||||
@@ -287,31 +251,25 @@ const my = {
|
||||
videos: 'Video',
|
||||
visibility: 'Keterlihatan',
|
||||
yes: 'Ya',
|
||||
you_have_been_referred_to_puter_by_a_friend: 'Anda telah dirujuk ke Puter oleh rakan!',
|
||||
zip: 'Zip',
|
||||
sequencing: 'Penyusunan %strong%',
|
||||
worker: 'Worker',
|
||||
zipping: 'Menzip %strong%',
|
||||
|
||||
// === 2FA Setup ===
|
||||
setup2fa_1_step_heading: 'Buka aplikasi authenticator anda',
|
||||
setup2fa_1_instructions: `
|
||||
Anda boleh menggunakan sebarang aplikasi authenticator yang menyokong protokol Kata Laluan Sekali Guna Berasaskan Masa (TOTP).
|
||||
Terdapat banyak untuk dipilih, tetapi jika anda tidak pasti
|
||||
<a target="_blank" href="https://authy.com/download">Authy</a>
|
||||
adalah pilihan yang kukuh untuk Android dan iOS.
|
||||
`,
|
||||
setup2fa_2_step_heading: 'Imbas kod QR',
|
||||
setup2fa_3_step_heading: 'Masukkan kod 6 digit',
|
||||
setup2fa_4_step_heading: 'Salin kod pemulihan anda',
|
||||
setup2fa_4_instructions: `
|
||||
Kod pemulihan ini adalah satu-satunya cara untuk mengakses akaun anda jika anda kehilangan telefon atau tidak boleh menggunakan aplikasi authenticator anda.
|
||||
Pastikan anda menyimpannya di tempat yang selamat.
|
||||
`,
|
||||
setup2fa_5_step_heading: 'Sahkan persediaan 2FA',
|
||||
setup2fa_5_confirmation_1: 'Saya telah menyimpan kod pemulihan saya di lokasi yang selamat',
|
||||
setup2fa_5_confirmation_2: 'Saya bersedia untuk mengaktifkan 2FA',
|
||||
setup2fa_5_button: 'Aktifkan 2FA',
|
||||
|
||||
// === 2FA Login ===
|
||||
login2fa_otp_title: 'Masukkan Kod 2FA',
|
||||
@@ -319,7 +277,6 @@ const my = {
|
||||
login2fa_recovery_title: 'Masukkan kod pemulihan',
|
||||
login2fa_recovery_instructions: 'Masukkan salah satu kod pemulihan anda untuk mengakses akaun anda.',
|
||||
login2fa_use_recovery_code: 'Gunakan kod pemulihan',
|
||||
login2fa_recovery_back: 'Kembali',
|
||||
login2fa_recovery_placeholder: 'XXXXXXXX',
|
||||
|
||||
// Sharing
|
||||
@@ -380,7 +337,6 @@ const my = {
|
||||
'billing.expanded': 'Diperluas',
|
||||
'billing.accelerated': 'Dipercepatkan',
|
||||
'billing.enjoy_msg': 'Nikmati %% Storan Awan ditambah faedah lain.',
|
||||
'too_many_attempts': 'Terlalu banyak percubaan. Sila cuba lagi kemudian.',
|
||||
'server_timeout': 'Server mengambil masa terlalu lama untuk bertindak balas. Sila cuba lagi.',
|
||||
'signup_error': 'Ralat berlaku semasa pendaftaran. Sila cuba lagi.',
|
||||
|
||||
@@ -408,19 +364,14 @@ const my = {
|
||||
'window_title_open': 'Buka',
|
||||
'window_title_change_password': 'Tukar Kata Laluan',
|
||||
'window_title_select_font': 'Pilih fon huruf…',
|
||||
'window_title_session_list': 'Senarai Sesi!',
|
||||
'window_title_set_new_password': 'Tetapkan Kata Laluan Baru',
|
||||
'window_title_publish_website': 'Terbitkan Laman Web',
|
||||
'window_title_publish_worker': 'Terbitkan Worker',
|
||||
'window_title_authenticating': 'Mengesahkan...',
|
||||
'window_title_refer_friend': 'Rujuk rakan!',
|
||||
|
||||
// Desktop UI
|
||||
'desktop_exit_full_screen': 'Keluar Skrin Penuh',
|
||||
'desktop_enter_full_screen': 'Masuk Skrin Penuh',
|
||||
|
||||
// Item UI
|
||||
'item_shared_with_you': 'Pengguna telah berkongsi item ini dengan anda.',
|
||||
'item_shared_by_you': 'Anda telah berkongsi item ini dengan sekurang-kurangnya satu pengguna lain.',
|
||||
'item_shortcut': 'Pintasan',
|
||||
'item_associated_websites': 'Laman web berkaitan',
|
||||
@@ -431,9 +382,6 @@ const my = {
|
||||
'window_click_to_go_back': 'Klik untuk kembali.',
|
||||
'window_click_to_go_forward': 'Klik untuk maju.',
|
||||
'window_click_to_go_up': 'Klik untuk naik satu direktori.',
|
||||
'window_title_public': 'Publik',
|
||||
'window_title_videos': 'Video',
|
||||
'window_title_pictures': 'Gambar',
|
||||
'window_title_puter': 'Puter',
|
||||
'window_folder_empty': 'Folder ini kosong',
|
||||
|
||||
|
||||
@@ -36,7 +36,6 @@ const nb = {
|
||||
allow: 'Tillate',
|
||||
ascending: 'Stigende',
|
||||
associated_websites: 'Tilknyttede nettsider',
|
||||
auto_arrange: 'Automatisk sortering',
|
||||
cancel: 'Avbryt',
|
||||
change: 'Endre',
|
||||
change_always_open_with: 'Vil du alltid åpne denne filtypen med',
|
||||
@@ -47,17 +46,10 @@ const nb = {
|
||||
close: 'Lukk',
|
||||
close_all_windows_and_log_out: 'Lukk alle vinduer og logg ut',
|
||||
confirm: 'Bekrefte',
|
||||
confirm_2fa_setup: 'Jeg har lagt til koden i autentiseringsappen min',
|
||||
confirm_2fa_recovery: 'Jeg har lagret gjenopprettingskodene mine på et sikkert sted',
|
||||
confirm_account_for_free_referral_storage_c2a: 'Opprett en konto og bekreft e-postadressen din for å motta 1 GB gratis lagringsplass. Din venn vil også få 1 GB gratis lagringsplass.',
|
||||
confirm_code_generic_incorrect: 'Feil kode.',
|
||||
confirm_code_generic_too_many_requests: 'For mange forespørsler. Vennligst vent noen minutter.',
|
||||
confirm_code_generic_submit: 'Send inn kode',
|
||||
confirm_code_generic_try_again: 'Prøv igjen',
|
||||
confirm_code_generic_title: 'Skriv inn bekreftelseskode',
|
||||
confirm_code_2fa_instruction: 'Skriv inn den 6-sifrede koden fra autentiseringsappen din.',
|
||||
confirm_code_2fa_submit_btn: 'Send inn',
|
||||
confirm_code_2fa_title: 'Skriv inn 2FA-kode',
|
||||
confirm_delete_multiple_items: 'Er du sikker på at du vil slette disse elementene permanent?',
|
||||
confirm_delete_single_item: 'Er du sikker på at du vil slette dette elemente permanent?',
|
||||
confirm_open_apps_log_out: 'Du har åpene apper, er du sikker på at du vil logge ut?',
|
||||
@@ -67,7 +59,6 @@ const nb = {
|
||||
confirm_session_revoke: 'Er du sikker på at du vil oppheve denne økten?',
|
||||
confirm_your_email_address: 'Bekreft e-postadressen din',
|
||||
contact_us: 'Kontakt oss',
|
||||
contact_us_verification_required: 'Du må ha en bekreftet e-postadresse for å bruke dette.',
|
||||
continue: 'Fortsett',
|
||||
copy: 'Kopier',
|
||||
copy_link: 'Kopier lenke',
|
||||
@@ -75,8 +66,6 @@ const nb = {
|
||||
copying_file: 'Kopierer %%',
|
||||
create_account: 'Opprett konto',
|
||||
create_free_account: 'Opprett gratis konto',
|
||||
create_desktop_shortcut: 'Opprett snarvei (skrivebord)',
|
||||
create_desktop_shortcut_s: 'Opprett snarveier (skrivebord)',
|
||||
create_shortcut: 'Opprett snarvei',
|
||||
create_shortcut_s: 'Opprett snarveier',
|
||||
credits: 'Kreditering',
|
||||
@@ -92,17 +81,13 @@ const nb = {
|
||||
deploy_as_app: 'Distribuer som app',
|
||||
descending: 'Synkende',
|
||||
desktop: 'Skrivebord',
|
||||
desktop_background_fit: 'Tilpass',
|
||||
developers: 'Utviklere',
|
||||
dir_published_as_website: '%strong% er publisert på:',
|
||||
disable_2fa: 'Deaktiver 2FA',
|
||||
disable_2fa_confirm: 'Er du sikker på at du vil deaktivere 2FA?',
|
||||
disable_2fa_instructions: 'Skriv inn passordet ditt for å deaktivere 2FA.',
|
||||
documents: 'Dokumenter',
|
||||
dont_allow: 'Ikke tillat',
|
||||
download: 'Last ned',
|
||||
download_file: 'Last ned fil',
|
||||
downloading: 'Laster ned',
|
||||
email: 'E-post',
|
||||
email_change_confirmation_sent: 'En bekreftelses-e-post har blitt sendt til din nye e-postadresse. Sjekk innboksen din og følg instruksjonene for å fullføre prosessen.',
|
||||
email_invalid: 'Ugyldig e-postadresse.',
|
||||
@@ -127,13 +112,10 @@ const nb = {
|
||||
forgot_pass_c2a: 'Glemt passord?',
|
||||
from: 'Fra',
|
||||
general: 'Generelt',
|
||||
get_a_copy_of_on_puter: "Få en kopi av '%%' på Puter.com!",
|
||||
get_copy_link: 'Få kopilenke',
|
||||
home: 'Hjem',
|
||||
html_document: 'HTML-dokument',
|
||||
hue: 'Fargetone',
|
||||
incorrect_password: 'Feil passord',
|
||||
invite_link: 'Invitasjonslenke',
|
||||
item: 'element',
|
||||
items_in_trash_cannot_be_renamed: 'Dette elementet kan ikke omdøpes fordi det er i papirkurven. For å omdøpe dette elementet, dra det først ut av papirkurven.',
|
||||
jpeg_image: 'JPEG-bilde',
|
||||
@@ -144,7 +126,6 @@ const nb = {
|
||||
loading: 'Laster',
|
||||
log_in: 'Logg inn',
|
||||
log_out: 'Logg ut',
|
||||
looks_good: 'Ser bra ut!',
|
||||
manage_sessions: 'Administrer økter',
|
||||
modified: 'Endret',
|
||||
move: 'Flytt',
|
||||
@@ -169,7 +150,6 @@ const nb = {
|
||||
open_with: 'Åpne med',
|
||||
original_name: 'Opprinnelig navn',
|
||||
original_path: 'Opprinnelig sti',
|
||||
oss_code_and_content: 'Åpen kildekodeprogramvare og innhold',
|
||||
password: 'Passord',
|
||||
password_changed: 'Passord endret.',
|
||||
password_recovery_rate_limit: 'Du har nådd grensen for antall forespørsler; vennligst vent noen minutter. For å unngå dette i fremtiden, unngå å laste inn siden for mange ganger.',
|
||||
@@ -181,27 +161,20 @@ const nb = {
|
||||
paste: 'Lim inn',
|
||||
paste_into_folder: 'Lim inn i mappe',
|
||||
path: 'Sti',
|
||||
personalization: 'Tilpasning',
|
||||
pick_name_for_website: 'Velg et navn for nettstedet ditt:',
|
||||
pictures: 'Bilder',
|
||||
plural_suffix: '',
|
||||
powered_by_puter_js: 'Drevet av {{link=docs}}Puter.js{{/link}}',
|
||||
preparing: 'Forbereder...',
|
||||
preparing_for_upload: 'Forbereder opplasting...',
|
||||
print: 'Skriv ut',
|
||||
privacy: 'Personvern',
|
||||
proceed_to_login: 'Fortsett til innlogging',
|
||||
proceed_with_account_deletion: 'Fortsett med sletting av konto',
|
||||
properties: 'Egenskaper',
|
||||
public: 'Offentlig',
|
||||
publish: 'Publiser',
|
||||
publish_as_website: 'Publiser som nettsted',
|
||||
puter_description: 'Puter er en personvernfokusert personlig sky der du kan samle alle filene, appene og spillene dine på ett sikkert sted, tilgjengelig fra hvor som helst, når som helst.',
|
||||
reading: 'Leser %strong%',
|
||||
writing: 'Skriver %strong%',
|
||||
recover_password: 'Gjenopprett passord',
|
||||
refer_friends_c2a: 'Få 1 GB for hver venn som oppretter og bekrefter en konto på Puter. Vennen din får også 1 GB.',
|
||||
refer_friends_social_media_c2a: 'Få 1 GB gratis lagringsplass på Puter.com!',
|
||||
refresh: 'Oppdater',
|
||||
rename: 'Gi nytt navn',
|
||||
replace: 'Erstatt',
|
||||
@@ -211,11 +184,9 @@ const nb = {
|
||||
save: 'Lagre',
|
||||
saturation: 'Metning',
|
||||
save_account: 'Lagre konto',
|
||||
save_account_to_get_copy_link: 'Vennligst opprett en konto for å fortsette.',
|
||||
save_account_to_publish: 'Vennligst opprett en konto for å fortsette.',
|
||||
save_session: 'Lagre økt',
|
||||
save_session_c2a: 'Opprett en konto for å lagre gjeldende økt og unngå å miste arbeidet ditt.',
|
||||
scan_qr_2fa: 'Skann QR-koden med autentiseringsappen din',
|
||||
search: 'Søk',
|
||||
seconds: 'sekunder',
|
||||
security: 'Sikkerhet',
|
||||
@@ -233,18 +204,13 @@ const nb = {
|
||||
show_hidden: 'Vis skjulte',
|
||||
sign_in_with_puter: 'Logg inn med Puter',
|
||||
sign_up: 'Registrer deg',
|
||||
signing_in: 'Logger inn…',
|
||||
size: 'Størrelse',
|
||||
skip: 'Hopp over',
|
||||
something_went_wrong: 'Noe gikk galt.',
|
||||
sort_by: 'Sorter etter',
|
||||
status: 'Status',
|
||||
storage_usage: 'Lagringsbruk',
|
||||
storage_puter_used: 'brukt av Puter',
|
||||
taking_longer_than_usual: 'Dette tar litt lenger tid enn vanlig. Vennligst vent...',
|
||||
'toolbar.enter_fullscreen': 'Gå til fullskjerm',
|
||||
'toolbar.github': 'GitHub',
|
||||
'toolbar.refer': 'Henvis',
|
||||
terms: 'Vilkår',
|
||||
text_document: 'Tekstdokument',
|
||||
tos_fineprint: "Ved å klikke på 'Opprett gratis konto' godtar du Puters {{link=terms}}tjenestevilkår{{/link}} og {{link=privacy}}personvernpolicy{{/link}}.",
|
||||
@@ -272,29 +238,23 @@ const nb = {
|
||||
videos: 'Videoer',
|
||||
visibility: 'Synlighet',
|
||||
yes: 'Ja',
|
||||
you_have_been_referred_to_puter_by_a_friend: 'Du har blitt invitert til Puter av en venn!',
|
||||
zip: 'Zip',
|
||||
sequencing: 'Sekvenserer %strong%',
|
||||
zipping: 'Zipper %strong%',
|
||||
|
||||
// === 2FA Setup ===
|
||||
setup2fa_1_step_heading: 'Åpne autentiseringsappen din',
|
||||
setup2fa_1_instructions: `
|
||||
Du kan bruke hvilken som helst autentiseringsapp som støtter TOTP (Time-based One-Time Password)-protokollen.
|
||||
Det finnes mange alternativer, men hvis du er usikker, er
|
||||
<a target="_blank" href="https://authy.com/download">Authy</a>
|
||||
et godt valg for Android og iOS.`,
|
||||
setup2fa_2_step_heading: 'Skann QR-koden',
|
||||
setup2fa_3_step_heading: 'Skriv inn den 6-sifrede koden',
|
||||
setup2fa_4_step_heading: 'Kopier gjenopprettingskodene dine',
|
||||
setup2fa_4_instructions: `
|
||||
Disse gjenopprettingskodene er den eneste måten å få tilgang til kontoen din på hvis du mister telefonen eller ikke kan bruke autentiseringsappen din.
|
||||
Sørg for å lagre dem på et trygt sted.
|
||||
`,
|
||||
setup2fa_5_step_heading: 'Bekreft 2FA-oppsett',
|
||||
setup2fa_5_confirmation_1: 'Jeg har lagret gjenopprettingskodene mine på et sikkert sted',
|
||||
setup2fa_5_confirmation_2: 'Jeg er klar til å aktivere 2FA',
|
||||
setup2fa_5_button: 'Aktiver 2FA',
|
||||
|
||||
// === 2FA Login ===
|
||||
login2fa_otp_title: 'Skriv inn 2FA-kode',
|
||||
@@ -302,7 +262,6 @@ const nb = {
|
||||
login2fa_recovery_title: 'Skriv inn en gjenopprettingskode',
|
||||
login2fa_recovery_instructions: 'Skriv inn en av gjenopprettingskodene dine for å få tilgang til kontoen.',
|
||||
login2fa_use_recovery_code: 'Bruk en gjenopprettingskode',
|
||||
login2fa_recovery_back: 'Tilbake',
|
||||
login2fa_recovery_placeholder: 'XXXXXXXX',
|
||||
|
||||
// Sharing
|
||||
@@ -374,13 +333,11 @@ const nb = {
|
||||
'source_code': 'Kildekode',
|
||||
'not_found': 'Fant ikke siden',
|
||||
'not_found_description': 'Beklager, vi finner ikke siden du leter etter.',
|
||||
'choose_publishing_option': 'Velg hvordan du vil publisere nettstedet ditt:',
|
||||
'minimize': 'Minimer',
|
||||
'reload_app': 'Last appen på nytt',
|
||||
'plural_suffix': 'er',
|
||||
'publish_as_serverless_worker': 'Publiser som Worker',
|
||||
'worker': 'Worker',
|
||||
'too_many_attempts': 'For mange forsøk. Prøv igjen senere.',
|
||||
'server_timeout': 'Tjeneren brukte for lang tid på å svare. Prøv igjen.',
|
||||
'signup_error': 'En feil oppstod under registreringen. Prøv igjen.',
|
||||
'alert_error_title': 'Feil!',
|
||||
@@ -398,15 +355,10 @@ const nb = {
|
||||
'window_title_open': 'Åpne',
|
||||
'window_title_change_password': 'Endre passord',
|
||||
'window_title_select_font': 'Velg skrift…',
|
||||
'window_title_session_list': 'Øktliste!',
|
||||
'window_title_set_new_password': 'Angi nytt passord',
|
||||
'window_title_publish_website': 'Publiser nettsted',
|
||||
'window_title_publish_worker': 'Publiser Worker',
|
||||
'window_title_authenticating': 'Autentiserer...',
|
||||
'window_title_refer_friend': 'Henvis en venn!',
|
||||
'desktop_exit_full_screen': 'Avslutt fullskjerm',
|
||||
'desktop_enter_full_screen': 'Gå til fullskjerm',
|
||||
'item_shared_with_you': 'En bruker har delt dette elementet med deg.',
|
||||
'item_shared_by_you': 'Du har delt dette elementet med minst én annen bruker.',
|
||||
'item_shortcut': 'Snarvei',
|
||||
'item_associated_websites': 'Tilknyttet nettsted',
|
||||
@@ -415,9 +367,6 @@ const nb = {
|
||||
'window_click_to_go_back': 'Klikk for å gå tilbake.',
|
||||
'window_click_to_go_forward': 'Klikk for å gå fremover.',
|
||||
'window_click_to_go_up': 'Klikk for å gå ett katalognivå opp.',
|
||||
'window_title_public': 'Offentlig',
|
||||
'window_title_videos': 'Videoer',
|
||||
'window_title_pictures': 'Bilder',
|
||||
'window_title_puter': 'Puter',
|
||||
'window_folder_empty': 'Denne mappen er tom',
|
||||
},
|
||||
|
||||
@@ -31,7 +31,6 @@ const nl = {
|
||||
allow: 'Toestaan',
|
||||
ascending: 'Oplopend',
|
||||
associated_websites: 'Geassocieerde Websites',
|
||||
auto_arrange: 'Automatisch sorteren',
|
||||
cancel: 'Annuleren',
|
||||
change_email: 'E-mail Wijzigen',
|
||||
change_language: 'Taal veranderen',
|
||||
@@ -41,17 +40,10 @@ const nl = {
|
||||
close_all_windows_and_log_out: 'Vensters sluiten en afmelden',
|
||||
change_always_open_with: 'Wilt u dit bestandstype altijd openen met',
|
||||
confirm: 'Bevestig',
|
||||
confirm_2fa_setup: 'Ik heb de code toegevoegd aan mijn authenticatie-app',
|
||||
confirm_2fa_recovery: 'Ik heb mijn herstelcodes op een veilige plaats opgeslagen',
|
||||
confirm_account_for_free_referral_storage_c2a: 'Maak een account aan en bevestig uw e-mailadres om 1 GB gratis opslag te ontvangen. Uw vriend krijgt ook 1 GB gratis opslag.',
|
||||
confirm_code_generic_incorrect: 'Onjuiste code.',
|
||||
confirm_code_generic_too_many_requests: 'Te veel aanvragen. Wacht een paar minuten.',
|
||||
confirm_code_generic_submit: 'Code invoeren',
|
||||
confirm_code_generic_try_again: 'Probeer opnieuw',
|
||||
confirm_code_generic_title: 'Bevestigingscode Invoeren',
|
||||
confirm_code_2fa_instruction: 'Voer de 6-cijferige code in van uw authenticatie-app.',
|
||||
confirm_code_2fa_submit_btn: 'Verzenden',
|
||||
confirm_code_2fa_title: 'Voer 2FA Code In',
|
||||
confirm_delete_multiple_items: 'Weet u zeker dat u deze items permanent wilt verwijderen?',
|
||||
confirm_delete_single_item: 'Wilt u dit item permanent verwijderen?',
|
||||
confirm_open_apps_log_out: 'U heeft geopende apps. Weet u zeker dat u wilt uitloggen?',
|
||||
@@ -61,7 +53,6 @@ const nl = {
|
||||
confirm_session_revoke: 'Weet u zeker dat u deze sessie wilt intrekken?',
|
||||
confirm_your_email_address: 'Bevestig Uw E-mailadres',
|
||||
contact_us: 'Neem Contact Op',
|
||||
contact_us_verification_required: 'U moet een geverifieerd e-mailadres hebben om dit te gebruiken.',
|
||||
continue: 'Doorgaan',
|
||||
copy: 'Kopiëren',
|
||||
copy_link: 'Link Kopiëren',
|
||||
@@ -83,17 +74,13 @@ const nl = {
|
||||
deploy_as_app: 'Uitrollen als app',
|
||||
descending: 'Aflopend',
|
||||
desktop: 'Bureaublad',
|
||||
desktop_background_fit: 'Aanpassen',
|
||||
developers: 'Ontwikkelaars',
|
||||
dir_published_as_website: '%strong% is gepubliceerd op:',
|
||||
disable_2fa: '2FA Uitschakelen',
|
||||
disable_2fa_confirm: 'Weet u zeker dat u 2FA wilt uitschakelen?',
|
||||
disable_2fa_instructions: 'Voer uw wachtwoord in om 2FA uit te schakelen.',
|
||||
documents: 'Documenten',
|
||||
dont_allow: 'Niet Toestaan',
|
||||
download: 'Downloaden',
|
||||
download_file: 'Bestand Downloaden',
|
||||
downloading: 'Downloaden',
|
||||
email: 'E-mail',
|
||||
email_change_confirmation_sent: 'Er is een bevestigingsmail gestuurd naar uw nieuwe e-mailadres. Controleer uw inbox en volg de instructies om het proces te voltooien.',
|
||||
email_invalid: 'E-mail is ongeldig.',
|
||||
@@ -118,13 +105,10 @@ const nl = {
|
||||
forgot_pass_c2a: 'Wachtwoord vergeten?',
|
||||
from: 'Van',
|
||||
general: 'Algemeen',
|
||||
get_a_copy_of_on_puter: 'Krijg een kopie van \'%%\' op Puter.com!',
|
||||
get_copy_link: 'Krijg Kopieerlink',
|
||||
home: 'Home',
|
||||
html_document: 'HTML-document',
|
||||
hue: 'Tint',
|
||||
incorrect_password: 'Onjuist wachtwoord',
|
||||
invite_link: 'Uitnodigingslink',
|
||||
item: 'item',
|
||||
items_in_trash_cannot_be_renamed: 'Dit item kan niet worden hernoemd omdat het in de prullenbak zit. Om dit item te hernoemen, sleept u het eerst uit de prullenbak.',
|
||||
jpeg_image: 'JPEG-afbeelding',
|
||||
@@ -135,7 +119,6 @@ const nl = {
|
||||
loading: 'Laden',
|
||||
log_in: 'Inloggen',
|
||||
log_out: 'Uitloggen',
|
||||
looks_good: 'Ziet er goed uit!',
|
||||
manage_sessions: 'Sessies Beheren',
|
||||
mobile_device: 'Mobiel apparaat',
|
||||
modified: 'Gewijzigd',
|
||||
@@ -161,7 +144,6 @@ const nl = {
|
||||
open_with: 'Openen met',
|
||||
original_name: 'Originele Naam',
|
||||
original_path: 'Origineel Pad',
|
||||
oss_code_and_content: 'Open Source Software Code en Inhoud',
|
||||
password: 'Wachtwoord',
|
||||
password_changed: 'Wachtwoord gewijzigd',
|
||||
password_recovery_rate_limit: 'U heeft te veel verzoeken ingediend. Wacht een paar minuten voordat u het opnieuw probeert.',
|
||||
@@ -173,26 +155,19 @@ const nl = {
|
||||
paste: 'Plakken',
|
||||
paste_into_folder: 'Plakken in Map',
|
||||
path: 'Pad',
|
||||
personalization: 'Personalisatie',
|
||||
pick_name_for_website: 'Kies een naam voor uw website',
|
||||
pictures: 'Afbeeldingen',
|
||||
plural_suffix: 'en',
|
||||
powered_by_puter_js: 'Aangedreven door {{link=docs}}Puter.js{{/link}}',
|
||||
preparing: 'Voorbereiden...',
|
||||
preparing_for_upload: 'Voorbereiden voor upload...',
|
||||
print: 'Afdrukken',
|
||||
privacy: 'Privacy',
|
||||
proceed_to_login: 'Doorgaan naar inloggen',
|
||||
proceed_with_account_deletion: 'Doorgaan met accountverwijdering',
|
||||
properties: 'Eigenschappen',
|
||||
public: 'Openbaar',
|
||||
publish: 'Publiceren',
|
||||
publish_as_website: 'Publiceer als website',
|
||||
puter_description: 'Puter is een privacy-first persoonlijke cloud om al je bestanden, apps en games op één veilige plek te bewaren, overal en altijd toegankelijk.',
|
||||
reading_file: 'Lezen %strong%',
|
||||
recover_password: 'Wachtwoord herstellen',
|
||||
refer_friends_c2a: 'Krijg 1 GB voor elke vriend die een account aanmaakt en bevestigt op Puter. Je vriend krijgt ook 1 GB!',
|
||||
refer_friends_social_media_c2a: 'Krijg 1 GB gratis opslagruimte op Puter.com!',
|
||||
refresh: 'Vernieuwen',
|
||||
rename: 'Hernoemen',
|
||||
replace: 'Vervangen',
|
||||
@@ -202,11 +177,9 @@ const nl = {
|
||||
save: 'Opslaan',
|
||||
saturation: 'Verzadiging',
|
||||
save_account: 'Account opslaan',
|
||||
save_account_to_get_copy_link: 'Maak een account aan om verder te gaan.',
|
||||
save_account_to_publish: 'Maak een account aan om verder te gaan.',
|
||||
save_session: 'Sessie opslaan',
|
||||
save_session_c2a: 'Maak een account aan om je huidige sessie op te slaan en verlies van werk te voorkomen.',
|
||||
scan_qr_2fa: 'Scan de QR-code met je authenticator-app',
|
||||
search: 'Zoeken',
|
||||
seconds: 'seconden',
|
||||
security: 'Beveiliging',
|
||||
@@ -224,13 +197,11 @@ const nl = {
|
||||
show_hidden: 'Toon verborgen',
|
||||
sign_in_with_puter: 'Inloggen met Puter',
|
||||
sign_up: 'Aanmelden',
|
||||
signing_in: 'Inloggen…',
|
||||
size: 'Grootte',
|
||||
skip: 'Overslaan',
|
||||
something_went_wrong: 'Er is iets misgegaan.',
|
||||
sort_by: 'Sorteren op',
|
||||
status: 'Status',
|
||||
storage_usage: 'Opslaggebruik',
|
||||
storage_puter_used: 'gebruikt door Puter',
|
||||
taking_longer_than_usual: 'Het duurt langer dan normaal. Even geduld alstublieft...',
|
||||
terms: 'Voorwaarden',
|
||||
@@ -258,29 +229,23 @@ const nl = {
|
||||
videos: 'Video\'s',
|
||||
visibility: 'Zichtbaarheid',
|
||||
yes: 'Ja',
|
||||
you_have_been_referred_to_puter_by_a_friend: 'Je bent door een vriend doorverwezen naar Puter!',
|
||||
zip: 'Zip',
|
||||
zipping_file: 'Bestand inpakken %strong%',
|
||||
|
||||
// === 2FA Setup ===
|
||||
setup2fa_1_step_heading: 'Open je authenticator-app',
|
||||
setup2fa_1_instructions: `
|
||||
Je kunt elke authenticator-app gebruiken die het Time-based One-Time Password (TOTP) protocol ondersteunt.
|
||||
Er zijn veel opties om uit te kiezen, maar als je twijfelt,
|
||||
<a target="_blank" href="https://authy.com/download">Authy</a>
|
||||
is een goede keuze voor Android en iOS.
|
||||
`,
|
||||
setup2fa_2_step_heading: 'Scan de QR-code',
|
||||
setup2fa_3_step_heading: 'Voer de 6-cijferige code in',
|
||||
setup2fa_4_step_heading: 'Kopieer je herstelcodes',
|
||||
setup2fa_4_instructions: `
|
||||
Deze herstelcodes zijn de enige manier om toegang te krijgen tot je account als je je telefoon kwijtraakt of je authenticator-app niet kunt gebruiken.
|
||||
Zorg ervoor dat je ze op een veilige plaats bewaart.
|
||||
`,
|
||||
setup2fa_5_step_heading: 'Bevestig 2FA-instelling',
|
||||
setup2fa_5_confirmation_1: 'Ik heb mijn herstelcodes op een veilige plaats opgeslagen',
|
||||
setup2fa_5_confirmation_2: 'Ik ben klaar om 2FA in te schakelen',
|
||||
setup2fa_5_button: '2FA inschakelen',
|
||||
|
||||
// === 2FA Login ===
|
||||
login2fa_otp_title: 'Voer 2FA-code in',
|
||||
@@ -288,7 +253,6 @@ const nl = {
|
||||
login2fa_recovery_title: 'Voer een herstelcode in',
|
||||
login2fa_recovery_instructions: 'Voer een van je herstelcodes in om toegang te krijgen tot je account.',
|
||||
login2fa_use_recovery_code: 'Gebruik een herstelcode',
|
||||
login2fa_recovery_back: 'Terug',
|
||||
login2fa_recovery_placeholder: 'XXXXXXXX',
|
||||
|
||||
'change': 'Wijzig',
|
||||
@@ -356,20 +320,13 @@ const nl = {
|
||||
// =============================================================
|
||||
// Missing translations
|
||||
// =============================================================
|
||||
'choose_publishing_option': 'Kies hoe u uw website wilt publiceren:', // In English: "Choose how you want to publish your website:"
|
||||
'create_desktop_shortcut': 'Snelkoppeling maken (Bureaublad)', // In English: "Create Shortcut (Desktop)"
|
||||
'create_desktop_shortcut_s': 'Snelkoppelingen maken (Bureaublad)', // In English: "Create Shortcuts (Desktop)"
|
||||
'create_shortcut_s': 'Snelkoppelingen maken', // In English: "Create Shortcuts"
|
||||
'minimize': 'Minimaliseren', // In English: "Minimize"
|
||||
'reload_app': 'App herladen', // In English: "Reload App"
|
||||
'publish_as_serverless_worker': 'Publiceer als Worker', // In English: "Publish as Worker"
|
||||
'toolbar.enter_fullscreen': 'Naar volledig scherm', // In English: "Enter Full Screen"
|
||||
'toolbar.github': 'GitHub', // In English: "GitHub"
|
||||
'toolbar.refer': 'Vriend uitnodigen', // In English: "Refer"
|
||||
'used_of': '{{used}} van {{available}} gebruikt', // In English: "{{used}} used of {{available}}"
|
||||
'worker': 'Worker', // In English: "Worker" (No direct Dutch equivalent, commonly used in tech context)
|
||||
'billing.offering.basic': 'Basis', // In English: "Basic"
|
||||
'too_many_attempts': 'Te veel pogingen. Probeer het later opnieuw.', // In English: "Too many attempts. Please try again later."
|
||||
'server_timeout': 'De server reageerde te langzaam. Probeer het opnieuw.', // In English: "The server took too long to respond. Please try again."
|
||||
'signup_error': 'Er is een fout opgetreden bij het aanmelden. Probeer het opnieuw.', // In English: "An error occurred during signup. Please try again."
|
||||
'alert_error_title': 'Fout!', // In English: "Error!"
|
||||
@@ -387,16 +344,11 @@ const nl = {
|
||||
'window_title_open': 'Openen', // In English: "Open"
|
||||
'window_title_change_password': 'Wachtwoord wijzigen', // In English: "Change Password"
|
||||
'window_title_select_font': 'Lettertype selecteren…', // In English: "Select font…"
|
||||
'window_title_session_list': 'Sessielijst!', // In English: "Session List!"
|
||||
'window_title_set_new_password': 'Nieuw wachtwoord instellen', // In English: "Set New Password"
|
||||
'window_title_publish_website': 'Website publiceren', // In English: "Publish Website"
|
||||
'window_title_publish_worker': 'Worker publiceren', // In English: "Publish Worker"
|
||||
'window_title_authenticating': 'Authenticatie bezig...', // In English: "Authenticating..."
|
||||
'window_title_refer_friend': 'Verwijs een vriend!', // In English: "Refer a friend!"
|
||||
'desktop_exit_full_screen': 'Volledig scherm verlaten', // In English: "Exit Full Screen"
|
||||
'desktop_enter_full_screen': 'Naar volledig scherm', // In English: "Enter Full Screen"
|
||||
|
||||
'item_shared_with_you': 'Een gebruiker heeft dit item met u gedeeld.', // In English: "A user has shared this item with you."
|
||||
'item_shared_by_you': 'U heeft dit item met ten minste één andere gebruiker gedeeld.', // In English: "You have shared this item with at least one other user."
|
||||
'item_shortcut': 'Snelkoppeling', // In English: "Shortcut"
|
||||
'item_associated_websites': 'Geassocieerde website', // In English: "Associated website"
|
||||
@@ -405,9 +357,6 @@ const nl = {
|
||||
'window_click_to_go_back': 'Klik om terug te gaan.', // In English: "Click to go back."
|
||||
'window_click_to_go_forward': 'Klik om vooruit te gaan.', // In English: "Click to go forward."
|
||||
'window_click_to_go_up': 'Klik om naar de bovenliggende map te gaan.', // In English: "Click to go one directory up."
|
||||
'window_title_public': 'Openbaar', // In English: "Public"
|
||||
'window_title_videos': "Video's", // In English: "Videos"
|
||||
'window_title_pictures': 'Afbeeldingen', // In English: "Pictures"
|
||||
'window_title_puter': 'Puter', // In English: "Puter"
|
||||
'window_folder_empty': 'Deze map is leeg', // In English: "This folder is empty"
|
||||
},
|
||||
|
||||
@@ -48,10 +48,7 @@ const nn = {
|
||||
delete_permanently: 'Slett permanent',
|
||||
deploy_as_app: 'Distribuer som app',
|
||||
descending: 'Synkande',
|
||||
desktop_background_fit: 'Tilpass',
|
||||
dir_published_as_website: '%strong% er publisert på:',
|
||||
download: 'Last ned',
|
||||
downloading: 'Lastar ned',
|
||||
email: 'E-post',
|
||||
email_or_username: 'E-post eller brukarnamn',
|
||||
empty_trash: 'Tøm papirkorg',
|
||||
@@ -65,10 +62,7 @@ const nn = {
|
||||
forgot_pass_c2a: 'Gløymt passord?',
|
||||
from: 'Frå',
|
||||
general: 'Generelt',
|
||||
get_a_copy_of_on_puter: "Få ein kopi av '%%' på Puter.com!",
|
||||
get_copy_link: 'Få kopilenkje',
|
||||
html_document: 'HTML-dokument',
|
||||
invite_link: 'Invitasjonslenkje',
|
||||
items_in_trash_cannot_be_renamed:
|
||||
'Dette elementet kan ikkje omdøypast fordi det er i papirkorga. For å omdøype dette elementet, dra det først ut av papirkorga.',
|
||||
jpeg_image: 'JPEG-bilete',
|
||||
@@ -97,22 +91,17 @@ const nn = {
|
||||
passwords_do_not_match: '`Nytt passord` og `Stadfest nytt passord` stemmer ikkje overeins.',
|
||||
paste: 'Lim inn',
|
||||
paste_into_folder: 'Lim inn i mappe',
|
||||
pick_name_for_website: 'Vel eit namn for nettstaden din:',
|
||||
powered_by_puter_js: 'Dreve av {{link=docs}}Puter.js{{/link}}',
|
||||
preparing: 'Førebur…',
|
||||
preparing_for_upload: 'Førebur opplasting…',
|
||||
properties: 'Eigenskapar',
|
||||
publish: 'Publiser',
|
||||
publish_as_website: 'Publiser som nettstad',
|
||||
recover_password: 'Gjenopprett passord',
|
||||
refer_friends_c2a:
|
||||
'Få 1 GB for kvar ven som opprettar og stadfestar ein konto på Puter. Vennen din får òg 1 GB.',
|
||||
refer_friends_social_media_c2a: 'Få 1 GB gratis lagringsplass på Puter.com!',
|
||||
refresh: 'Oppdater',
|
||||
rename: 'Gje nytt namn',
|
||||
resend_confirmation_code: 'Send stadfestingskoden på nytt',
|
||||
restore: 'Gjenopprett',
|
||||
save_account_to_get_copy_link: 'Vennligst opprett ein konto for å halde fram.',
|
||||
save_account_to_publish: 'Vennligst opprett ein konto for å halde fram.',
|
||||
save_session_c2a: 'Opprett ein konto for å lagre gjeldande økt og unngå å miste arbeidet ditt.',
|
||||
select: 'Vel',
|
||||
@@ -124,7 +113,6 @@ const nn = {
|
||||
show_hidden: 'Vis skjulte',
|
||||
sign_in_with_puter: 'Logg inn med Puter',
|
||||
sign_up: 'Registrer deg',
|
||||
signing_in: 'Logger inn…',
|
||||
size: 'Storleik',
|
||||
sort_by: 'Sorter etter',
|
||||
taking_longer_than_usual: 'Dette tar litt lengre tid enn vanleg. Vennligst vent...',
|
||||
@@ -140,7 +128,6 @@ const nn = {
|
||||
username: 'Brukarnamn',
|
||||
username_changed: 'Brukarnamn oppdatert.',
|
||||
versions: 'Versjonar',
|
||||
you_have_been_referred_to_puter_by_a_friend: 'Du har blitt referert til Puter av ein ven!',
|
||||
zip: 'Zip',
|
||||
|
||||
// Updated translations for previously missing keys
|
||||
@@ -149,23 +136,15 @@ const nn = {
|
||||
account_password: 'Stadfest kontopassord', // In English: "Verify Account Password"
|
||||
allow: 'Tillat', // In English: "Allow"
|
||||
associated_websites: 'Tilknytte nettstader', // In English: "Associated Websites"
|
||||
auto_arrange: 'Auto-ordne', // In English: "Auto Arrange"
|
||||
change: 'Endre', // In English: "Change"
|
||||
change_always_open_with: 'Vil du alltid opne denne filtypen med', // In English: "Do you want to always open this type of file with"
|
||||
change_email: 'Endre e-post', // In English: "Change Email"
|
||||
close: 'Lukk', // In English: "Close"
|
||||
close_all_windows_and_log_out: 'Lukk vindauge og logg ut', // In English: "Close Windows and Log Out"
|
||||
confirm: 'Stadfest', // In English: "Confirm"
|
||||
confirm_2fa_setup: 'Eg har lagt til koden i autentikatorappen min', // In English: "I have added the code to my authenticator app"
|
||||
confirm_2fa_recovery: 'Eg har lagra gjenopprettingskodane mine på ein trygg stad', // In English: "I have saved my recovery codes in a secure location"
|
||||
confirm_code_generic_incorrect: 'Feil kode.', // In English: "Incorrect Code."
|
||||
confirm_code_generic_too_many_requests: 'For mange førespurnader. Vennligst vent nokre minutt.', // In English: "Too many requests. Please wait a few minutes."
|
||||
confirm_code_generic_submit: 'Send inn kode', // In English: "Submit Code"
|
||||
confirm_code_generic_try_again: 'Prøv igjen', // In English: "Try Again"
|
||||
confirm_code_generic_title: 'Skriv inn stadfestingskode', // In English: "Enter Confirmation Code"
|
||||
confirm_code_2fa_instruction: 'Skriv inn den 6-sifra koden frå autentikatorappen din.', // In English: "Enter the 6-digit code from your authenticator app."
|
||||
confirm_code_2fa_submit_btn: 'Send inn', // In English: "Submit"
|
||||
confirm_code_2fa_title: 'Skriv inn 2FA-kode', // In English: "Enter 2FA Code"
|
||||
confirm_delete_multiple_items: 'Er du sikker på at du vil slette desse elementa permanent?', // In English: "Are you sure you want to permanently delete these items?"
|
||||
confirm_delete_single_item: 'Vil du slette dette elementet permanent?', // In English: "Do you want to permanently delete this item?"
|
||||
confirm_open_apps_log_out: 'Du har opne appar. Er du sikker på at du vil logge ut?', // In English: "You have open apps. Are you sure you want to log out?"
|
||||
@@ -174,7 +153,6 @@ const nn = {
|
||||
confirm_delete_user_title: 'Slette konto?', // In English: "Delete Account?"
|
||||
confirm_session_revoke: 'Er du sikker på at du vil trekkje tilbake denne økta?', // In English: "Are you sure you want to revoke this session?"
|
||||
confirm_your_email_address: 'Stadfest e-postadressa di', // In English: "Confirm Your Email Address"
|
||||
contact_us_verification_required: 'Du må ha ein stadfesta e-postadresse for å bruke dette.', // In English: "You must have a verified email address to use this."
|
||||
copying_file: 'Kopierer %%', // In English: "Copying %%"
|
||||
credits: 'Bidragsytarar', // In English: "Credits"
|
||||
close_all: 'Lukk alle', // In English: "Close All"
|
||||
@@ -184,7 +162,6 @@ const nn = {
|
||||
desktop: 'Skrivebord', // In English: "Desktop"
|
||||
developers: 'Utviklarar', // In English: "Developers"
|
||||
disable_2fa: 'Deaktiver 2FA', // In English: "Disable 2FA"
|
||||
disable_2fa_confirm: 'Er du sikker på at du vil deaktivere 2FA?', // In English: "Are you sure you want to disable 2FA?"
|
||||
disable_2fa_instructions: 'Skriv inn passordet ditt for å deaktivere 2FA.', // In English: "Enter your password to disable 2FA."
|
||||
documents: 'Dokument', // In English: "Documents"
|
||||
dont_allow: 'Ikkje tillat', // In English: "Don't Allow"
|
||||
@@ -214,14 +191,12 @@ const nn = {
|
||||
lightness: 'Lys',
|
||||
link_copied: 'Lenkja kopiert',
|
||||
loading: 'Lastar',
|
||||
looks_good: 'Ser bra ut!',
|
||||
manage_sessions: 'Handter økter',
|
||||
modified: 'Endra',
|
||||
new_email: 'Ny e-post',
|
||||
no: 'Nei',
|
||||
original_name: 'Originalt namn',
|
||||
original_path: 'Original sti',
|
||||
oss_code_and_content: 'Programvare med open kjeldekode og innhald',
|
||||
password_recovery_rate_limit:
|
||||
'Du har nådd grensa vår for frekvens; vennligst vent nokre minutt. For å unngå dette i framtida, ikkje last inn sida på nytt for mange gonger.',
|
||||
password_recovery_token_invalid:
|
||||
@@ -231,16 +206,12 @@ const nn = {
|
||||
password_strength_error:
|
||||
'Passordet må vere minst 8 teikn langt og innehalde minst éin stor bokstav, éin liten bokstav, éin tal og éin spesialteikn.',
|
||||
path: 'Sti',
|
||||
personalization: 'Personleggjering',
|
||||
pictures: 'Bilete',
|
||||
plural_suffix: 'ar',
|
||||
print: 'Skriv ut',
|
||||
privacy: 'Personvern',
|
||||
proceed_to_login: 'Fortsett til innlogging',
|
||||
proceed_with_account_deletion: 'Fortsett med sletting av konto',
|
||||
public: 'Offentleg',
|
||||
puter_description:
|
||||
'Puter er ein personleg skyteknologi med fokus på personvern, der du kan lagre alle filene, appane og spela dine på ein sikker stad, tilgjengeleg frå overalt til ei kvar tid.',
|
||||
reading: 'Leser %strong%',
|
||||
writing: 'Skriv %strong%',
|
||||
replace: 'Erstatt',
|
||||
@@ -249,7 +220,6 @@ const nn = {
|
||||
saturation: 'Metting',
|
||||
save_account: 'Lagre konto',
|
||||
save_session: 'Lagre økt',
|
||||
scan_qr_2fa: 'Skann QR-koden med autentikatorappen din',
|
||||
search: 'Søk',
|
||||
seconds: 'sekund',
|
||||
security: 'Tryggleik',
|
||||
@@ -261,7 +231,6 @@ const nn = {
|
||||
skip: 'Hopp over',
|
||||
something_went_wrong: 'Noko gjekk galt.',
|
||||
status: 'Status',
|
||||
storage_usage: 'Lagringsbruk',
|
||||
storage_puter_used: 'brukt av Puter',
|
||||
terms: 'Vilkår',
|
||||
transparency: 'Gjennomsikt',
|
||||
@@ -280,31 +249,25 @@ const nn = {
|
||||
yes: 'Ja',
|
||||
sequencing: 'Sekvenserar %strong%',
|
||||
zipping: 'Zippar %strong%',
|
||||
setup2fa_1_step_heading: 'Opne autentikatorappen din',
|
||||
setup2fa_1_instructions: `
|
||||
Du kan bruke ein autentikatorapp som støttar Time-based One-Time Password (TOTP)-protokollen.
|
||||
Det finst mange å velje mellom, men om du er usikker,
|
||||
er <a target="_blank" href="https://authy.com/download">Authy</a>
|
||||
eit godt valg for Android og iOS.
|
||||
`,
|
||||
setup2fa_2_step_heading: 'Skann QR-koden',
|
||||
setup2fa_3_step_heading: 'Skriv inn den 6-sifra koden',
|
||||
setup2fa_4_step_heading: 'Kopier gjenopprettingskodane dine',
|
||||
setup2fa_4_instructions: `
|
||||
Desse gjenopprettingskodane er den einaste måten å få tilgang til kontoen din om du mistar telefonen eller ikkje kan bruke autentikatorappen.
|
||||
Pass på å lagre dei på ein trygg stad.
|
||||
`,
|
||||
setup2fa_5_step_heading: 'Stadfest 2FA-oppsett',
|
||||
setup2fa_5_confirmation_1: 'Eg har lagra gjenopprettingskodane mine på ein trygg stad',
|
||||
setup2fa_5_confirmation_2: 'Eg er klar til å aktivere 2FA',
|
||||
setup2fa_5_button: 'Aktiver 2FA',
|
||||
login2fa_otp_title: 'Skriv inn 2FA-kode',
|
||||
login2fa_otp_instructions: 'Skriv inn den 6-sifra koden frå autentikatorappen din.',
|
||||
login2fa_recovery_title: 'Skriv inn ein gjenopprettingskode',
|
||||
login2fa_recovery_instructions:
|
||||
'Skriv inn ein av gjenopprettingskodane dine for å få tilgang til kontoen din.',
|
||||
login2fa_use_recovery_code: 'Bruk ein gjenopprettingskode',
|
||||
login2fa_recovery_back: 'Tilbake',
|
||||
login2fa_recovery_placeholder: 'XXXXXXXX',
|
||||
Editor: 'Redigerar',
|
||||
Viewer: 'Visar',
|
||||
@@ -368,20 +331,13 @@ const nn = {
|
||||
'billing.accelerated': 'Akselerert', // In English: "Accelerated"
|
||||
'billing.enjoy_msg': 'Nyt %% skylagring pluss andre fordelar.', // In English: "Enjoy %% of Cloud Storage plus other benefits."
|
||||
|
||||
choose_publishing_option: 'Vel korleis du vil publisere nettsida di:', // "Original English: Choose how you want to publish your website:"
|
||||
create_desktop_shortcut: 'Lag snarveg (Skrivebord)', // "Original English: Create Shortcut (Desktop)"
|
||||
create_desktop_shortcut_s: 'Lag snarvegar (Skrivebord)', // "Original English: Create Shortcuts (Desktop)"
|
||||
create_shortcut_s: 'Lag snarvegar', // "Original English: Create Shortcuts"
|
||||
minimize: 'Minimer', // "Original English: Minimize"
|
||||
reload_app: 'Last inn app på nytt', // "Original English: Reload App"
|
||||
publish_as_serverless_worker: 'Publiser som Worker', // "Original English: Publish as Worker - 'Worker' kept as technical term"
|
||||
'toolbar.enter_fullscreen': 'Gå til fullskjerm', // "Original English: Enter Full Screen"
|
||||
'toolbar.github': 'GitHub', // "Original English: GitHub - Brand name kept unchanged"
|
||||
'toolbar.refer': 'Verv', // "Original English: Refer - 'Verv' is more natural than 'Referer'"
|
||||
used_of: '{{used}} brukt av {{available}}', // "Original English: {{used}} used of {{available}} - Variables preserved in original format"
|
||||
worker: 'Worker', // "Original English: Worker - Technical term kept"
|
||||
'billing.offering.basic': 'Grunnleggjande', // "Original English: Basic"
|
||||
too_many_attempts: 'For mange forsøk. Prøv igjen seinare.', // "Original English: Too many attempts. Please try again later."
|
||||
server_timeout: 'Tenaren brukte for lang tid på å svare. Prøv igjen.', // "Original English: The server took too long to respond. Please try again."
|
||||
signup_error: 'Det oppstod ein feil under registrering. Prøv igjen.', // "Original English: An error occurred during signup. Please try again."
|
||||
alert_error_title: 'Feil!', // "Original English: Error!"
|
||||
@@ -399,15 +355,10 @@ const nn = {
|
||||
window_title_open: 'Opne', // "Original English: Open"
|
||||
window_title_change_password: 'Endre passord', // "Original English: Change Password"
|
||||
window_title_select_font: 'Vel skrifttype…', // "Original English: Select font… - Ellipsis preserved"
|
||||
window_title_session_list: 'Øktliste!', // "Original English: Session List!"
|
||||
window_title_set_new_password: 'Vel nytt passord', // "Original English: Set New Password"
|
||||
window_title_publish_website: 'Publiser nettside', // "Original English: Publish Website"
|
||||
window_title_publish_worker: 'Publiser Worker', // "Original English: Publish Worker"
|
||||
window_title_authenticating: 'Autentiserer...', // "Original English: Authenticating..."
|
||||
window_title_refer_friend: 'Verv ein ven!', // "Original English: Refer a friend!"
|
||||
desktop_exit_full_screen: 'Avslutt fullskjerm', // "Original English: Exit Full Screen"
|
||||
desktop_enter_full_screen: 'Gå til fullskjerm', // "Original English: Enter Full Screen"
|
||||
item_shared_with_you: 'Ein brukar har delt denne tingen med deg.', // "Original English: A user has shared this item with you."
|
||||
item_shared_by_you: 'Du har delt denne tingen med minst ein annan brukar.', // "Original English: You have shared this item with at least one other user."
|
||||
item_shortcut: 'Snarveg', // "Original English: Shortcut"
|
||||
item_associated_websites: 'Tilknytt nettside', // "Original English: Associated website"
|
||||
@@ -416,9 +367,6 @@ const nn = {
|
||||
window_click_to_go_back: 'Klikk for å gå tilbake.', // "Original English: Click to go back."
|
||||
window_click_to_go_forward: 'Klikk for å gå framover.', // "Original English: Click to go forward."
|
||||
window_click_to_go_up: 'Klikk for å gå eitt nivå opp.', // "Original English: Click to go one directory up."
|
||||
window_title_public: 'Offentleg', // "Original English: Public"
|
||||
window_title_videos: 'Videoar', // "Original English: Videos"
|
||||
window_title_pictures: 'Bilete', // "Original English: Pictures"
|
||||
window_title_puter: 'Puter', // "Original English: Puter - Brand name kept unchanged"
|
||||
window_folder_empty: 'Denne mappa er tom', // "Original English: This folder is empty"
|
||||
},
|
||||
|
||||
@@ -31,7 +31,6 @@ const pl = {
|
||||
allow: 'Pozwól',
|
||||
ascending: 'Rosnąco',
|
||||
associated_websites: 'Powiązane strony',
|
||||
auto_arrange: 'Auto Aranżacja',
|
||||
cancel: 'Anuluj',
|
||||
change_email: 'Zmień email',
|
||||
change_language: 'Zmień język',
|
||||
@@ -41,17 +40,10 @@ const pl = {
|
||||
close_all_windows_and_log_out: 'Zamknij wszystkie okna i wyloguj',
|
||||
change_always_open_with: 'Czy chcesz zawsze otwierać ten typ pliku używając',
|
||||
confirm: 'Potwierdzam',
|
||||
confirm_2fa_setup: 'Dodałem kod do mojej aplikacji autentykującej',
|
||||
confirm_2fa_recovery: 'Zapisałem moje kody odzyskiwania w bezpiecznym miejscu',
|
||||
confirm_account_for_free_referral_storage_c2a: 'Stwórz konto i potwierdź swój adres e-mail, żeby dostać 1 GB darmowego miejsca. Twój znajomy również dostanie 1 GB darmowego miejsca.',
|
||||
confirm_code_generic_incorrect: 'Nieprawidłowy kod.',
|
||||
confirm_code_generic_too_many_requests: 'Zbyt wiele zapytań. Zaczekaj kilka minut.',
|
||||
confirm_code_generic_submit: 'Wyślij kod',
|
||||
confirm_code_generic_try_again: 'Spróbuj jeszcze raz',
|
||||
confirm_code_generic_title: 'Wprowadź kod odzyskiwania',
|
||||
confirm_code_2fa_instruction: 'Wprowadź 6-cyfrowy kod ze swojej aplikacji autentykującej.',
|
||||
confirm_code_2fa_submit_btn: 'Wyślij',
|
||||
confirm_code_2fa_title: 'Wprowadź kod uwierzytelniania dwuskładnikowego',
|
||||
confirm_delete_multiple_items: 'Czy na pewno chcesz na zawsze usunąć te przedmioty?',
|
||||
confirm_delete_single_item: 'Czy chcesz na zawsze usunąć ten przedmiot?',
|
||||
confirm_open_apps_log_out: 'Masz otwarte aplikacje. Czy chcesz na pewno się wylogować?',
|
||||
@@ -61,7 +53,6 @@ const pl = {
|
||||
confirm_session_revoke: 'Czy jesteś pewien że chcesz unieważnić tą sesję?',
|
||||
confirm_your_email_address: 'Potwierdź swój adres email',
|
||||
contact_us: 'Skontaktuj się z nami',
|
||||
contact_us_verification_required: 'Twój adres email musi być potwierdzony aby tego użyć.',
|
||||
continue: 'Kontynuuj',
|
||||
copy: 'Kopiuj',
|
||||
copy_link: 'Kopiuj Link',
|
||||
@@ -83,17 +74,13 @@ const pl = {
|
||||
deploy_as_app: 'Wdrożenie jako apkę',
|
||||
descending: 'Malejąco',
|
||||
desktop: 'Pulpit',
|
||||
desktop_background_fit: 'Dopasowanie',
|
||||
developers: 'Dla deweloperów',
|
||||
dir_published_as_website: '%strong% został opublikowany do:',
|
||||
disable_2fa: 'Wyłącz uwierzytelnianie dwuskładnikowe',
|
||||
disable_2fa_confirm: 'Czy jesteś pewien że chcesz wyłączyć uwierzytelnianie dwuskładnikowe?',
|
||||
disable_2fa_instructions: 'Wprowadź swoje hasło aby wyłączyć uwierzytelnianie dwuskładnikowe.',
|
||||
documents: 'Dokumenty',
|
||||
dont_allow: 'Nie pozwalaj',
|
||||
download: 'Pobierz',
|
||||
download_file: 'Pobierz plik',
|
||||
downloading: 'Pobieranie',
|
||||
email: 'Email',
|
||||
email_change_confirmation_sent: 'Email z potwierdzeniem został wysłany na twój adres. Sprawdź swoją skrzynkę mailową i wykonaj przesłane instrukcje aby zakończyć proces.',
|
||||
email_invalid: 'Email jest nieprawidłowy.',
|
||||
@@ -118,13 +105,10 @@ const pl = {
|
||||
forgot_pass_c2a: 'Zapomniałeś hasła?',
|
||||
from: 'Od',
|
||||
general: 'Ogólne',
|
||||
get_a_copy_of_on_puter: 'Pobierz kopię \'%%\' na Puter.com!',
|
||||
get_copy_link: 'Pobierz skopiowany link',
|
||||
home: 'Folder domowy',
|
||||
html_document: 'dokument HTML',
|
||||
hue: 'Odcień',
|
||||
incorrect_password: 'Nieprawidłowe hasło',
|
||||
invite_link: 'Link z zaproszeniem',
|
||||
item: 'przedmiot',
|
||||
items_in_trash_cannot_be_renamed: 'Nazwa tego przedmiotu nie może zostać zmieniona, ponieważ znajduje się on w koszu. Aby zmienić jego nazwę, wyciągnij go z kosza.',
|
||||
jpeg_image: 'Obraz JPEG',
|
||||
@@ -135,7 +119,6 @@ const pl = {
|
||||
loading: 'Ładowanie',
|
||||
log_in: 'Zaloguj się',
|
||||
log_out: 'Wyloguj się',
|
||||
looks_good: 'W porządku!',
|
||||
manage_sessions: 'Zarządzaj sesjami',
|
||||
modified: 'Zmodyfikowany',
|
||||
move: 'Przenieś',
|
||||
@@ -160,7 +143,6 @@ const pl = {
|
||||
open_with: 'Otwórz za pomocą',
|
||||
original_name: 'Oryginalna nazwa',
|
||||
original_path: 'Oryginalna ścieżka',
|
||||
oss_code_and_content: 'Oprogramowanie i treści open source',
|
||||
password: 'Hasło',
|
||||
password_changed: 'Hasło zostało zmienione.',
|
||||
password_recovery_rate_limit: 'Osiągnąłeś limit szybkości powtórzeń; poczekaj kilka minut. Aby zapobiec temu w przyszłości, unikaj wielokrotnego przeładowywania strony.',
|
||||
@@ -172,26 +154,19 @@ const pl = {
|
||||
paste: 'Wklej',
|
||||
paste_into_folder: 'Wklej do folderu',
|
||||
path: 'Ścieżka',
|
||||
personalization: 'Personalizacja',
|
||||
pick_name_for_website: 'Wybierz nazwę dla swojej strony:',
|
||||
pictures: 'Obrazy',
|
||||
plural_suffix: '', //In polish there is a ton of plural suffixes, so I just left it empty
|
||||
powered_by_puter_js: 'Zasilane za pomocą {{link=docs}}Puter.js{{/link}}',
|
||||
preparing: 'Przygotowywanie...',
|
||||
preparing_for_upload: 'Przygotowywanie do wgrania...',
|
||||
print: 'Drukuj',
|
||||
privacy: 'Prywatność',
|
||||
proceed_to_login: 'Przejdź do logowania',
|
||||
proceed_with_account_deletion: 'Przejdź do kasowania konta',
|
||||
properties: 'Właściwości',
|
||||
public: 'Publiczne',
|
||||
publish: 'Opublikuj',
|
||||
publish_as_website: 'Opublikuj jako stronę',
|
||||
puter_description: 'Puter to zachowująca twoją prywatność osobista chmura, służąca do przechowywania wszystkich twoich plików, aplikacji i gier w jednym, bezpiecznym miejscu, dostępnym z dowolnego miejsca w dowolnej chwili.',
|
||||
reading_file: 'Odczyt %strong%',
|
||||
recover_password: 'Odzyskaj hasło',
|
||||
refer_friends_c2a: 'Zdobądź 1 GB za każdego znajomego, który założy konto na Puter! On również otrzyma 1 GB.',
|
||||
refer_friends_social_media_c2a: 'Zdobądź 1 GB darmowego miejsca na Puter.com!',
|
||||
refresh: 'Odśwież',
|
||||
rename: 'Zmień nazwę',
|
||||
replace: 'Zamień',
|
||||
@@ -201,11 +176,9 @@ const pl = {
|
||||
save: 'Zapisz',
|
||||
saturation: 'Nasycenie',
|
||||
save_account: 'Zapisz konto',
|
||||
save_account_to_get_copy_link: 'Zapisz konto, aby uzyskać link do skopiowania',
|
||||
save_account_to_publish: 'Zapisz konto, aby opublikować',
|
||||
save_session: 'Zapisz sesję',
|
||||
save_session_c2a: 'Stwórz konto, żeby zapisać aktualną sesję i nie utracić swojej pracy.',
|
||||
scan_qr_2fa: 'Zeskanuj kod QR za pomocą apki autentykującej',
|
||||
search: 'Szukaj',
|
||||
seconds: 'sekund',
|
||||
security: 'Bezpieczeństwo',
|
||||
@@ -223,13 +196,11 @@ const pl = {
|
||||
show_hidden: 'Pokaż ukryte',
|
||||
sign_in_with_puter: 'Zaloguj się z Puter',
|
||||
sign_up: 'Zarejestruj się',
|
||||
signing_in: 'Logowanie…',
|
||||
size: 'Rozmiar',
|
||||
skip: 'Pomiń',
|
||||
something_went_wrong: 'Coś poszło nie tak.',
|
||||
sort_by: 'Sortuj',
|
||||
status: 'Status',
|
||||
storage_usage: 'Wykorzystanie miejsca',
|
||||
storage_puter_used: 'wykorzystane przez Puter',
|
||||
taking_longer_than_usual: 'To trwa chwilę dłużej niż zwyklę. Prosimy poczekać...',
|
||||
terms: 'Warunki',
|
||||
@@ -257,29 +228,23 @@ const pl = {
|
||||
videos: 'Wideo',
|
||||
visibility: 'Widoczność',
|
||||
yes: 'Tak',
|
||||
you_have_been_referred_to_puter_by_a_friend: 'Twój znajomy polecił Ci Puter!',
|
||||
zip: 'Spakuj',
|
||||
zipping_file: 'Pakowanie %strong%',
|
||||
|
||||
// === 2FA Setup ===
|
||||
setup2fa_1_step_heading: 'Otwórz swoją aplikację autentykującą',
|
||||
setup2fa_1_instructions: `
|
||||
Możesz użyć dowolnej aplikacji autentykującej, która wspiera protokół haseł jednorazowych opartych o czas (TOTP).
|
||||
Jest ich wiele, ale jeżeli nie masz pewności,
|
||||
<a target="_blank" href="https://authy.com/download">Authy</a>
|
||||
to solidny wybór dla systemów Android i iOS.
|
||||
`,
|
||||
setup2fa_2_step_heading: 'Zeskanuj kod QR',
|
||||
setup2fa_3_step_heading: 'Wprowadź 6-cyfrowy kod',
|
||||
setup2fa_4_step_heading: 'Skopiuj swoje kody odzyskiwania',
|
||||
setup2fa_4_instructions: `
|
||||
Te kody odzyskiwania są jedynym sposobem aby uzyskać dostęp do twojego konta jeżeli stracisz swój telefon lub nie jesteś w stanie użyć aplikacji autentykującej.
|
||||
Upewnij się, że przechowujesz je w bezpiecznym miejscu
|
||||
`,
|
||||
setup2fa_5_step_heading: 'Potwierdź ustawienia autentykacji dwuetapowej',
|
||||
setup2fa_5_confirmation_1: 'Zachowałem moje kody odzyskiwania w bezpiecznym miejscu',
|
||||
setup2fa_5_confirmation_2: 'Jestem gotów aby włączyć autentykację dwuetapową',
|
||||
setup2fa_5_button: 'Włącz autentykację dwuetapową',
|
||||
|
||||
// === 2FA Login ===
|
||||
login2fa_otp_title: 'Wprowadź kod autentykacji dwuetapowej',
|
||||
@@ -287,7 +252,6 @@ const pl = {
|
||||
login2fa_recovery_title: 'Wprowadź kod odzyskiwania',
|
||||
login2fa_recovery_instructions: 'Wprowadź jeden ze swoich kodów odzyskiwania aby uzyskać dostęp do swojego konta.',
|
||||
login2fa_use_recovery_code: 'Użyj kod odzyskiwania',
|
||||
login2fa_recovery_back: 'Powrót',
|
||||
login2fa_recovery_placeholder: 'XXXXXXXX',
|
||||
|
||||
'change': 'Zmiana',
|
||||
@@ -353,21 +317,14 @@ const pl = {
|
||||
'billing.expanded': 'Rozszerzona', // -> These adjectives are used to describe the "AI Access" and/or "Bandwidth"
|
||||
'billing.accelerated': 'Przyspieszona', // /
|
||||
'billing.enjoy_msg': 'Ciesz się pakietem %% pamięci w chmurze i innymi benefitami',
|
||||
'choose_publishing_option': 'Wybierz jak chcesz opublikować swoją stronę:',
|
||||
'create_desktop_shortcut': 'Utwórz Skrót (Pulpit)',
|
||||
'create_desktop_shortcut_s': 'Utwórz Skróty (Pulpit)',
|
||||
'create_shortcut_s': 'Utwórz Skróty',
|
||||
'minimize': 'Zminimalizuj',
|
||||
'reload_app': 'Odśwież Aplikację',
|
||||
'plural_suffix': undefined,
|
||||
'publish_as_serverless_worker': 'Opublikuj jako Worker',
|
||||
'toolbar.enter_fullscreen': 'Otwórz Pełen Ekran',
|
||||
'toolbar.github': 'GitHub',
|
||||
'toolbar.refer': 'Poleć',
|
||||
'used_of': '{{used}} użyte z {{available}}',
|
||||
'worker': 'Worker',
|
||||
'billing.offering.basic': 'Podstawowe',
|
||||
'too_many_attempts': 'Zbyt wiele prób. Spróbuj ponownie później.',
|
||||
'server_timeout': 'Serwer zbyt długo nie odpowiada. Spróbuj ponownie.',
|
||||
'signup_error': 'Wystąpił błąd w trakcie rejestrowania. Spróbuj ponownie.',
|
||||
'alert_error_title': 'Błąd!',
|
||||
@@ -385,15 +342,10 @@ const pl = {
|
||||
'window_title_open': 'Otwórz',
|
||||
'window_title_change_password': 'Zmień Hasło',
|
||||
'window_title_select_font': 'Wybierz czcionkę…',
|
||||
'window_title_session_list': 'Lista Sesji!',
|
||||
'window_title_set_new_password': 'Ustaw Nowe Hasło',
|
||||
'window_title_publish_website': 'Opublikuj Stronę',
|
||||
'window_title_publish_worker': 'Opublikuj Workera',
|
||||
'window_title_authenticating': 'Autentykowanie...',
|
||||
'window_title_refer_friend': 'Poleć znajomego!',
|
||||
'desktop_exit_full_screen': 'Zamknij Pełen Ekran',
|
||||
'desktop_enter_full_screen': 'Otwórz Pełne Okno',
|
||||
'item_shared_with_you': 'Użytkownik podzielił się tym przedmiotem z tobą.',
|
||||
'item_shared_by_you': 'Podzieliłeś się tym przedmiotem przynajmniej z jednym innym użytkownikiem.',
|
||||
'item_shortcut': 'Skrót',
|
||||
'item_associated_websites': 'Powiązana strona',
|
||||
@@ -402,9 +354,6 @@ const pl = {
|
||||
'window_click_to_go_back': 'Kliknij by wrócić',
|
||||
'window_click_to_go_forward': 'Kliknij by przejść dalej',
|
||||
'window_click_to_go_up': 'Kliknij by przejść do o katalog wyżej',
|
||||
'window_title_public': 'Publiczne',
|
||||
'window_title_videos': 'Filmy',
|
||||
'window_title_pictures': 'Zdjęcia',
|
||||
'window_title_puter': 'Puter',
|
||||
'window_folder_empty': 'Ten folder jest pusty',
|
||||
|
||||
|
||||
@@ -31,7 +31,6 @@ const pt = {
|
||||
allow: 'Permitir',
|
||||
ascending: 'Ascendente',
|
||||
associated_websites: 'Sites Associados',
|
||||
auto_arrange: 'Auto Organizar',
|
||||
cancel: 'Cancelar',
|
||||
change: 'Alterar',
|
||||
change_email: 'Alterar e-mail',
|
||||
@@ -42,17 +41,10 @@ const pt = {
|
||||
close_all_windows_and_log_out: 'Fechar Janelas e Sair',
|
||||
change_always_open_with: 'Queres que ficheiros deste tipo abram sempre com',
|
||||
confirm: 'Confirmar',
|
||||
confirm_2fa_setup: 'Adicionei o código à minha aplicação de autenticação',
|
||||
confirm_2fa_recovery: 'Guardei os meus códigos de recuperação em um local seguro.',
|
||||
confirm_account_for_free_referral_storage_c2a: 'Cria uma conta e confirma o endereço do email para receberes 1 GB de armazenamento gratuito. O teu amigo também receberá 1 GB de armazenamento gratuito.',
|
||||
confirm_code_generic_incorrect: 'Código Incorreto.',
|
||||
confirm_code_generic_too_many_requests: 'Demasiados pedidos. Aguarde alguns minutos.',
|
||||
confirm_code_generic_submit: 'Submeter Código',
|
||||
confirm_code_generic_try_again: 'Tentar Novamente',
|
||||
confirm_code_generic_title: 'Introduza o Código de Confirmação',
|
||||
confirm_code_2fa_instruction: 'Introduza o código de 6 dígitos da sua aplicação de autenticação.',
|
||||
confirm_code_2fa_submit_btn: 'Submeter',
|
||||
confirm_code_2fa_title: 'Introduza o Código 2FA',
|
||||
confirm_delete_multiple_items: 'Tens a certeza que queres apagar estes itens permanentemente?',
|
||||
confirm_delete_single_item: 'Queres apagar este item permanentemente?',
|
||||
confirm_open_apps_log_out: 'Tens aplicações abertas. Queres mesmo terminar a sessão?',
|
||||
@@ -62,7 +54,6 @@ const pt = {
|
||||
confirm_session_revoke: 'Tem a certeza de que deseja revogar esta sessão?',
|
||||
confirm_your_email_address: 'Confirme o Seu Endereço de Email',
|
||||
contact_us: 'Contacta-nos',
|
||||
contact_us_verification_required: 'É necessário ter um endereço de email verificado para usar isto.',
|
||||
continue: 'Continua',
|
||||
copy: 'Copia',
|
||||
copy_link: 'Copia Link',
|
||||
@@ -84,17 +75,13 @@ const pt = {
|
||||
deploy_as_app: 'Publicar como aplicativo',
|
||||
descending: 'Descendente',
|
||||
desktop: 'Desktop',
|
||||
desktop_background_fit: 'Ajustado',
|
||||
developers: 'Desenvolvedores',
|
||||
dir_published_as_website: '%strong% foi publicado em:',
|
||||
disable_2fa: 'Disabilitar 2FA',
|
||||
disable_2fa_confirm: 'Tem acerteza que quer desabilitar a 2FA?',
|
||||
disable_2fa_instructions: 'Submetar a sua password para desabilitar 2FA.',
|
||||
documents: 'Dicumentos',
|
||||
dont_allow: 'Não Permitir',
|
||||
download: 'Descarregar',
|
||||
download_file: 'Descarregar Ficheiro',
|
||||
downloading: 'Fazendo a descarga',
|
||||
email: 'Email',
|
||||
email_change_confirmation_sent: 'Um email de confirmação foi enviado para o teu novo endereço de email. Por favor, verifique a sua caixa de entrada e siga as instruções para completar o processo.',
|
||||
email_invalid: 'O Email que providenciou é invalido.',
|
||||
@@ -119,13 +106,10 @@ const pt = {
|
||||
forgot_pass_c2a: 'Esqueceste a senha?',
|
||||
from: 'De',
|
||||
general: 'Geral',
|
||||
get_a_copy_of_on_puter: 'Obter uma cópia de \'%%\' em Puter.com!',
|
||||
get_copy_link: 'Copiar Link',
|
||||
home: 'Home',
|
||||
html_document: 'Documento HTML',
|
||||
hue: 'Hue',
|
||||
incorrect_password: 'Password Incorreta.',
|
||||
invite_link: 'Link do Convite',
|
||||
item: 'item',
|
||||
items_in_trash_cannot_be_renamed: 'Este item não pode ser renomeado porque está no lixo. Para alterar o nome, primeiro arrasta-o para fora do Lixo.',
|
||||
jpeg_image: 'Imagem JPEG',
|
||||
@@ -136,7 +120,6 @@ const pt = {
|
||||
loading: 'Carregando',
|
||||
log_in: 'Entrar',
|
||||
log_out: 'Sair',
|
||||
looks_good: 'Looks good!',
|
||||
manage_sessions: 'Gerir Sessões',
|
||||
modified: 'Modificado',
|
||||
move: 'Mover',
|
||||
@@ -161,7 +144,6 @@ const pt = {
|
||||
open_with: 'Abrir Com',
|
||||
original_name: 'Original Name',
|
||||
original_path: 'Original Path',
|
||||
oss_code_and_content: 'Software de Código Aberto',
|
||||
password: 'Password',
|
||||
password_changed: 'Password alterada.',
|
||||
password_recovery_rate_limit: 'Atingiste o nosso limite de pedidos; por favor, espera alguns minutos. Para evitar isto no futuro, evita recarregar a página demasiadas vezes',
|
||||
@@ -173,28 +155,21 @@ const pt = {
|
||||
paste: 'Colar',
|
||||
paste_into_folder: 'Cola na Pasta',
|
||||
path: 'Caminho',
|
||||
personalization: 'Personalização',
|
||||
pick_name_for_website: 'Escolha um nome para seu site:',
|
||||
pictures: 'Imagens',
|
||||
plural_suffix: 's',
|
||||
powered_by_puter_js: 'Criado com {{link=docs}}Puter.js{{/link}}',
|
||||
preparing: 'A preparar...',
|
||||
preparing_for_upload: 'A preparar o upload...',
|
||||
print: 'Imprimir',
|
||||
privacy: 'Privacidade',
|
||||
proceed_to_login: 'Prosseguir para o login',
|
||||
proceed_with_account_deletion: 'Prosseguir com Remoção da Conta',
|
||||
properties: 'Propriedades',
|
||||
public: 'Público',
|
||||
publish: 'Publicar',
|
||||
publish_as_website: 'Publicar como Site',
|
||||
puter_description: 'Puter é uma nuvem pessoal que prioriza a privacidade e que mantém todos os teus ficheiros, aplicativos e jogos num local seguro, acessível de qualquer lugar e a qualquer hora.',
|
||||
reading: 'A ler %strong%',
|
||||
writing: 'A escrever %strong%',
|
||||
reading_file: 'A ler %strong%',
|
||||
recover_password: 'Recuperar Password',
|
||||
refer_friends_c2a: 'Ganha 1 GB por cada amigo que criar e confirmar uma conta Puter. Os teus amigos também ganham 1 GB!',
|
||||
refer_friends_social_media_c2a: 'Ganha 1 GB de armazenamento gratuito em Puter.com!',
|
||||
refresh: 'Atualizar',
|
||||
rename: 'Renomear',
|
||||
replace: 'Substituir',
|
||||
@@ -204,11 +179,9 @@ const pt = {
|
||||
save: 'Gravar',
|
||||
saturation: 'Saturação',
|
||||
save_account: 'Gravar conta',
|
||||
save_account_to_get_copy_link: 'Para continuar, por favor crie uma conta.',
|
||||
save_account_to_publish: 'Para continuar, por favor crie uma conta.',
|
||||
save_session: 'Gravar sessão',
|
||||
save_session_c2a: 'Crie uma conta para gravar a sessão atual e evitar perder o seu trabalho.',
|
||||
scan_qr_2fa: 'Digitalize o código QR com a tua aplicação de autenticação',
|
||||
search: 'Pesquisar',
|
||||
seconds: 'segundos',
|
||||
security: 'Segurança',
|
||||
@@ -226,13 +199,11 @@ const pt = {
|
||||
show_hidden: 'Exibir janelas ocultas',
|
||||
sign_in_with_puter: 'Entrar em Puter',
|
||||
sign_up: 'Registar',
|
||||
signing_in: 'Entrar…',
|
||||
size: 'Tamanho',
|
||||
skip: 'Passar à frente',
|
||||
something_went_wrong: 'Algo correu mal.',
|
||||
sort_by: 'Ordenar por',
|
||||
status: 'Status',
|
||||
storage_usage: 'Uso do Armazenamento',
|
||||
storage_puter_used: 'Usado por Puter',
|
||||
taking_longer_than_usual: 'Está a levar mais tempo que o usual. Por favor aguarda...',
|
||||
terms: 'Termos',
|
||||
@@ -261,30 +232,24 @@ const pt = {
|
||||
videos: 'Videos',
|
||||
visibility: 'Visibilidade',
|
||||
yes: 'Sim',
|
||||
you_have_been_referred_to_puter_by_a_friend: 'Um amigo teu recomendou-te a Puter.com!',
|
||||
zip: 'Zipar',
|
||||
sequencing: 'A sequenciar %strong%', // In English: "Sequencing %strong%"
|
||||
zipping: 'A compactar %strong%', // In English: "Zipping %strong%"
|
||||
|
||||
// === 2FA Setup ===
|
||||
setup2fa_1_step_heading: 'Abra uma aplicação de autenticação',
|
||||
setup2fa_1_instructions: `
|
||||
Podes usar qualquer aplicação de autenticação que suporte o protocolo Time-based One-Time Password (TOTP).
|
||||
Existem muitas opções, mas se não tiveres a certeza,
|
||||
<a target="_blank" href="https://authy.com/download">Authy</a>
|
||||
é uma escolha sólida para Android e iOS.
|
||||
`,
|
||||
setup2fa_2_step_heading: 'Digitalize o código QR',
|
||||
setup2fa_3_step_heading: 'Introduza o código de 6 dígitos',
|
||||
setup2fa_4_step_heading: 'Guarde os códigos de recuperação',
|
||||
setup2fa_4_instructions: `
|
||||
Estes códigos de recuperação são a única maneira de aceder à tua conta se perderes o teu telefone ou não puderes usar a tua aplicação de autenticação.
|
||||
Certifica-te de os guardar num local seguro.
|
||||
`,
|
||||
setup2fa_5_step_heading: 'Confirmação',
|
||||
setup2fa_5_confirmation_1: 'Guardei os meus códigos de recuperação num local seguro.',
|
||||
setup2fa_5_confirmation_2: 'Estou pronto para ativar a 2FA.',
|
||||
setup2fa_5_button: 'Ativar 2FA',
|
||||
|
||||
// === 2FA Login ===
|
||||
login2fa_otp_title: 'Introduza o código 2FA',
|
||||
@@ -292,7 +257,6 @@ const pt = {
|
||||
login2fa_recovery_title: 'Intruduza o codigo de Recuperação de 2FA',
|
||||
login2fa_recovery_instructions: 'Introduza um dos seus códigos de recuperação de 2FA para ter acesso a sua conta.',
|
||||
login2fa_use_recovery_code: 'Usar código de recuperação',
|
||||
login2fa_recovery_back: 'Voltar',
|
||||
login2fa_recovery_placeholder: 'XXXXXXXX',
|
||||
|
||||
'Editor': 'Editor', // In English: "Editor"
|
||||
@@ -354,20 +318,13 @@ const pt = {
|
||||
'billing.expanded': 'Expandido', // In English: "Expanded"
|
||||
'billing.accelerated': 'Acelerado', // In English: "Accelerated"
|
||||
'billing.enjoy_msg': 'Desfrute de %% de Armazenamento na Nuvem e outros benefícios.', // In English: "Enjoy %% of Cloud Storage plus other benefits."
|
||||
'choose_publishing_option': 'Escolha como deseja publicar seu site:', // In English: "Choose how you want to publish your website:"
|
||||
'create_desktop_shortcut': 'Criar Atalho (Área de Trabalho)', // In English: "Create Shortcut (Desktop)"
|
||||
'create_desktop_shortcut_s': 'Criar Atalhos (Área de Trabalho)', // In English: "Create Shortcuts (Desktop)"
|
||||
'create_shortcut_s': 'Criar Atalhos', // In English: "Create Shortcuts"
|
||||
'minimize': 'Minimizar', // In English: "Minimize"
|
||||
'reload_app': 'Recarregar Aplicação', // In English: "Reload App"
|
||||
'publish_as_serverless_worker': 'Publicar como Worker', // In English: "Publish as Worker"
|
||||
'toolbar.enter_fullscreen': 'Entrar em Tela Cheia', // In English: "Enter Full Screen"
|
||||
'toolbar.github': 'GitHub', // In English: "GitHub"
|
||||
'toolbar.refer': 'Indicar', // In English: "Refer"
|
||||
'used_of': '{{used}} usado de {{available}}', // In English: "{{used}} used of {{available}}"
|
||||
'worker': 'Worker', // In English: "Worker"
|
||||
'billing.offering.basic': 'Básico', // In English: "Basic"
|
||||
'too_many_attempts': 'Muitas tentativas. Por favor, tente novamente mais tarde.', // In English: "Too many attempts. Please try again later."
|
||||
'server_timeout': 'O servidor demorou muito para responder. Por favor, tente novamente.', // In English: "The server took too long to respond. Please try again."
|
||||
'signup_error': 'Ocorreu um erro durante o cadastro. Por favor, tente novamente.', // In English: "An error occurred during signup. Please try again."
|
||||
'alert_error_title': 'Erro!', // In English: "Error!"
|
||||
@@ -385,15 +342,10 @@ const pt = {
|
||||
'window_title_open': 'Abrir', // In English: "Open"
|
||||
'window_title_change_password': 'Alterar Senha', // In English: "Change Password"
|
||||
'window_title_select_font': 'Selecionar fonte…', // In English: "Select font…"
|
||||
'window_title_session_list': 'Lista de Sessões!', // In English: "Session List!"
|
||||
'window_title_set_new_password': 'Definir Nova Senha', // In English: "Set New Password"
|
||||
'window_title_publish_website': 'Publicar Site', // In English: "Publish Website"
|
||||
'window_title_publish_worker': 'Publicar Worker', // In English: "Publish Worker"
|
||||
'window_title_authenticating': 'Autenticando...', // In English: "Authenticating..."
|
||||
'window_title_refer_friend': 'Indicar um amigo!', // In English: "Refer a friend!"
|
||||
'desktop_exit_full_screen': 'Sair da Tela Cheia', // In English: "Exit Full Screen"
|
||||
'desktop_enter_full_screen': 'Entrar em Tela Cheia', // In English: "Enter Full Screen"
|
||||
'item_shared_with_you': 'Um usuário compartilhou este item com você.', // In English: "A user has shared this item with you."
|
||||
'item_shared_by_you': 'Você compartilhou este item com pelo menos um outro usuário.', // In English: "You have shared this item with at least one other user."
|
||||
'item_shortcut': 'Atalho', // In English: "Shortcut"
|
||||
'item_associated_websites': 'Site associado', // In English: "Associated website"
|
||||
@@ -402,9 +354,6 @@ const pt = {
|
||||
'window_click_to_go_back': 'Clique para voltar.', // In English: "Click to go back."
|
||||
'window_click_to_go_forward': 'Clique para avançar.', // In English: "Click to go forward."
|
||||
'window_click_to_go_up': 'Clique para subir um diretório.', // In English: "Click to go one directory up."
|
||||
'window_title_public': 'Público', // In English: "Public"
|
||||
'window_title_videos': 'Vídeos', // In English: "Videos"
|
||||
'window_title_pictures': 'Imagens', // In English: "Pictures"
|
||||
'window_title_puter': 'Puter', // In English: "Puter"
|
||||
'window_folder_empty': 'Esta pasta está vazia', // In English: "This folder is empty"
|
||||
},
|
||||
|
||||
@@ -31,7 +31,6 @@ const ro = {
|
||||
allow: 'Permite',
|
||||
ascending: 'Ascendent',
|
||||
associated_websites: 'Site-uri partenere',
|
||||
auto_arrange: 'Aranjare automată',
|
||||
cancel: 'Anulează',
|
||||
change_email: 'Schimbă e-mailul',
|
||||
change_language: 'Schimbă Limba',
|
||||
@@ -41,18 +40,11 @@ const ro = {
|
||||
close_all_windows_and_log_out: 'Închide toate ferestrele și delogheză-mă',
|
||||
change_always_open_with: 'Doriți să deschideți acest tip de fișiere cu ',
|
||||
confirm: 'Confirmă',
|
||||
confirm_2fa_setup: 'Am adăgat codul la aplicația de autentificare',
|
||||
confirm_2fa_recovery: 'Am salvat codurile de recuperare într-o locație sigură',
|
||||
|
||||
confirm_account_for_free_referral_storage_c2a: 'Creați un cont și confirmați adresa de e-mail pentru a primi 1 GB de spațiu de stocare gratuit. Deasemenea, un prieten de-al tău va primi 1 GB de spațiu de stocare gratuit.',
|
||||
confirm_code_generic_incorrect: 'Cod incorect',
|
||||
confirm_code_generic_too_many_requests: 'Prea multe solicitări. Vă rugăm așteptați câteva minute.',
|
||||
confirm_code_generic_submit: 'Trimite cod',
|
||||
confirm_code_generic_try_again: 'Încercați din nou',
|
||||
confirm_code_generic_title: 'Introduceți codul de confirmare',
|
||||
confirm_code_2fa_instruction: 'Introduceți codul de 6 cifre generat de aplicația de autentificare',
|
||||
confirm_code_2fa_submit_btn: 'Trimite',
|
||||
confirm_code_2fa_title: 'Introduceți codul 2FA',
|
||||
confirm_delete_multiple_items: 'Sunteți sigur(ă) că doriți să ștergeți aceste obiecte permanent',
|
||||
confirm_delete_single_item: 'Doriți să ștergeți acest obiect permanent?',
|
||||
confirm_open_apps_log_out: 'Aveți aplicații care rulează. Sunteți sigur(ă) că doriți să vă delogați?',
|
||||
@@ -62,7 +54,6 @@ const ro = {
|
||||
confirm_session_revoke: 'Sunteți sigur(ă) că doriți să revocați sesiunea curentă?',
|
||||
confirm_your_email_address: 'Confirmați adresa dumneavoastră de e-mail',
|
||||
contact_us: 'Contactează-ne',
|
||||
contact_us_verification_required: 'Aveți nevoie de o adresă de e-mail confirmată.',
|
||||
continue: 'Continuă',
|
||||
copy: 'Copiază',
|
||||
copy_link: 'Copiază link',
|
||||
@@ -84,17 +75,13 @@ const ro = {
|
||||
deploy_as_app: 'Publică ca aplicație',
|
||||
descending: 'Coborând',
|
||||
desktop: 'Desktop',
|
||||
desktop_background_fit: 'Potrivește fundalul',
|
||||
developers: 'Programatori',
|
||||
dir_published_as_website: '%strong% a fost publicat către:',
|
||||
disable_2fa: 'Dezactivați 2FA',
|
||||
disable_2fa_confirm: 'Sunteți sigur(ă) că doriți să dezactivați 2FA?',
|
||||
disable_2fa_instructions: 'Introduceți parola dumneavoastră pentru a dezactiva 2FA.',
|
||||
documents: 'Documente',
|
||||
dont_allow: 'Nu permiteți',
|
||||
download: 'Descarcă',
|
||||
download_file: 'Descarcă fișier',
|
||||
downloading: 'Se descarcă',
|
||||
email: 'E-mail',
|
||||
email_change_confirmation_sent: 'Un e-mail de confirmare a fost trimis către noua dumneavoastră adresă de e-mail. Vă rugăm să verificați ©ăsuța și să urmați intrucțiunile pentru a finaliza procesul.',
|
||||
email_invalid: 'E-mailul este invalid.',
|
||||
@@ -119,13 +106,10 @@ const ro = {
|
||||
forgot_pass_c2a: 'Ați uitat parola?',
|
||||
from: 'De la',
|
||||
general: 'General',
|
||||
get_a_copy_of_on_puter: 'Obțineți o copie a \'%%\' pe Puter.com!',
|
||||
get_copy_link: 'Obțineți link-ul copiei',
|
||||
home: 'Acasă',
|
||||
html_document: 'Document HTML',
|
||||
hue: 'Hue',
|
||||
incorrect_password: 'Parolă incorectă',
|
||||
invite_link: 'Link de invitație',
|
||||
item: 'Obiect',
|
||||
items_in_trash_cannot_be_renamed: 'Acest obiect nu poate fi redenumit deoarece este în coșul de gunoi. Pentru a redenumi acest obiect, mai întâi scoateți-l din Coșul de gunoi.',
|
||||
jpeg_image: 'Imagine JPEG',
|
||||
@@ -136,7 +120,6 @@ const ro = {
|
||||
loading: 'Încarcă',
|
||||
log_in: 'Loghează-te',
|
||||
log_out: 'Deconectează-te',
|
||||
looks_good: 'Arată bine!',
|
||||
manage_sessions: 'Administrează sesiuni',
|
||||
modified: 'Modificat',
|
||||
move: 'Mută',
|
||||
@@ -161,7 +144,6 @@ const ro = {
|
||||
open_with: 'Deschide cu',
|
||||
original_name: 'Numele original',
|
||||
original_path: 'Calea originală',
|
||||
oss_code_and_content: 'Software și conținut Open Source',
|
||||
password: 'Parolă',
|
||||
password_changed: 'Parolă schimbată.',
|
||||
password_recovery_rate_limit: 'Ați ajuns la frecvența limită; vă rugăm așteptați câteva minute. Pentru a nu se mai repeta pe viitor, evitați să reîncărcați pagina de prea multe ori.',
|
||||
@@ -173,26 +155,19 @@ const ro = {
|
||||
paste: 'Inserează',
|
||||
paste_into_folder: 'Inserează in folder',
|
||||
path: 'Cale',
|
||||
personalization: 'Personalizare',
|
||||
pick_name_for_website: 'Alegeți un nume pentru site-ul dvs:',
|
||||
pictures: 'Imagini',
|
||||
plural_suffix: 'e',
|
||||
powered_by_puter_js: 'Creat de {{link=docs}}Puter.js{{/link}}',
|
||||
preparing: 'Preparare...',
|
||||
preparing_for_upload: 'Preparare pentru încărcare...',
|
||||
print: 'Tipărește',
|
||||
privacy: 'Confidențialitate',
|
||||
proceed_to_login: 'Mergeți mai departe pentru logare',
|
||||
proceed_with_account_deletion: 'Mergeți mai departe cu ștergerea contului',
|
||||
properties: 'Proprietăți',
|
||||
public: 'Public',
|
||||
publish: 'Publică',
|
||||
publish_as_website: 'Publică, ca site web',
|
||||
puter_description: 'Puter este un cloud personal care pune pe primul loc confidențialitatea pentru păstrarea tuturor fișierelor dumneavoastră, a app-urilor, a jocurilor într-un loc sigur și accesibil de oriunde oricând.',
|
||||
reading_file: 'Citind %strong%',
|
||||
recover_password: 'Recuperare Parolă',
|
||||
refer_friends_c2a: 'Obțineți 1 GB pentru fiecare prieten care creează și confirmă un cont pe Puter. și prietenul tău va primi 1 GB!',
|
||||
refer_friends_social_media_c2a: 'Obțineți 1 GB de spațiu de stocare gratuit pe Puter.com!',
|
||||
refresh: 'Reîmprospătare',
|
||||
rename: 'Redenumește',
|
||||
replace: 'Înlocuiește',
|
||||
@@ -202,11 +177,9 @@ const ro = {
|
||||
save: 'Salvare',
|
||||
saturation: 'Saturație',
|
||||
save_account: 'Salvați contul',
|
||||
save_account_to_get_copy_link: 'Vă rugăm să creați un cont pentru a copia un link.',
|
||||
save_account_to_publish: 'Vă rugăm să creați un cont pentru a publica.',
|
||||
save_session: 'Salvați sesiunea',
|
||||
save_session_c2a: 'Creați un cont pentru a vă salva sesiunea curentă și pentru a evita pierderea muncii.',
|
||||
scan_qr_2fa: 'Scanati codul QR cu aplicația de autentificare',
|
||||
search: 'Caută',
|
||||
seconds: 'Secunde',
|
||||
security: 'Securitate',
|
||||
@@ -224,13 +197,11 @@ const ro = {
|
||||
show_hidden: 'Arată ascuns',
|
||||
sign_in_with_puter: 'Conectați-vă cu Puter',
|
||||
sign_up: 'Inscrie-te',
|
||||
signing_in: 'Se conectează…',
|
||||
size: 'Mărime',
|
||||
skip: 'Ignoră',
|
||||
something_went_wrong: 'Ceva nu a funcționat.',
|
||||
sort_by: 'Sortează dupa',
|
||||
status: 'Stare',
|
||||
storage_usage: 'Utilizare spațiu',
|
||||
storage_puter_used: 'folosit de Puter',
|
||||
taking_longer_than_usual: 'Durează puțin mai mult decât de obicei. Vă rugăm așteptați...',
|
||||
terms: 'Termeni',
|
||||
@@ -258,34 +229,27 @@ const ro = {
|
||||
videos: 'Video-uri',
|
||||
visibility: 'Vizibilitate',
|
||||
yes: 'Da',
|
||||
you_have_been_referred_to_puter_by_a_friend: 'Ai fost invitat pe Puter de către un prieten!',
|
||||
zip: 'Zip',
|
||||
zipping_file: 'Se arhivează %strong%',
|
||||
|
||||
setup2fa_1_step_heading: 'Deschideți aplicația de autentificare',
|
||||
setup2fa_1_instructions: `
|
||||
Puteți folosi orice aplicație de autentificare care folosește protocolul Time-based One-Time Password (TOTP).
|
||||
Sunt multe astfel de aplicații, dar dacă sunteți nesiguri
|
||||
<a target="_blank" href="https://authy.com/download">Authy</a>
|
||||
este o opțiune serioasă pentru Android si iOS.
|
||||
`,
|
||||
setup2fa_2_step_heading: 'Scanați codul QR',
|
||||
setup2fa_3_step_heading: 'Introduceți codul de 6 cifre',
|
||||
setup2fa_4_step_heading: 'Copiați codurile dumneavoastră de restaurare',
|
||||
setup2fa_4_instructions: `
|
||||
Aceste coduri de restaurare sunt singurul mod în care vă puteți accesa contul dacă vă pierdeți telefonul sau nu puteți folosi aplicația de autentificare.
|
||||
Asigurați-vă că le scrie-ți într-un loc sigur.`,
|
||||
setup2fa_5_step_heading: 'Confirmați configurația 2FA',
|
||||
setup2fa_5_confirmation_1: 'Mi-am salvat codurile de restaurare într-un loc sigur',
|
||||
setup2fa_5_confirmation_2: 'Sunt gata să activez 2FA',
|
||||
setup2fa_5_button: 'Activează 2FA',
|
||||
|
||||
login2fa_otp_title: 'Introduceți codul 2FA',
|
||||
login2fa_otp_instructions: 'Introduceți codul de 6 cifre din aplicația de autentificare.',
|
||||
login2fa_recovery_title: 'Introduceți un cod de restaurare',
|
||||
login2fa_recovery_instructions: 'Introduceți unul dintre codurile de restaurare pentru a vă accesa contul.',
|
||||
login2fa_use_recovery_code: 'Folosiți un cod de restaurare',
|
||||
login2fa_recovery_back: 'Înapoi',
|
||||
login2fa_recovery_placeholder: 'XXXXXXXX',
|
||||
|
||||
change: 'Schimbǎ',
|
||||
@@ -349,20 +313,13 @@ const ro = {
|
||||
'billing.expanded': 'Extins',
|
||||
'billing.accelerated': 'Accelerat',
|
||||
'billing.enjoy_msg': 'Bucură-te de %% spațiu de stocare în cloud plus alte beneficii.',
|
||||
'choose_publishing_option': 'Alege cum vrei să îți publici site-ul:',
|
||||
'create_desktop_shortcut': 'Creează Shortcut (Desktop)',
|
||||
'create_desktop_shortcut_s': 'Creează Shortcut-uri (Desktop)',
|
||||
'create_shortcut_s': 'Creează Shortcut-uri',
|
||||
'minimize': 'Minimizează',
|
||||
'reload_app': 'Reîncarcă aplicația',
|
||||
'publish_as_serverless_worker': 'Publică ca muncitor',
|
||||
'toolbar.enter_fullscreen': 'Intră în modul tot ecranul',
|
||||
'toolbar.github': 'GitHub',
|
||||
'toolbar.refer': 'Recomandă',
|
||||
'used_of': '%% folosit din %%',
|
||||
'worker': 'Muncitor',
|
||||
'billing.offering.basic': 'De bază',
|
||||
'too_many_attempts': 'Prea multe încercări. Te rugăm să încerci din nou mai târziu.',
|
||||
'server_timeout': 'Serverului i-a luat prea mult să răspundă. Te rugăm să încerci din nou.',
|
||||
'signup_error': 'A apărut o eroare la înregistrare. Te rugăm să încerci din nou.',
|
||||
'alert_error_title': 'Eroare!',
|
||||
@@ -380,15 +337,10 @@ const ro = {
|
||||
'window_title_open': 'Deschide',
|
||||
'window_title_change_password': 'Schimbă parola',
|
||||
'window_title_select_font': 'Selectează font…',
|
||||
'window_title_session_list': 'Lista de sesiuni!',
|
||||
'window_title_set_new_password': 'Setează o parolă nouă',
|
||||
'window_title_publish_website': 'Publică site-ul',
|
||||
'window_title_publish_worker': 'Publică muncitorul',
|
||||
'window_title_authenticating': 'Se autentifică...',
|
||||
'window_title_refer_friend': 'Recomandă unui prieten!',
|
||||
'desktop_exit_full_screen': 'Ieși din ecran complet',
|
||||
'desktop_enter_full_screen': 'Intră pe ecran complet',
|
||||
'item_shared_with_you': 'Un utilizator a partajat acest element cu tine.',
|
||||
'item_shared_by_you': 'Ai partajat acest element cu cel puțin un alt utilizator.',
|
||||
'item_shortcut': 'Scurtătură',
|
||||
'item_associated_websites': 'Website asociat',
|
||||
@@ -397,9 +349,6 @@ const ro = {
|
||||
'window_click_to_go_back': 'Apasă pentru a merge înapoi.',
|
||||
'window_click_to_go_forward': 'Apasă pentru a merge înainte.',
|
||||
'window_click_to_go_up': 'Apasă pentru a avansa un director.',
|
||||
'window_title_public': 'Public',
|
||||
'window_title_videos': 'Videoclipuri',
|
||||
'window_title_pictures': 'Poze',
|
||||
'window_title_puter': 'Puter',
|
||||
'window_folder_empty': 'Acest folder este gol',
|
||||
|
||||
|
||||
@@ -31,7 +31,6 @@ const ru = {
|
||||
allow: 'Разрешить',
|
||||
ascending: 'По возрастанию',
|
||||
associated_websites: 'Связанные сайты',
|
||||
auto_arrange: 'Автоупорядочивание',
|
||||
cancel: 'Отмена',
|
||||
change_email: 'Изменить электронную почту',
|
||||
change_language: 'Изменить язык',
|
||||
@@ -42,21 +41,13 @@ const ru = {
|
||||
change_always_open_with:
|
||||
'Хотите всегда открывать файлы этого типа с помощью',
|
||||
confirm: 'Подтвердить',
|
||||
confirm_2fa_setup: 'Я добавил код в приложение для аутентификации',
|
||||
confirm_2fa_recovery:
|
||||
'Я сохранил коды восстановления доступа в безопасном месте',
|
||||
confirm_account_for_free_referral_storage_c2a:
|
||||
'Создайте учетную запись и подтвердите свой адрес электронной почты, чтобы получить 1 Гб бесплатного дискового пространства. Ваш друг также получит 1 Гб бесплатного дискового пространства.',
|
||||
confirm_code_generic_incorrect: 'Неверный код.',
|
||||
confirm_code_generic_too_many_requests:
|
||||
'Слишком много запросов. Пожалуйста, подождите несколько минут.',
|
||||
confirm_code_generic_submit: 'Отправить код',
|
||||
confirm_code_generic_try_again: 'Попробуйте снова',
|
||||
confirm_code_generic_title: 'Введите код подтверждения',
|
||||
confirm_code_2fa_instruction:
|
||||
'Введите 6-значный код из приложения для аутентификации.',
|
||||
confirm_code_2fa_submit_btn: 'Отправить',
|
||||
confirm_code_2fa_title: 'Введите код аутентификации',
|
||||
confirm_delete_multiple_items:
|
||||
'Вы уверены, что хотите навсегда удалить эти элементы?',
|
||||
confirm_delete_single_item:
|
||||
@@ -69,8 +60,6 @@ const ru = {
|
||||
confirm_delete_user_title: 'Удалить учетную запись?',
|
||||
confirm_session_revoke: 'Вы уверены, что хотите отменить эту сессию?',
|
||||
contact_us: 'Связаться с нами',
|
||||
contact_us_verification_required:
|
||||
'Подтвердите адрес электронной почты чтобы продожить.',
|
||||
continue: 'Продолжить',
|
||||
copy: 'Копировать',
|
||||
copy_link: 'Скопировать ссылку',
|
||||
@@ -92,19 +81,14 @@ const ru = {
|
||||
deploy_as_app: 'Развернуть как приложение',
|
||||
descending: 'По убыванию',
|
||||
desktop: 'Рабочий стол',
|
||||
desktop_background_fit: 'Вместить',
|
||||
developers: 'Разработчики',
|
||||
dir_published_as_website: '%strong% опубликован в:',
|
||||
disable_2fa: 'Отключить двойную аутентификацию',
|
||||
disable_2fa_confirm:
|
||||
'Вы уверены, что хотите отключить двойную аутентификацию?',
|
||||
disable_2fa_instructions:
|
||||
'Введите пароль чтобы отключить двойную аутентификацию.',
|
||||
documents: 'Документы',
|
||||
dont_allow: 'Доступ запрещён',
|
||||
download: 'Загрузить',
|
||||
download_file: 'Загрузить файл',
|
||||
downloading: 'Загрузка',
|
||||
email: 'Электронная почта',
|
||||
email_change_confirmation_sent:
|
||||
'На ваш новый адрес электронной почты было отправлено письмо с подтверждением. Пожалуйста, проверьте свой ящик электронной почты и следуйте инструкциям, чтобы завершить процесс.',
|
||||
@@ -133,13 +117,10 @@ const ru = {
|
||||
forgot_pass_c2a: 'Забыли пароль?',
|
||||
from: 'От',
|
||||
general: 'Общее',
|
||||
get_a_copy_of_on_puter: 'Получите копию \'%%\' на Puter.com!',
|
||||
get_copy_link: 'Получить ссылку для копирования',
|
||||
home: 'Домой',
|
||||
html_document: 'HTML документ',
|
||||
hue: 'Оттенок',
|
||||
incorrect_password: 'Неверный пароль',
|
||||
invite_link: 'Ссылка для приглашения',
|
||||
item: 'элемент',
|
||||
items_in_trash_cannot_be_renamed: 'Этот элемент нельзя переименовать, потому что он находится в Корзине. Чтобы переименовать этот элемент, сначала перенесите его из Корзины.',
|
||||
jpeg_image: 'JPEG изображение',
|
||||
@@ -150,7 +131,6 @@ const ru = {
|
||||
loading: 'Загружается',
|
||||
log_in: 'Войти',
|
||||
log_out: 'Выйти',
|
||||
looks_good: 'Выглядит здорово!',
|
||||
manage_sessions: 'Управление Сеансами',
|
||||
modified: 'Изменено',
|
||||
move: 'Переместить',
|
||||
@@ -175,8 +155,6 @@ const ru = {
|
||||
open_with: 'Открыть с помощью',
|
||||
original_name: 'Оригинальное имя',
|
||||
original_path: 'Изначальный путь',
|
||||
oss_code_and_content:
|
||||
'Программное обеспечение и контент с открытым исходным кодом',
|
||||
password: 'Пароль',
|
||||
password_changed: 'Пароль изменен.',
|
||||
password_recovery_rate_limit:
|
||||
@@ -193,27 +171,20 @@ const ru = {
|
||||
paste: 'Вставить',
|
||||
paste_into_folder: 'Вставить в папку',
|
||||
path: 'Путь',
|
||||
personalization: 'Персонализация',
|
||||
pick_name_for_website: 'Выберите имя для вашего сайта:',
|
||||
pictures: 'Изображения',
|
||||
plural_suffix: 's', //does not exist in Russian language
|
||||
powered_by_puter_js: 'Создано на {{link=docs}}Puter.js{{/link}}',
|
||||
preparing: 'Подготовка...',
|
||||
preparing_for_upload: 'Подготовка к загрузке...',
|
||||
print: 'Печать',
|
||||
privacy: 'Конфиденциальность',
|
||||
proceed_to_login: 'Перейти ко входу',
|
||||
proceed_with_account_deletion: 'Продолжить удаление учетной записи',
|
||||
properties: 'Свойства',
|
||||
publish: 'Опубликовать',
|
||||
public: 'Общий доступ',
|
||||
publish_as_website: 'Опубликовать как сайт',
|
||||
puter_description: 'Puter — это персональное облако, обеспечивающее конфиденциальность, позволяющее хранить все ваши файлы, приложения и игры в одном безопасном месте, доступном из любого места в любое время.',
|
||||
reading_file: 'Чтение %strong%',
|
||||
recover_password: 'Восстановить Пароль',
|
||||
refer_friends_c2a:
|
||||
'Получите 1 ГБ за каждого друга, который создаст и подтвердит учетную запись на Puter. Ваш друг тоже получит 1 ГБ!',
|
||||
refer_friends_social_media_c2a: 'Получите 1 ГБ бесплатного хранилища на Puter.com!',
|
||||
refresh: 'Обновить',
|
||||
rename: 'Переименовать',
|
||||
replace: 'Заменить',
|
||||
@@ -223,14 +194,11 @@ const ru = {
|
||||
save: 'Сохранить',
|
||||
saturation: 'Насыщенность',
|
||||
save_account: 'Сохранить Учетную запись',
|
||||
save_account_to_get_copy_link:
|
||||
'Пожалуйста, создайте учетную запись, чтобы продолжить.',
|
||||
save_account_to_publish:
|
||||
'Пожалуйста, создайте учетную запись, чтобы продолжить.',
|
||||
save_session: 'Сохранить сеанс',
|
||||
save_session_c2a:
|
||||
'Создайте учетную запись, чтобы сохранить текущий сеанс и не потерять данные.',
|
||||
scan_qr_2fa: 'Отсканируйте QR-код с помощью приложения аутентификации',
|
||||
search: 'Поиск',
|
||||
seconds: 'секунды',
|
||||
security: 'Безопасность',
|
||||
@@ -250,13 +218,11 @@ const ru = {
|
||||
show_hidden: 'Показать скрытые',
|
||||
sign_in_with_puter: 'Войти с Puter',
|
||||
sign_up: 'Зарегистрироваться',
|
||||
signing_in: 'Вход в систему…',
|
||||
size: 'Размер',
|
||||
skip: 'Пропустить',
|
||||
something_went_wrong: 'Что-то пошло не так.',
|
||||
sort_by: 'Отсортировать по',
|
||||
status: 'Статус',
|
||||
storage_usage: 'Использование хранилища',
|
||||
storage_puter_used: 'использовано Puter',
|
||||
taking_longer_than_usual:
|
||||
'Это занимает немного больше времени чем обычно, пожалуйста, подождите...',
|
||||
@@ -286,32 +252,24 @@ const ru = {
|
||||
videos: 'Видео',
|
||||
visibility: 'Видимость',
|
||||
yes: 'Да',
|
||||
you_have_been_referred_to_puter_by_a_friend:
|
||||
'Вы были приглашены в Puter другом!',
|
||||
zip: 'Добавить в архив',
|
||||
zipping_file: 'Добавление в архив %strong%',
|
||||
|
||||
// === 2FA Setup ===
|
||||
setup2fa_1_step_heading: 'Откройте приложение для аутенцификации',
|
||||
setup2fa_1_instructions: `
|
||||
Вы можете использовать любое приложение для аутентификации, поддерживающее протокол одноразового пароля на основе времени (TOTP).
|
||||
Существует большой выбор приложений, но если вы не уверены, то
|
||||
<a target="_blank" href="https://authy.com/download">Authy</a>
|
||||
это хороший выбор для Android и iOS
|
||||
`,
|
||||
setup2fa_2_step_heading: 'Отсканируйте QR-код',
|
||||
setup2fa_3_step_heading: 'Введите 6-значный код',
|
||||
setup2fa_4_step_heading: 'Скопируйте коды восстановления',
|
||||
setup2fa_4_instructions: `
|
||||
Эти коды восстановления — единственный способ получить доступ к вашей учетной записи, если вы потеряете свой телефон или не сможете использовать приложение для аутентификации.
|
||||
Обязательно храните их в безопасном месте.
|
||||
`,
|
||||
setup2fa_5_step_heading:
|
||||
'Подтвердите установку двухфакторной аутентификации',
|
||||
setup2fa_5_confirmation_1:
|
||||
'Я сохранил коды восстановления в безопасном месте',
|
||||
setup2fa_5_confirmation_2: 'Я готов включить двухфакторную аутентификацию',
|
||||
setup2fa_5_button: 'Включить двухфакторную аутентификацию',
|
||||
|
||||
// === 2FA Login ===
|
||||
login2fa_otp_title: 'Введите код двухфакторной аутентификации',
|
||||
@@ -321,7 +279,6 @@ const ru = {
|
||||
login2fa_recovery_instructions:
|
||||
'Введите один из кодов восстановления доступа чтобы получить доступ к учетной записи.',
|
||||
login2fa_use_recovery_code: 'Используйте код восстановления доступа',
|
||||
login2fa_recovery_back: 'Назад',
|
||||
login2fa_recovery_placeholder: 'XXXXXXXX',
|
||||
change: 'Изменить',
|
||||
confirm_your_email_address: 'Подтвердить электронную почту',
|
||||
@@ -385,20 +342,13 @@ const ru = {
|
||||
'billing.expanded': 'Расширенный', // In English: "Expanded"
|
||||
'billing.accelerated': 'Ускоренный', // In English: "Accelerated"
|
||||
'billing.enjoy_msg': 'Пользуйтесь %% Облачным Хранилищем и остальными выгодами', // In English: "Enjoy %% of Cloud Storage plus other benefits."
|
||||
'choose_publishing_option': 'Выберите способ публикации вашего веб-сайта:', // In English: "Choose how you want to publish your website:"
|
||||
'create_desktop_shortcut': 'Создать ярлык (на рабочем столе)', // In English: "Create Shortcut (Desktop)"
|
||||
'create_desktop_shortcut_s': 'Создать ярлыки (на рабочем столе)', // In English: "Create Shortcuts (Desktop)"
|
||||
'create_shortcut_s': 'Создать ярлыки', // In English: "Create Shortcuts"
|
||||
'minimize': 'Свернуть', // In English: "Minimize"
|
||||
'reload_app': 'Перезагрузить приложение', // In English: "Reload App"
|
||||
'publish_as_serverless_worker': 'опубликовать как воркера', // In English: "Publish as Worker"
|
||||
'toolbar.enter_fullscreen': 'Перейти в полноэкранный режим', // In English: "Enter Full Screen"
|
||||
'toolbar.github': 'GitHub', // In English: "GitHub"
|
||||
'toolbar.refer': 'Рекомендовать', // In English: "Refer"
|
||||
'used_of': 'Использовано', // In English: "{{used}} used of {{available}}"
|
||||
'worker': 'Воркер', // In English: "Worker"
|
||||
'billing.offering.basic': 'Базовый', // In English: "Basic"
|
||||
'too_many_attempts': 'Слишком много попыток. Попробуйте позже.', // In English: "Too many attempts. Please try again later."
|
||||
'server_timeout': 'Слишком много попыток. Пожалуйста, попробуйте позже.', // In English: "The server took too long to respond. Please try again."
|
||||
'signup_error': 'Сервер слишком долго не отвечал. Пожалуйста, попробуйте снова.', // In English: "An error occurred during signup. Please try again."
|
||||
'alert_error_title': 'Ошибка!', // In English: "Error!"
|
||||
@@ -416,15 +366,10 @@ const ru = {
|
||||
'window_title_open': 'Открыть', // In English: "Open"
|
||||
'window_title_change_password': 'Изменить пароль', // In English: "Change Password"
|
||||
'window_title_select_font': 'Выберите шрифт...', // In English: "Select font…"
|
||||
'window_title_session_list': 'Список сессий!', // In English: "Session List!"
|
||||
'window_title_set_new_password': 'Установить новый пароль', // In English: "Set New Password"
|
||||
'window_title_publish_website': 'Опубликовать веб-сайт', // In English: "Publish Website"
|
||||
'window_title_publish_worker': 'Опубликовать воркер', // In English: "Publish Worker"
|
||||
'window_title_authenticating': 'Идёт проверка подлинности...', // In English: "Authenticating..."
|
||||
'window_title_refer_friend': 'Пригласить друга!', // In English: "Refer a friend!"
|
||||
'desktop_exit_full_screen': 'Выйти из полноэкранного режима', // In English: "Exit Full Screen"
|
||||
'desktop_enter_full_screen': 'Перейти в полноэкранный режим', // In English: "Enter Full Screen"
|
||||
'item_shared_with_you': 'Пользователь поделился с вами этим элементом.', // In English: "A user has shared this item with you."
|
||||
'item_shared_by_you': 'Вы поделились этим элементом как минимум с одним другим пользователем.', // In English: "You have shared this item with at least one other user."
|
||||
'item_shortcut': 'Ярлык', // In English: "Shortcut"
|
||||
'item_associated_websites': 'Связанный веб-сайт', // In English: "Associated website"
|
||||
@@ -433,9 +378,6 @@ const ru = {
|
||||
'window_click_to_go_back': 'Нажмите, чтобы вернуться назад', // In English: "Click to go back."
|
||||
'window_click_to_go_forward': 'Нажмите, чтобы перейти вперёд', // In English: "Click to go forward."
|
||||
'window_click_to_go_up': 'Нажмите, чтобы перейти на один каталог вверх', // In English: "Click to go one directory up."
|
||||
'window_title_public': 'Публичный', // In English: "Public"
|
||||
'window_title_videos': 'Видео', // In English: "Videos"
|
||||
'window_title_pictures': 'Изображения', // In English: "Pictures"
|
||||
'window_title_puter': 'Путер', // In English: "Puter"
|
||||
'window_folder_empty': 'Эта папка пуста', // In English: "This folder is empty"
|
||||
|
||||
|
||||
@@ -31,7 +31,6 @@ const sl = {
|
||||
allow: 'Dovoli',
|
||||
ascending: 'Naraščajoče',
|
||||
associated_websites: 'Povezana spletna mesta',
|
||||
auto_arrange: 'Samodejno razporedi',
|
||||
cancel: 'Prekliči',
|
||||
change: 'Spremeni',
|
||||
change_always_open_with: 'Ali želite to vrsto datotek vedno odpirati s/z',
|
||||
@@ -42,17 +41,10 @@ const sl = {
|
||||
close: 'Zapri',
|
||||
close_all_windows_and_log_out: 'Zapri okna in se odjavi',
|
||||
confirm: 'Potrdi',
|
||||
confirm_2fa_setup: 'Kodo sem dodal v svojo aplikacijo za preverjanje pristnosti',
|
||||
confirm_2fa_recovery: 'Svoje obnovitvene kode sem shranil na varno lokacijo',
|
||||
confirm_account_for_free_referral_storage_c2a: 'Ustvarite račun in potrdite svoj e-poštni naslov, da prejmete 1 GB brezplačnega prostora za shranjevanje. Tudi vaš prijatelj bo dobil 1 GB brezplačnega prostora za shranjevanje.',
|
||||
confirm_code_generic_incorrect: 'Napačna koda.',
|
||||
confirm_code_generic_too_many_requests: 'Preveč zahtev. Počakajte nekaj minut.',
|
||||
confirm_code_generic_submit: 'Pošlji kodo',
|
||||
confirm_code_generic_try_again: 'Poskusi znova',
|
||||
confirm_code_generic_title: 'Vnesite potrditveno kodo',
|
||||
confirm_code_2fa_instruction: 'Vnesite 6-mestno kodo iz vaše aplikacije za preverjanje pristnosti.',
|
||||
confirm_code_2fa_submit_btn: 'Pošlji',
|
||||
confirm_code_2fa_title: 'Vnesite 2FA kodo',
|
||||
confirm_delete_multiple_items: 'Ali ste prepričani, da želite trajno izbrisati te elemente?',
|
||||
confirm_delete_single_item: 'Ali želite trajno izbrisati ta element?',
|
||||
confirm_open_apps_log_out: 'Imate odprte aplikacije. Ste prepričani, da se želite odjaviti?',
|
||||
@@ -62,7 +54,6 @@ const sl = {
|
||||
confirm_session_revoke: 'Ali ste prepričani, da želite preklicati to sejo?',
|
||||
confirm_your_email_address: 'Potrdite svoj e-poštni naslov',
|
||||
contact_us: 'Kontaktirajte nas',
|
||||
contact_us_verification_required: 'Za uporabo tega morate imeti potrjen e-poštni naslov.',
|
||||
continue: 'Nadaljuj',
|
||||
copy: 'Kopiraj',
|
||||
copy_link: 'Kopiraj povezavo',
|
||||
@@ -70,8 +61,6 @@ const sl = {
|
||||
copying_file: 'Kopiranje %%',
|
||||
create_account: 'Ustvari račun',
|
||||
create_free_account: 'Ustvari brezplačen račun',
|
||||
create_desktop_shortcut: 'Ustvari bližnjico (namizje)',
|
||||
create_desktop_shortcut_s: 'Ustvari bližnjice (namizje)',
|
||||
create_shortcut: 'Ustvari bližnjico',
|
||||
create_shortcut_s: 'Ustvari bližnjice',
|
||||
credits: 'Zasluge',
|
||||
@@ -87,17 +76,13 @@ const sl = {
|
||||
deploy_as_app: 'Izvedi kot aplikacijo',
|
||||
descending: 'Padajoče',
|
||||
desktop: 'Namizje',
|
||||
desktop_background_fit: 'Prilagodi',
|
||||
developers: 'Razvijalci',
|
||||
dir_published_as_website: '%strong% je bilo objavljeno na:',
|
||||
disable_2fa: 'Onemogoči 2FA',
|
||||
disable_2fa_confirm: 'Ali ste prepričani, da želite onemogočiti 2FA?',
|
||||
disable_2fa_instructions: 'Za onemogočanje 2FA vnesite svoje geslo.',
|
||||
documents: 'Dokumenti',
|
||||
dont_allow: 'Ne dovoli',
|
||||
download: 'Prenos',
|
||||
download_file: 'Prenesi datoteko',
|
||||
downloading: 'Prenašanje',
|
||||
email: 'E-pošta',
|
||||
email_change_confirmation_sent: 'Potrditveno e-poštno sporočilo je bilo poslano na vaš novi e-poštni naslov. Preverite svoj poštni predal in sledite navodilom za dokončanje postopka.',
|
||||
email_invalid: 'E-pošta ni veljavna.',
|
||||
@@ -122,13 +107,10 @@ const sl = {
|
||||
forgot_pass_c2a: 'Ste pozabili geslo?',
|
||||
from: 'Od',
|
||||
general: 'Splošno',
|
||||
get_a_copy_of_on_puter: 'Pridobite kopijo \'%%\' na Puter.com!',
|
||||
get_copy_link: 'Pridobi povezave kopije',
|
||||
home: 'Domov',
|
||||
html_document: 'HTML dokument',
|
||||
hue: 'Odtenek',
|
||||
incorrect_password: 'Napačno geslo',
|
||||
invite_link: 'Povezava za povabilo',
|
||||
item: 'element',
|
||||
items_in_trash_cannot_be_renamed: 'Tega elementa ni mogoče preimenovati, ker je v smeteh. Če želite preimenovati ta element, ga najprej povlecite iz smeti.',
|
||||
jpeg_image: 'JPEG slika',
|
||||
@@ -139,7 +121,6 @@ const sl = {
|
||||
loading: 'Nalaganje',
|
||||
log_in: 'Prijava',
|
||||
log_out: 'Odjava',
|
||||
looks_good: 'Videti je v redu!',
|
||||
manage_sessions: 'Upravljanje sej',
|
||||
modified: 'Spremenjeno',
|
||||
move: 'Premakni',
|
||||
@@ -166,7 +147,6 @@ const sl = {
|
||||
open_with: 'Odpri z',
|
||||
original_name: 'Izvirno ime',
|
||||
original_path: 'Izvirna pot',
|
||||
oss_code_and_content: 'Odprtokodna programska oprema in vsebina',
|
||||
password: 'Geslo',
|
||||
password_changed: 'Geslo je bilo spremenjeno.',
|
||||
password_recovery_rate_limit: 'Dosegli ste omejitev zahtev; počakajte nekaj minut. Da to v prihodnje preprečite, ne osvežujte strani prevečkrat.',
|
||||
@@ -178,28 +158,21 @@ const sl = {
|
||||
paste: 'Prilepi',
|
||||
paste_into_folder: 'Prilepi v mapo',
|
||||
path: 'Pot',
|
||||
personalization: 'Prilagajanje',
|
||||
pick_name_for_website: 'Izberite ime za svoje spletno mesto:',
|
||||
pictures: 'Slike',
|
||||
plural_suffix: '', // "i", "je" - masculine; "e", "i" - feminine; "a", "i" - neuter
|
||||
powered_by_puter_js: 'Poganja {{link=docs}}Puter.js{{/link}}',
|
||||
preparing: 'Priprava...',
|
||||
preparing_for_upload: 'Priprava na prenos...',
|
||||
print: 'Natisni',
|
||||
privacy: 'Zasebnost',
|
||||
proceed_to_login: 'Nadaljuj na prijavo',
|
||||
proceed_with_account_deletion: 'Nadaljuj z izbrisom računa',
|
||||
properties: 'Lastnosti',
|
||||
public: 'Javno',
|
||||
publish: 'Objavi',
|
||||
publish_as_website: 'Objavi kot spletno stran',
|
||||
publish_as_serverless_worker: 'Objavi kot Worker',
|
||||
puter_description: 'Puter je osebni oblak, ki na prvo mesto postavlja zasebnost in varno hrani vse vaše datoteke, aplikacije in igre, do katerih lahko dostopate od koder koli in kadar koli.',
|
||||
reading: 'Branje %strong%',
|
||||
writing: 'Pisanje %strong%',
|
||||
recover_password: 'Obnovi geslo',
|
||||
refer_friends_c2a: 'Pridobite 1 GB za vsakega prijatelja, ki na Puterju ustvari in potrdi račun. Tudi vaš prijatelj dobi 1 GB!',
|
||||
refer_friends_social_media_c2a: 'Pridobite 1 GB brezplačnega prostora za shranjevanje na Puter.com!',
|
||||
refresh: 'Osveži',
|
||||
rename: 'Preimenuj',
|
||||
replace: 'Zamenjaj',
|
||||
@@ -209,11 +182,9 @@ const sl = {
|
||||
save: 'Shrani',
|
||||
saturation: 'Nasičenost',
|
||||
save_account: 'Shrani račun',
|
||||
save_account_to_get_copy_link: 'Za nadaljevanje ustvarite račun.',
|
||||
save_account_to_publish: 'Za nadaljevanje ustvarite račun.',
|
||||
save_session: 'Shrani sejo',
|
||||
save_session_c2a: 'Ustvarite račun, da shranite trenutno sejo in se izognete izgubi dela.',
|
||||
scan_qr_2fa: 'Skenirajte QR kodo z aplikacijo za preverjanje pristnosti',
|
||||
search: 'Iskanje',
|
||||
seconds: 'sekund',
|
||||
security: 'Varnost',
|
||||
@@ -231,20 +202,15 @@ const sl = {
|
||||
show_hidden: 'Prikaži skrito',
|
||||
sign_in_with_puter: 'Prijavite se s Puterjem',
|
||||
sign_up: 'Ustvari račun',
|
||||
signing_in: 'Prijavljanje…',
|
||||
size: 'Velikost',
|
||||
skip: 'Preskoči',
|
||||
something_went_wrong: 'Nekaj je šlo narobe.',
|
||||
sort_by: 'Razvrsti po',
|
||||
status: 'Stanje',
|
||||
storage_usage: 'Poraba prostora',
|
||||
storage_puter_used: 'uporabljeno s strani Puterja',
|
||||
taking_longer_than_usual: 'Traja malo dlje kot običajno. Prosimo, počakajte ...',
|
||||
terms: 'Pogoji',
|
||||
text_document: 'Besedilni dokument',
|
||||
'toolbar.enter_fullscreen': 'Preklopi celozaslonski način',
|
||||
'toolbar.github': 'GitHub',
|
||||
'toolbar.refer': 'Priporoči',
|
||||
tos_fineprint: 'S klikom na \'Ustvari brezplačen račun\' se strinjate s Puterjevimi {{link=terms}}pogoji storitve{{/link}} in {{link=privacy}}pravilnikom o zasebnosti{{/link}}.',
|
||||
transparency: 'Prosojnost',
|
||||
trash: 'Smeti',
|
||||
@@ -270,30 +236,24 @@ const sl = {
|
||||
videos: 'Videoposnetki',
|
||||
visibility: 'Vidnost',
|
||||
yes: 'Da',
|
||||
you_have_been_referred_to_puter_by_a_friend: 'Prijatelj vas je povabil na Puter!',
|
||||
zip: 'Stisni',
|
||||
sequencing: 'Razvrščanje %strong%',
|
||||
worker: 'Worker',
|
||||
zipping: 'Stiskanje %strong%',
|
||||
|
||||
// === 2FA Setup ===
|
||||
setup2fa_1_step_heading: 'Odprite aplikacijo za preverjanje pristnosti',
|
||||
setup2fa_1_instructions: `
|
||||
Uporabite lahko katero koli aplikacijo za preverjanje pristnosti, ki podpira protokol enkratnega gesla na podlagi časa (TOTP).
|
||||
Na voljo jih je veliko, če pa niste prepričani, je <a target="_blank" href="https://authy.com/download">Authy</a>
|
||||
odlična izbira za Android in iOS.
|
||||
`,
|
||||
setup2fa_2_step_heading: 'Skenirajte QR kodo',
|
||||
setup2fa_3_step_heading: 'Vnesite 6-mestno kodo',
|
||||
setup2fa_4_step_heading: 'Kopirajte svoje obnovitvene kode',
|
||||
setup2fa_4_instructions: `
|
||||
Te kode za obnovitev so edini način za dostop do računa, če izgubite telefon ali ne morete uporabljati aplikacije za preverjanje pristnosti.
|
||||
Shranite jih na varno mesto.
|
||||
`,
|
||||
setup2fa_5_step_heading: 'Potrdite nastavitev 2FA',
|
||||
setup2fa_5_confirmation_1: 'Moje obnovitvene kode so shranjene na varno mesto',
|
||||
setup2fa_5_confirmation_2: 'Pripravljen/a sem omogočiti 2FA',
|
||||
setup2fa_5_button: 'Omogoči 2FA',
|
||||
|
||||
// === 2FA Login ===
|
||||
login2fa_otp_title: 'Vnesite kodo 2FA',
|
||||
@@ -301,7 +261,6 @@ Shranite jih na varno mesto.
|
||||
login2fa_recovery_title: 'Vnesite kodo za obnovitev',
|
||||
login2fa_recovery_instructions: 'Za dostop do računa vnesite eno od svojih obnovitvenih kod.',
|
||||
login2fa_use_recovery_code: 'Uporabi obnovitveno kodo',
|
||||
login2fa_recovery_back: 'Nazaj',
|
||||
login2fa_recovery_placeholder: 'XXXXXXXX',
|
||||
|
||||
// Sharing
|
||||
@@ -363,7 +322,6 @@ Shranite jih na varno mesto.
|
||||
'billing.expanded': 'Razširjeno',
|
||||
'billing.accelerated': 'Pospešeno',
|
||||
'billing.enjoy_msg': 'Izkoristite %% shrambe v oblaku in druge ugodnosti.',
|
||||
'too_many_attempts': 'Preveč poskusov. Poskusite znova pozneje.',
|
||||
'server_timeout': 'Strežnik je potreboval predolgo za odgovor. Poskusite znova.',
|
||||
'signup_error': 'Med prijavo je prišlo do napake. Poskusite znova.',
|
||||
|
||||
@@ -391,18 +349,13 @@ Shranite jih na varno mesto.
|
||||
'window_title_open': 'Odpri',
|
||||
'window_title_change_password': 'Spremeni geslo',
|
||||
'window_title_select_font': 'Izberi pisavo…',
|
||||
'window_title_session_list': 'Seznam sej!',
|
||||
'window_title_set_new_password': 'Nastavite novo geslo',
|
||||
'window_title_publish_website': 'Objavite spletno stran',
|
||||
'window_title_publish_worker': 'Objavite Workerja',
|
||||
'window_title_authenticating': 'Preverjanje pristnosti ...',
|
||||
'window_title_refer_friend': 'Priporoči prijatelju!',
|
||||
|
||||
// Desktop UI
|
||||
'desktop_exit_full_screen': 'Izhod iz celozaslonskega načina',
|
||||
'desktop_enter_full_screen': 'Preklopi na celozaslonski način',
|
||||
// Item UI
|
||||
'item_shared_with_you': 'Uporabnik je ta element delil z vami.',
|
||||
'item_shared_by_you': 'Ta element ste delili z vsaj enim drugim uporabnikom.',
|
||||
'item_shortcut': 'Bližnjica',
|
||||
'item_associated_websites': 'Povezano spletno mesto',
|
||||
@@ -413,9 +366,6 @@ Shranite jih na varno mesto.
|
||||
'window_click_to_go_back': 'Kliknite za nazaj',
|
||||
'window_click_to_go_forward': 'Kliknite za naprej',
|
||||
'window_click_to_go_up': 'Kliknite za prehod za en imenik navzgor.',
|
||||
'window_title_public': 'Javno',
|
||||
'window_title_videos': 'Videoposnetki',
|
||||
'window_title_pictures': 'Slike',
|
||||
'window_title_puter': 'Puter',
|
||||
'window_folder_empty': 'Ta mapa je prazna',
|
||||
|
||||
|
||||
@@ -31,7 +31,6 @@ const sv = {
|
||||
allow: 'Tillåt',
|
||||
ascending: 'Stigande',
|
||||
associated_websites: 'Anknytande webbplatser',
|
||||
auto_arrange: 'Auto Arrange',
|
||||
cancel: 'Avbryt',
|
||||
change_email: 'Ändra e-postadress',
|
||||
change_language: 'Ändra språk',
|
||||
@@ -41,17 +40,10 @@ const sv = {
|
||||
close_all_windows_and_log_out: 'Stäng alla fönster och logga ut',
|
||||
change_always_open_with: 'Vill du alltid öppna den här filtypen med',
|
||||
confirm: 'Bekräfta',
|
||||
confirm_2fa_setup: 'Jag har lagt in koden i min autentiseringsapp',
|
||||
confirm_2fa_recovery: 'Jag har sparat mina återställningskoder på en säker plats',
|
||||
confirm_account_for_free_referral_storage_c2a: 'Skapa ett konto och bekräfta din e-postadress för att få 1 GB gratis lagringsutrymme. Din vän får också 1 GB gratis lagringsutrymme.',
|
||||
confirm_code_generic_incorrect: 'Felaktig kod.',
|
||||
confirm_code_generic_too_many_requests: 'För många förfrågningar. Var god vänta ett par minuter.',
|
||||
confirm_code_generic_submit: 'Skicka in kod',
|
||||
confirm_code_generic_try_again: 'Försök igen',
|
||||
confirm_code_generic_title: 'Fyll i bekräftelsekod',
|
||||
confirm_code_2fa_instruction: 'Fyll i de 6 siffrorna från din autentiseringsapp.',
|
||||
confirm_code_2fa_submit_btn: 'Skicka in',
|
||||
confirm_code_2fa_title: 'Fyll i 2FA-kod',
|
||||
confirm_delete_multiple_items: 'Är det säkert att du vill ta bort de här objekten permanent?',
|
||||
confirm_delete_single_item: 'Vill du ta bort det här objektet?',
|
||||
confirm_open_apps_log_out: 'Du har öppna applikationer. Är det säkert att du vill logga ut?',
|
||||
@@ -61,7 +53,6 @@ const sv = {
|
||||
confirm_session_revoke: 'Är det säkert att du vill upphäva den här sessionen?',
|
||||
confirm_your_email_address: 'Bekräfta din e-postadress',
|
||||
contact_us: 'Kontakta oss',
|
||||
contact_us_verification_required: 'Du behöver en verifierad e-postadress för att använda den här funktionen.',
|
||||
continue: 'Continue',
|
||||
copy: 'Kopiera',
|
||||
copy_link: 'Kopiera länk',
|
||||
@@ -83,17 +74,13 @@ const sv = {
|
||||
deploy_as_app: 'Distribuera som app',
|
||||
descending: 'Fallande',
|
||||
desktop: 'Skrivbord',
|
||||
desktop_background_fit: 'Anpassa',
|
||||
developers: 'Utvecklare',
|
||||
dir_published_as_website: '%strong% är publicerat på:',
|
||||
disable_2fa: 'Stäng av 2FA',
|
||||
disable_2fa_confirm: 'Är det säkert att du vill stänga av 2FA?',
|
||||
disable_2fa_instructions: 'Fyll i ditt lösenord för att stänga av 2FA.',
|
||||
documents: 'Dokument',
|
||||
dont_allow: 'Tillåt inte',
|
||||
download: 'Ladda ner',
|
||||
download_file: 'Ladda ner fil',
|
||||
downloading: 'Laddar ner',
|
||||
email: 'E-post',
|
||||
email_change_confirmation_sent: 'Ett bekräftelsemail har skickats till din nya e-postadress. Var god kontrollera inkorgen och följ instruktionerna för att fullfölja processen.',
|
||||
email_invalid: 'Adressen är ogiltig.',
|
||||
@@ -118,13 +105,10 @@ const sv = {
|
||||
forgot_pass_c2a: 'Glömt lösenord?',
|
||||
from: 'Från',
|
||||
general: 'Allmänt',
|
||||
get_a_copy_of_on_puter: "Få en kopia av '%%' på Puter.com!",
|
||||
get_copy_link: 'Få kopieringslänk',
|
||||
home: 'Hem',
|
||||
html_document: 'HTML-dokument',
|
||||
hue: 'Färgton',
|
||||
incorrect_password: 'Felaktigt lösenord',
|
||||
invite_link: 'Länk för inbjudan',
|
||||
item: 'Objekt',
|
||||
items_in_trash_cannot_be_renamed: 'Det här objektet kan inte byta namn eftersom det är i papperskorgen. För att byta namn på detta objekt, dra det först ur papperskorgen.',
|
||||
jpeg_image: 'JPEG-bild',
|
||||
@@ -135,7 +119,6 @@ const sv = {
|
||||
loading: 'Laddar',
|
||||
log_in: 'Logga in',
|
||||
log_out: 'Logga ut',
|
||||
looks_good: 'Ser bra ut!',
|
||||
manage_sessions: 'Hantera sessioner',
|
||||
modified: 'Ändrad',
|
||||
move: 'Flytta',
|
||||
@@ -160,7 +143,6 @@ const sv = {
|
||||
open_with: 'Öppna med',
|
||||
original_name: 'Utsprungligt namn',
|
||||
original_path: 'Utsprunglig filväg',
|
||||
oss_code_and_content: 'Öppen mjukvara och innehåll',
|
||||
password: 'Lösenord',
|
||||
password_changed: 'Lösenord ändrat.',
|
||||
password_recovery_rate_limit: 'Du har uppnått vår hastighetsgräns; var god vänta ett par minuter. För att motverka detta i framtiden, undvik att ladda om sidan för många gånger.',
|
||||
@@ -172,26 +154,19 @@ const sv = {
|
||||
paste: 'Klistra in',
|
||||
paste_into_folder: 'Klistra in i mapp',
|
||||
path: 'Filväg',
|
||||
personalization: 'Personalisering',
|
||||
pick_name_for_website: 'Välj ett namn för din webbplats:',
|
||||
pictures: 'Bilder',
|
||||
plural_suffix: '', // neutrum has "", utrum has "or", "ar", "er"
|
||||
powered_by_puter_js: 'Drivs av {{link=docs}}Puter.js{{/link}}',
|
||||
preparing: 'Förbereder...',
|
||||
preparing_for_upload: 'Förbereder för uppladdning...',
|
||||
print: 'Skriv ut',
|
||||
privacy: 'Integritet',
|
||||
proceed_to_login: 'Förtsätt till inloggning',
|
||||
proceed_with_account_deletion: 'Försätt med kontoborttagning',
|
||||
properties: 'Egenskaper',
|
||||
public: 'Offentligt',
|
||||
publish: 'Publicera',
|
||||
publish_as_website: 'Publicera som webbplats',
|
||||
puter_description: 'Puter är ett integritetsvänligt personligt moln för alla dina filer, appar och spel på ett säkert ställe, tillgängligt varsomhelst och närsomhelst.',
|
||||
reading_file: 'Läser in %strong%',
|
||||
recover_password: 'Återställ lösenord',
|
||||
refer_friends_c2a: 'Få 1 GB för varje vän som skapar och bekräftar ett konto på Puter. Din vän får också 1 GB.',
|
||||
refer_friends_social_media_c2a: 'Få 1 GB gratis lagringsutrymme på Puter.com!',
|
||||
refresh: 'Uppdatera',
|
||||
rename: 'Byt namn',
|
||||
replace: 'Ersätt',
|
||||
@@ -201,11 +176,9 @@ const sv = {
|
||||
save: 'Spara',
|
||||
saturation: 'Mättnad',
|
||||
save_account: 'Spara konto',
|
||||
save_account_to_get_copy_link: 'Vänligen skapa ett konto för att fortsätta.',
|
||||
save_account_to_publish: 'Vänligen skapa ett konto för att fortsätta.',
|
||||
save_session: 'Spara sessionen',
|
||||
save_session_c2a: 'Skapa ett konto för att spara den nuvarande sessionen och undvika att ditt arbete går förlorat.',
|
||||
scan_qr_2fa: 'Skanna QR-koden med din autentiseringsapp',
|
||||
search: 'Sök',
|
||||
seconds: 'sekunder',
|
||||
security: 'Säkerhet',
|
||||
@@ -223,13 +196,11 @@ const sv = {
|
||||
show_hidden: 'Visa dolda',
|
||||
sign_in_with_puter: 'Logga in med Puter',
|
||||
sign_up: 'Skapa konto',
|
||||
signing_in: 'Loggar in…',
|
||||
size: 'Storlek',
|
||||
skip: 'Hoppa över',
|
||||
something_went_wrong: 'Någonting gick fel.',
|
||||
sort_by: 'Sortera efter',
|
||||
status: 'Tillstånd',
|
||||
storage_usage: 'Användning av lagringsutrymme',
|
||||
storage_puter_used: 'använt av Puter',
|
||||
taking_longer_than_usual: 'Detta tar längre tid än vanligt. Vänligen vänta...',
|
||||
terms: 'Villkor',
|
||||
@@ -257,29 +228,23 @@ const sv = {
|
||||
videos: 'Videor',
|
||||
visibility: 'Synlighet',
|
||||
yes: 'Ja',
|
||||
you_have_been_referred_to_puter_by_a_friend: 'Du har blivit hänvisad till Puter av en vän!',
|
||||
zip: 'Zippa',
|
||||
zipping_file: 'Komprimerar %strong%',
|
||||
|
||||
// === 2FA Setup ===
|
||||
setup2fa_1_step_heading: 'Öppna din autentiseringsapp',
|
||||
setup2fa_1_instructions: `
|
||||
Du kan använda godtycklig autentiseringsapp som stöder Time-based One-Time Password (TOTP)-protokollet.
|
||||
Det finns många att välja bland, men om du är osäker så är
|
||||
<a target="_blank" href="https://authy.com/download">Authy</a>
|
||||
ett stabilt val för Android och iOS.
|
||||
`,
|
||||
setup2fa_2_step_heading: 'Skanna QR-kod',
|
||||
setup2fa_3_step_heading: 'Fyll i koden om 6 siffror',
|
||||
setup2fa_4_step_heading: 'Kopiera dina återställningskoder',
|
||||
setup2fa_4_instructions: `
|
||||
De här återställningskoderna är det enda sättet att komma åt ditt konto om du skulle tappa bort din telefon eller inte kan använda din autentiseringsapp.
|
||||
Försäkra dig om att du förvarar dem på en säker plats.
|
||||
`,
|
||||
setup2fa_5_step_heading: 'Bekräfta 2FA-installationen',
|
||||
setup2fa_5_confirmation_1: 'Jag har sparat mina återställningskoder på en säker plats',
|
||||
setup2fa_5_confirmation_2: 'Jag är redo att aktivera 2FA',
|
||||
setup2fa_5_button: 'Aktivera 2FA',
|
||||
|
||||
// === 2FA Login ===
|
||||
login2fa_otp_title: 'Fyll i 2FA-kod',
|
||||
@@ -287,7 +252,6 @@ const sv = {
|
||||
login2fa_recovery_title: 'Fyll i en återhämtningskod',
|
||||
login2fa_recovery_instructions: 'Fyll i en av dina återhämtningskoder för att få tillgång till ditt konto.',
|
||||
login2fa_use_recovery_code: 'Använd en återhämtningskod',
|
||||
login2fa_recovery_back: 'Tillbaka',
|
||||
login2fa_recovery_placeholder: 'XXXXXXXX',
|
||||
|
||||
'change': 'Ändra', // In English: "Change"
|
||||
@@ -354,21 +318,14 @@ const sv = {
|
||||
'billing.expanded': 'Utökad', // In English: "Expanded"
|
||||
'billing.accelerated': 'Accelererad', // In English: "Accelerated"
|
||||
'billing.enjoy_msg': 'Njut av %% av Cloud Storage plus andra förmåner.', // In English: "Enjoy %% of Cloud Storage plus other benefits."
|
||||
'choose_publishing_option': 'Välj hur du vill publicera din webbplats:', // In English: "Choose how you want to publish your website:"
|
||||
'create_desktop_shortcut': 'Skapa genväg (skrivbord)', // In English: "Create Shortcut (Desktop)"
|
||||
'create_desktop_shortcut_s': 'Skapa genvägar (skrivbord)', // In English: "Create Shortcuts (Desktop)"
|
||||
'create_shortcut_s': 'Skapa genvägar', // In English: "Create Shortcuts"
|
||||
'minimize': 'Minimera', // In English: "Minimize"
|
||||
'reload_app': 'Ladda om app', // In English: "Reload App"
|
||||
'plural_suffix': 'ar', // In English: "s"
|
||||
'publish_as_serverless_worker': 'Publicera som Worker', // In English: "Publish as Worker"
|
||||
'toolbar.enter_fullscreen': 'Aktivera helskärm', // In English: "Enter Full Screen"
|
||||
'toolbar.github': 'GitHub', // In English: "GitHub"
|
||||
'toolbar.refer': 'Rekommendera', // In English: "Refer"
|
||||
'used_of': '{{used}} använt av {{available}}', // In English: "{{used}} used of {{available}}"
|
||||
'worker': 'Worker', // In English: "Worker"
|
||||
'billing.offering.basic': 'Bas', // In English: "Basic"
|
||||
'too_many_attempts': 'För många försök. Försök igen senare.', // In English: "Too many attempts. Please try again later."
|
||||
'server_timeout': 'Servern tog för lång tid att svara. Försök igen.', // In English: "The server took too long to respond. Please try again."
|
||||
'signup_error': 'Ett fel uppstod vid registreringen. Försök igen.', // In English: "An error occurred during signup. Please try again."
|
||||
'alert_error_title': 'Fel!', // In English: "Error!"
|
||||
@@ -386,15 +343,10 @@ const sv = {
|
||||
'window_title_open': 'Öppna', // In English: "Open"
|
||||
'window_title_change_password': 'Ändra lösenord', // In English: "Change Password"
|
||||
'window_title_select_font': 'Välj typsnitt…', // In English: "Select font…"
|
||||
'window_title_session_list': 'Sessionslista!', // In English: "Session List!"
|
||||
'window_title_set_new_password': 'Ange nytt lösenord', // In English: "Set New Password"
|
||||
'window_title_publish_website': 'Publicera webbplats', // In English: "Publish Website"
|
||||
'window_title_publish_worker': 'Publicera Worker', // In English: "Publish Worker"
|
||||
'window_title_authenticating': 'Autentiserar...', // In English: "Authenticating..."
|
||||
'window_title_refer_friend': 'Rekommendera en vän!', // In English: "Refer a friend!"
|
||||
'desktop_exit_full_screen': 'Avsluta helskärm', // In English: "Exit Full Screen"
|
||||
'desktop_enter_full_screen': 'Aktivera helskärm', // In English: "Enter Full Screen"
|
||||
'item_shared_with_you': 'En användare har delat detta objekt med dig.', // In English: "A user has shared this item with you."
|
||||
'item_shared_by_you': 'Du har delat detta objekt med minst en annan användare.', // In English: "You have shared this item with at least one other user."
|
||||
'item_shortcut': 'Genväg', // In English: "Shortcut"
|
||||
'item_associated_websites': 'Associerad webbplats', // In English: "Associated website"
|
||||
@@ -403,9 +355,6 @@ const sv = {
|
||||
'window_click_to_go_back': 'Klicka för att gå tillbaka.', // In English: "Click to go back."
|
||||
'window_click_to_go_forward': 'Klicka för att gå framåt.', // In English: "Click to go forward."
|
||||
'window_click_to_go_up': 'Klicka för att gå upp en katalog.', // In English: "Click to go one directory up."
|
||||
'window_title_public': 'Offentligt', // In English: "Public"
|
||||
'window_title_videos': 'Videor', // In English: "Videos"
|
||||
'window_title_pictures': 'Bilder', // In English: "Pictures"
|
||||
'window_title_puter': 'Puter', // In English: "Puter"
|
||||
'window_folder_empty': 'Denna mapp är tom', // In English: "This folder is empty"
|
||||
|
||||
|
||||
@@ -31,7 +31,6 @@ const ta = {
|
||||
allow: 'அனுமதி',
|
||||
ascending: 'ஏறுமுகம்',
|
||||
associated_websites: 'தொடர்புடைய இணையதளங்கள்',
|
||||
auto_arrange: 'ஆட்டோ ஏற்பாடு',
|
||||
cancel: 'ரத்து செய்',
|
||||
change_email: 'மின்னஞ்சலை மாற்றவும்',
|
||||
change_language: 'மொழியை மாற்றவும்',
|
||||
@@ -41,22 +40,13 @@ const ta = {
|
||||
close_all_windows_and_log_out: 'விண்டோஸை மூடிவிட்டு வெளியேறவும்',
|
||||
change_always_open_with:
|
||||
'இந்த வகையான கோப்பை எப்போதும் திறக்க விரும்புகிறீர்களா?',
|
||||
confirm_2fa_setup:
|
||||
'எனது அங்கீகரிப்பு பயன்பாட்டில் குறியீட்டைச் சேர்த்துள்ளேன்',
|
||||
confirm_2fa_recovery:
|
||||
'எனது மீட்புக் குறியீடுகளை பாதுகாப்பான இடத்தில் சேமித்துள்ளேன்',
|
||||
confirm_account_for_free_referral_storage_c2a:
|
||||
'1 ஜிபி இலவச சேமிப்பிடத்தைப் பெற, கணக்கை உருவாக்கி உங்கள் மின்னஞ்சல் முகவரியை உறுதிப்படுத்தவும். உங்கள் நண்பருக்கு 1 ஜிபி இலவச சேமிப்பகமும் கிடைக்கும்.',
|
||||
confirm_code_generic_incorrect: 'தவறான குறியீடு.',
|
||||
confirm_code_generic_too_many_requests:
|
||||
'பல கோரிக்கைகள். தயவுசெய்து சில நிமிடங்கள் காத்திருக்கவும்.',
|
||||
confirm_code_generic_submit: 'குறியீட்டை சமர்ப்பிக்கவும்',
|
||||
confirm_code_generic_try_again: 'மீண்டும் முயற்சி செய்யவும்',
|
||||
confirm_code_generic_title: 'உறுதிப்படுத்தல் குறியீட்டை உள்ளிடவும்',
|
||||
confirm_code_2fa_instruction:
|
||||
'உங்கள் அங்கீகரிப்பு பயன்பாட்டிலிருந்து 6 இலக்கக் குறியீட்டை உள்ளிடவும்.',
|
||||
confirm_code_2fa_submit_btn: 'சமர்ப்பிக்கவும்',
|
||||
confirm_code_2fa_title: '2FA குறியீட்டை உள்ளிடவும்',
|
||||
confirm_delete_multiple_items:
|
||||
'இந்த உருப்படிகளை நிரந்தரமாக நீக்க விரும்புகிறீர்களா?',
|
||||
confirm_delete_single_item:
|
||||
@@ -70,8 +60,6 @@ const ta = {
|
||||
confirm_session_revoke: 'இந்த அமர்வை நிச்சயமாக திரும்பப் பெற விரும்புகிறீர்களா?',
|
||||
confirm_your_email_address: 'உங்கள் மின்னஞ்சல் முகவரியை உறுதிப்படுத்தவும்',
|
||||
contact_us: 'எங்களை தொடர்பு கொள்ள',
|
||||
contact_us_verification_required:
|
||||
'இதைப் பயன்படுத்த, சரிபார்க்கப்பட்ட மின்னஞ்சல் முகவரி உங்களிடம் இருக்க வேண்டும்.',
|
||||
continue: 'தொடரவும்',
|
||||
copy: 'நகலெடுக்கவும்',
|
||||
copy_link: 'இணைப்பை நகலெடுக்கவும்',
|
||||
@@ -93,17 +81,13 @@ const ta = {
|
||||
deploy_as_app: 'பயன்பாடாக வரிசைப்படுத்து',
|
||||
descending: 'இறங்குதல்',
|
||||
desktop: 'டெஸ்க்டாப்',
|
||||
desktop_background_fit: 'பொருத்தம்',
|
||||
developers: 'டெவலப்பர்கள்',
|
||||
dir_published_as_website: '%strong% வெளியிடப்பட்டது:',
|
||||
disable_2fa: '2FA ஐ முடக்கு',
|
||||
disable_2fa_confirm: '2FA ஐ நிச்சயமாக முடக்க விரும்புகிறீர்களா?',
|
||||
disable_2fa_instructions: '2FA ஐ முடக்க உங்கள் கடவுச்சொல்லை உள்ளிடவும்.',
|
||||
documents: 'ஆவணங்கள்',
|
||||
dont_allow: 'அனுமதிக்காதே',
|
||||
download: 'பதிவிறக்கவும்',
|
||||
download_file: 'பதிவிறக்க கோப்பு',
|
||||
downloading: 'பதிவிறக்கிறது',
|
||||
email: 'மின்னஞ்சல்',
|
||||
email_change_confirmation_sent:
|
||||
'உங்கள் புதிய மின்னஞ்சல் முகவரிக்கு உறுதிப்படுத்தல் மின்னஞ்சல் அனுப்பப்பட்டுள்ளது. செயல்முறையை முடிக்க உங்கள் இன்பாக்ஸைச் சரிபார்த்து, வழிமுறைகளைப் பின்பற்றவும்.',
|
||||
@@ -133,13 +117,10 @@ const ta = {
|
||||
forgot_pass_c2a: 'கடவுச்சொல்லை மறந்துவிட்டீர்களா?',
|
||||
from: 'இருந்து',
|
||||
general: 'பொது',
|
||||
get_a_copy_of_on_puter: 'Puter.com இல் \'%%\' நகலைப் பெறுங்கள்!',
|
||||
get_copy_link: 'நகல் இணைப்பைப் பெறவும்',
|
||||
home: 'வீடு',
|
||||
html_document: 'HTML ஆவணம்',
|
||||
hue: 'சாயல்',
|
||||
incorrect_password: 'தவறான கடவுச்சொல்',
|
||||
invite_link: 'அழைப்பு இணைப்பு',
|
||||
item: 'பொருள்',
|
||||
items_in_trash_cannot_be_renamed:
|
||||
'இந்த உருப்படி குப்பையில் இருப்பதால் மறுபெயரிட முடியாது. இந்த உருப்படியை மறுபெயரிட, முதலில் அதை குப்பையிலிருந்து வெளியே இழுக்கவும்.',
|
||||
@@ -151,7 +132,6 @@ const ta = {
|
||||
loading: 'ஏற்றுகிறது',
|
||||
log_in: 'உள்நுழைய',
|
||||
log_out: 'வெளியேறு',
|
||||
looks_good: 'நன்றாக இருக்கிறது!',
|
||||
manage_sessions: 'அமர்வுகளை நிர்வகிக்கவும்',
|
||||
modified: 'மாற்றியமைக்கப்பட்டது',
|
||||
move: 'நகர்வு',
|
||||
@@ -176,7 +156,6 @@ const ta = {
|
||||
open_with: 'உடன் திற',
|
||||
original_name: 'அசல் பெயர்',
|
||||
original_path: 'அசல் பாதை',
|
||||
oss_code_and_content: 'திறந்த மூல மென்பொருள் மற்றும் உள்ளடக்கம்',
|
||||
password: 'கடவுச்சொல்',
|
||||
password_changed: 'கடவுச்சொல் மாற்றப்பட்டது.',
|
||||
password_recovery_rate_limit:
|
||||
@@ -193,29 +172,20 @@ const ta = {
|
||||
paste: 'ஒட்டவும்',
|
||||
paste_into_folder: 'கோப்புறையில் ஒட்டவும்',
|
||||
path: 'பாதை',
|
||||
personalization: 'தனிப்பயனாக்கம்',
|
||||
pick_name_for_website: 'உங்கள் வலைத்தளத்திற்கு ஒரு பெயரைத் தேர்ந்தெடுக்கவும்:',
|
||||
pictures: 'படங்கள்',
|
||||
plural_suffix: 'கள்',
|
||||
powered_by_puter_js: 'மூலம் இயக்கப்படுகிறது {{link=docs}}Puter.js{{/link}}',
|
||||
preparing: 'தயாராகிறது...',
|
||||
preparing_for_upload: 'பதிவேற்றம் செய்ய தயாராகிறது...',
|
||||
print: 'அச்சிடுக',
|
||||
privacy: 'தனியுரிமை',
|
||||
proceed_to_login: 'உள்நுழைய தொடரவும்',
|
||||
proceed_with_account_deletion: 'கணக்கு நீக்குதலைத் தொடரவும்',
|
||||
properties: 'பண்புகள்',
|
||||
public: 'பொது',
|
||||
publish: 'வெளியிடு',
|
||||
publish_as_website: 'இணையதளமாக வெளியிடவும்',
|
||||
puter_description:
|
||||
'உங்கள் கோப்புகள், பயன்பாடுகள் மற்றும் கேம்கள் அனைத்தையும் ஒரே பாதுகாப்பான இடத்தில் வைத்திருக்க, எந்த நேரத்திலும் எங்கிருந்தும் அணுகக்கூடிய தனியுரிமை-முதல் தனிப்பட்ட கிளவுட் புட்டர் ஆகும்.',
|
||||
reading_file: 'படித்தல் %strong%',
|
||||
recover_password: 'கடவுச்சொல்லை மீட்டெடுக்கவும்',
|
||||
refer_friends_c2a:
|
||||
'புட்டர் இல் கணக்கை உருவாக்கி உறுதிப்படுத்தும் ஒவ்வொரு நண்பருக்கும் 1 GB கிடைக்கும். உங்கள் நண்பருக்கும் 1 ஜிபி கிடைக்கும்!',
|
||||
refer_friends_social_media_c2a:
|
||||
'Puter.com இல் 1 GB இலவச சேமிப்பிடத்தைப் பெறுங்கள்!',
|
||||
refresh: 'புதுப்பிப்பு',
|
||||
rename: 'மறுபெயரிடவும்',
|
||||
replace: 'மாற்றவும்',
|
||||
@@ -225,13 +195,10 @@ const ta = {
|
||||
save: 'சேமிக்கவும்',
|
||||
saturation: 'செறிவூட்டல்',
|
||||
save_account: 'கணக்கைச் சேமிக்கவும்',
|
||||
save_account_to_get_copy_link: 'தொடர ஒரு கணக்கை உருவாக்கவும்.',
|
||||
save_account_to_publish: 'தொடர ஒரு கணக்கை உருவாக்கவும்.',
|
||||
save_session: 'அமர்வை சேமிக்கவும்',
|
||||
save_session_c2a:
|
||||
'உங்கள் தற்போதைய அமர்வைச் சேமிக்க ஒரு கணக்கை உருவாக்கவும் மற்றும் உங்கள் வேலையை இழப்பதைத் தவிர்க்கவும்.',
|
||||
scan_qr_2fa:
|
||||
'உங்கள் அங்கீகரிப்பு பயன்பாட்டின் மூலம் QR குறியீட்டை ஸ்கேன் செய்யவும்',
|
||||
search: 'தேடு',
|
||||
seconds: 'வினாடிகள்',
|
||||
security: 'பாதுகாப்பு',
|
||||
@@ -250,13 +217,11 @@ const ta = {
|
||||
show_hidden: 'மறைக்கப்பட்டதைக் காட்டு',
|
||||
sign_in_with_puter: 'புட்டர் மூலம் உள்நுழையவும்',
|
||||
sign_up: 'பதிவு செய்யவும்',
|
||||
signing_in: 'உள்நுழைகிறேன்…',
|
||||
size: 'அளவு',
|
||||
skip: 'தவிர்க்கவும்',
|
||||
something_went_wrong: 'ஏதோ தவறு நடந்துவிட்டது.',
|
||||
sort_by: 'வரிசைப்படுத்து',
|
||||
status: 'நிலை',
|
||||
storage_usage: 'சேமிப்பக பயன்பாடு',
|
||||
storage_puter_used: 'புட்டரால் பயன்படுத்தப்பட்டது',
|
||||
taking_longer_than_usual:
|
||||
'வழக்கத்தை விட சிறிது நேரம் எடுக்கும். தயவுசெய்து காத்திருங்கள்...',
|
||||
@@ -287,31 +252,24 @@ const ta = {
|
||||
videos: 'வீடியோக்கள்',
|
||||
visibility: 'தெரிவுநிலை',
|
||||
yes: 'ஆம்',
|
||||
you_have_been_referred_to_puter_by_a_friend:
|
||||
'நீங்கள் ஒரு நண்பரால் புட்டருக்கு பரிந்துரைக்கப்பட்டீர்கள்!',
|
||||
zip: 'ஜிப்',
|
||||
zipping_file: 'ஜிப்பிங் %strong%',
|
||||
|
||||
// === 2FA Setup ===
|
||||
setup2fa_1_step_heading: 'உங்கள் அங்கீகரிப்பு பயன்பாட்டைத் திறக்கவும்',
|
||||
setup2fa_1_instructions: `
|
||||
Time-based One-Time Password (TOTP) நெறிமுறையை ஆதரிக்கும் எந்த அங்கீகார பயன்பாட்டையும் நீங்கள் பயன்படுத்தலாம்.
|
||||
தேர்வு செய்ய பல உள்ளன, ஆனால் நீங்கள் உறுதியாக தெரியவில்லை என்றால்
|
||||
<a target="_blank" href="https://authy.com/download">Authy</a>
|
||||
ஆண்ட்ராய்டு மற்றும் iOSக்கு ஒரு திடமான தேர்வாகும்.
|
||||
`,
|
||||
setup2fa_2_step_heading: 'QR குறியீட்டை ஸ்கேன் செய்யவும்',
|
||||
setup2fa_3_step_heading: '6 இலக்கக் குறியீட்டை உள்ளிடவும்',
|
||||
setup2fa_4_step_heading: 'உங்கள் மீட்பு குறியீடுகளை நகலெடுக்கவும்',
|
||||
setup2fa_4_instructions: `
|
||||
உங்கள் ஃபோனை இழந்தாலோ அல்லது அங்கீகரிப்பு பயன்பாட்டைப் பயன்படுத்த முடியாமலோ உங்கள் கணக்கை அணுக இந்த மீட்புக் குறியீடுகள் மட்டுமே ஒரே வழி.
|
||||
அவற்றை பாதுகாப்பான இடத்தில் சேமித்து வைப்பதை உறுதி செய்யவும்.
|
||||
`,
|
||||
setup2fa_5_step_heading: '2FA அமைப்பை உறுதிப்படுத்தவும்',
|
||||
setup2fa_5_confirmation_1:
|
||||
'எனது மீட்புக் குறியீடுகளை பாதுகாப்பான இடத்தில் சேமித்துள்ளேன்',
|
||||
setup2fa_5_confirmation_2: '2FA ஐ இயக்க நான் தயாராக இருக்கிறேன்',
|
||||
setup2fa_5_button: '2FA ஐ இயக்கவும்',
|
||||
|
||||
// === 2FA Login ===
|
||||
login2fa_otp_title: '2FA குறியீட்டை உள்ளிடவும்',
|
||||
@@ -321,7 +279,6 @@ const ta = {
|
||||
login2fa_recovery_instructions:
|
||||
'உங்கள் கணக்கை அணுக, உங்கள் மீட்புக் குறியீடுகளில் ஒன்றை உள்ளிடவும்.',
|
||||
login2fa_use_recovery_code: 'மீட்புக் குறியீட்டைப் பயன்படுத்தவும்',
|
||||
login2fa_recovery_back: 'மீண்டும்',
|
||||
login2fa_recovery_placeholder: 'XXXXXXXX',
|
||||
|
||||
change: 'மாற்றம்',
|
||||
@@ -401,21 +358,13 @@ const ta = {
|
||||
// =============================================================
|
||||
// Completed missing translations
|
||||
// =============================================================
|
||||
choose_publishing_option:
|
||||
'உங்கள் வலைத்தளத்தை எப்படி வெளியிட வேண்டும் என்பதைத் தேர்வுசெய்க:',
|
||||
create_desktop_shortcut: 'குறுக்குவழி உருவாக்கு (டெஸ்க்டாப்)',
|
||||
create_desktop_shortcut_s: 'குறுக்குவழிகள் உருவாக்கு (டெஸ்க்டாப்)',
|
||||
create_shortcut_s: 'குறுக்குவழிகள் உருவாக்கு',
|
||||
minimize: 'சுருக்கு',
|
||||
reload_app: 'பயன்பாட்டை மீளேற்று',
|
||||
publish_as_serverless_worker: 'வொர்க்கராக வெளியிடு',
|
||||
'toolbar.enter_fullscreen': 'முழுத்திரைக்கு செல்',
|
||||
'toolbar.github': 'GitHub',
|
||||
'toolbar.refer': 'அறிமுகப்படுத்து',
|
||||
used_of: '{{available}} இல் {{used}} பயன்படுத்தப்பட்டது',
|
||||
worker: 'வொர்க்கர்',
|
||||
'billing.offering.basic': 'அடிப்படை',
|
||||
too_many_attempts: 'அதிக முயற்சிகள். தயவுசெய்து பிறகு முயற்சிக்கவும்.',
|
||||
server_timeout:
|
||||
'சர்வர் பதில் அளிக்க தாமதமாகிறது. மீண்டும் முயற்சிக்கவும்.',
|
||||
signup_error: 'பதிவின் போது பிழை ஏற்பட்டது. மீண்டும் முயற்சிக்கவும்.',
|
||||
@@ -434,16 +383,10 @@ const ta = {
|
||||
window_title_open: 'திற',
|
||||
window_title_change_password: 'கடவுச்சொல்லை மாற்று',
|
||||
window_title_select_font: 'எழுத்துருவை தேர்வுசெய்…',
|
||||
window_title_session_list: 'அமர்வுப் பட்டியல்!',
|
||||
window_title_set_new_password: 'புதிய கடவுச்சொல்லை அமை',
|
||||
window_title_publish_website: 'வலைத்தளத்தை வெளியிடு',
|
||||
window_title_publish_worker: 'வொர்க்கரை வெளியிடு',
|
||||
window_title_authenticating: 'அடையாளம் சரிபார்க்கப்படுகிறது...',
|
||||
window_title_refer_friend: 'நண்பரை அறிமுகப்படுத்து!',
|
||||
desktop_exit_full_screen: 'முழுத்திரையிலிருந்து வெளியேறு',
|
||||
desktop_enter_full_screen: 'முழுத்திரைக்கு செல்',
|
||||
item_shared_with_you:
|
||||
'ஒரு பயனர் இந்த உருப்படியை உங்களுடன் பகிர்ந்துள்ளார்.',
|
||||
item_shared_by_you:
|
||||
'இந்த உருப்படியை நீங்கள் குறைந்தது ஒருவருடன் பகிர்ந்துள்ளீர்கள்.',
|
||||
item_shortcut: 'குறுக்குவழி',
|
||||
@@ -453,9 +396,6 @@ const ta = {
|
||||
window_click_to_go_back: 'முந்தையதிற்குச் செல்ல கிளிக் செய்யவும்.',
|
||||
window_click_to_go_forward: 'அடுத்ததிற்குச் செல்ல கிளிக் செய்யவும்.',
|
||||
window_click_to_go_up: 'ஒரு அடைவுக்கு மேலே செல்ல கிளிக் செய்யவும்.',
|
||||
window_title_public: 'பொது',
|
||||
window_title_videos: 'வீடியோக்கள்',
|
||||
window_title_pictures: 'படங்கள்',
|
||||
window_title_puter: 'Puter',
|
||||
window_folder_empty: 'இந்த கோப்புறை காலியாக உள்ளது',
|
||||
},
|
||||
|
||||
@@ -31,7 +31,6 @@ const th = {
|
||||
allow: 'อนุญาต',
|
||||
ascending: 'เรียงจากน้อยไปมาก',
|
||||
associated_websites: 'เว็บไซต์ที่เกี่ยวข้อง',
|
||||
auto_arrange: 'จัดเรียงอัตโนมัติ',
|
||||
cancel: 'ยกเลิก',
|
||||
change_email: 'เปลี่ยนอีเมล',
|
||||
change_language: 'เปลี่ยนภาษา',
|
||||
@@ -40,17 +39,10 @@ const th = {
|
||||
close: 'ปิด',
|
||||
close_all_windows_and_log_out: 'ปิดหน้าต่างและออกจากระบบ',
|
||||
change_always_open_with: 'คุณต้องการเปิดไฟล์ประเภทนี้ด้วย',
|
||||
confirm_2fa_setup: 'ฉันได้เพิ่มรหัสลงไปใน authenticator แอฟของฉันแล้ว',
|
||||
confirm_2fa_recovery: 'ฉันได้เก็บรหัสกู้ในที่ปลอดภัยแล้ว',
|
||||
confirm_account_for_free_referral_storage_c2a: 'สร้างบัญชีและยืนยันที่อยู่อีเมลของคุณเพื่อรับพื้นที่จัดเก็บข้อมูลฟรี 1 GB เพื่อนของคุณจะได้รับพื้นที่จัดเก็บข้อมูลฟรี 1 GB เช่นกัน',
|
||||
confirm_code_generic_incorrect: 'รหัสไม่ถูกต้อง',
|
||||
confirm_code_generic_too_many_requests: 'ส่งรีเควสมากเกินไป กรุณารอสักสองสามนาที',
|
||||
confirm_code_generic_submit: 'ส่งรหัส',
|
||||
confirm_code_generic_try_again: 'ลองใหม่',
|
||||
confirm_code_generic_title: 'กรอกรหัสยืนยัน',
|
||||
confirm_code_2fa_instruction: 'กรอกรหัส6หลักจากใน authenticator แอฟ',
|
||||
confirm_code_2fa_submit_btn: 'ส่งข้อมูล',
|
||||
confirm_code_2fa_title: 'กรอกรหัส 2FA',
|
||||
confirm_delete_multiple_items: 'คุณแน่ใจหรือไม่ว่าต้องการลบรายการเหล่านี้อย่างถาวร?',
|
||||
confirm_delete_single_item: 'คุณต้องการลบรายการนี้อย่างถาวรหรือไม่?',
|
||||
confirm_open_apps_log_out: 'คุณมีแอปพลิเคชันที่เปิดอยู่ คุณแน่ใจหรือไม่ว่าต้องการออกจากระบบ?',
|
||||
@@ -60,7 +52,6 @@ const th = {
|
||||
confirm_session_revoke: 'คุณแน่ใจว่าเพิกถอนเซสชั่นของคุณ?',
|
||||
confirm_your_email_address: 'ยืนยันอีเมลของคุณ',
|
||||
contact_us: 'ติดต่อเรา',
|
||||
contact_us_verification_required: 'คุณต้องมีอีเมล์ที่ยืนยันแล้วเพื่อใช้งานได้',
|
||||
continue: 'ดำเนินการต่อ',
|
||||
copy: 'คัดลอก',
|
||||
copy_link: 'คัดลอกลิงก์',
|
||||
@@ -82,17 +73,13 @@ const th = {
|
||||
deploy_as_app: 'นำไปใช้เป็นแอป',
|
||||
descending: 'เรียงจากมากไปน้อย',
|
||||
desktop: 'เดสก์ท็อป',
|
||||
desktop_background_fit: 'พอดี',
|
||||
developers: 'นักพัฒนา',
|
||||
dir_published_as_website: '%strong% ได้รับการเผยแพร่ไปยัง:',
|
||||
disable_2fa: 'ปิด 2FA',
|
||||
disable_2fa_confirm: 'คุณแน่ใจว่าต้องการจะปิด 2FA?',
|
||||
disable_2fa_instructions: 'กรอกรหัสผ่านเพื่อปิด 2FA.',
|
||||
documents: 'เอกสาร',
|
||||
dont_allow: 'ไม่อนุญาต',
|
||||
download: 'ดาวน์โหลด',
|
||||
download_file: 'ดาวน์โหลดไฟล์',
|
||||
downloading: 'กำลังดาวน์โหลด',
|
||||
email: 'อีเมล',
|
||||
email_change_confirmation_sent: 'อีเมล์ยืนยันได้ถูกส่งไปที่อยู่อีเมลใหม่ของคุณแล้ว กรุณาตรวจสอบกล่องข้อความของคุณและทำตามขั้นตอนต่อจนเสร็จ',
|
||||
email_invalid: 'อีเมล์ไม่ถูกต้อง.',
|
||||
@@ -117,13 +104,10 @@ const th = {
|
||||
forgot_pass_c2a: 'ลืมรหัสผ่าน?',
|
||||
from: 'จาก',
|
||||
general: 'ทั่วไป',
|
||||
get_a_copy_of_on_puter: 'รับสำเนาของ "%%" ได้ที่ Puter.com!',
|
||||
get_copy_link: 'คัดลอกลิงก์',
|
||||
home: 'บ้าน',
|
||||
html_document: 'เอกสาร HTML',
|
||||
hue: 'สี',
|
||||
incorrect_password: 'รหัสไม่ถูกต้อง',
|
||||
invite_link: 'ลิงก์เชิญชวน',
|
||||
item: 'รายการ',
|
||||
items_in_trash_cannot_be_renamed: 'ไม่สามารถเปลี่ยนชื่อรายการนี้ได้เนื่องจากอยู่ในถังขยะ หากต้องการเปลี่ยนชื่อรายการนี้ ให้ลากออกจากถังขยะก่อน',
|
||||
jpeg_image: 'ภาพ JPEG',
|
||||
@@ -134,7 +118,6 @@ const th = {
|
||||
loading: 'กำลังโหลด',
|
||||
log_in: 'เข้าสู่ระบบ',
|
||||
log_out: 'ออกจากระบบ',
|
||||
looks_good: 'ดูดีเลย!',
|
||||
manage_sessions: 'จัดการเซสชั่น',
|
||||
modified: 'แก้ไขเเมื่อ',
|
||||
move: 'ย้าย',
|
||||
@@ -159,7 +142,6 @@ const th = {
|
||||
open_with: 'เปิดด้วย',
|
||||
original_name: 'ชื่อดั้งเดิม',
|
||||
original_path: 'ที่อยู่ดั้งเดิม',
|
||||
oss_code_and_content: 'ซอฟแวร์โอเพนซอร์สและเนื้อหา',
|
||||
password: 'รหัสผ่าน',
|
||||
password_changed: 'เปลี่ยนรหัสผ่านแล้ว',
|
||||
password_recovery_rate_limit: 'คุณได้ใช้ถึงข้อจำกัดแล้ว; กรุณารอสองสามนาที. เพื่อไม่ให้เกิดแบบนี้ในอนาคต, พยายามเลี่ยงการรีโหลดหลายๆครั้ง.',
|
||||
@@ -170,26 +152,19 @@ const th = {
|
||||
passwords_do_not_match: 'รหัสผ่านไม่ตรงกัน',
|
||||
paste: 'วาง',
|
||||
paste_into_folder: 'วางลงในโฟลเดอร์',
|
||||
personalization: 'ปรับเฉพาะบุคคล',
|
||||
pick_name_for_website: 'เลือกชื่อสำหรับเว็บไซต์ของคุณ:',
|
||||
pictures: 'รูปภาพ',
|
||||
plural_suffix: '',
|
||||
powered_by_puter_js: 'สนับสนุนโดย {{link=docs}}Puter.js{{/link}}',
|
||||
preparing: 'กำลังเตรียม...',
|
||||
preparing_for_upload: 'กำลังเตรียมสำหรับอัปโหลด...',
|
||||
print: 'พิมพ์',
|
||||
privacy: 'ความเป็นส่วนตัว',
|
||||
proceed_to_login: 'ดำเนินการเข้าสู่ระบบ',
|
||||
proceed_with_account_deletion: 'ดำเนินการลบบัญชี',
|
||||
properties: 'คุณสมบัติ',
|
||||
public: 'สาธารณะ',
|
||||
publish: 'เผยแพร่',
|
||||
publish_as_website: 'เผยแพร่เป็นเว็บไซต์',
|
||||
puter_description: 'Puter is a privacy-first personal cloud to keep all your files, apps, and games in one secure place, accessible from anywhere at any time.',
|
||||
reading_file: 'กำลังอ่าน %strong%',
|
||||
recover_password: 'กู้คืนรหัสผ่าน',
|
||||
refer_friends_c2a: 'รับพื้นที่ 1 GB สำหรับเพื่อนทุกคนที่สร้าง และยืนยันบัญชีบน Puter เพื่อนของคุณจะได้รับพื้นที่ 1 GB เช่นกัน!',
|
||||
refer_friends_social_media_c2a: 'รับพื้นที่จัดเก็บข้อมูลฟรี 1 GB บน Puter.com!',
|
||||
refresh: 'รีเฟรช',
|
||||
rename: 'เปลี่ยนชื่อ',
|
||||
replace: 'แทนที่',
|
||||
@@ -198,11 +173,9 @@ const th = {
|
||||
restore: 'คืนค่า',
|
||||
saturation: 'ความอิ่มตัว',
|
||||
save_account: 'บันทึกบัญชี',
|
||||
save_account_to_get_copy_link: 'กรุณาสร้างบัญชีเพื่อดำเนินการต่อ',
|
||||
save_account_to_publish: 'กรุณาสร้างบัญชีเพื่อดำเนินการต่อ',
|
||||
save_session: 'บันทึกเซสชัน',
|
||||
save_session_c2a: 'สร้างบัญชีเพื่อบันทึกเซสชันปัจจุบัน และป้องกันการสูญเสียข้อมูลการทำงานของคุณ',
|
||||
scan_qr_2fa: 'แสกนคิวอาร์โค้ดด้วย authenticator แอฟ',
|
||||
search: 'ค้นหา',
|
||||
seconds: 'วินาที',
|
||||
security: 'ความปลอดภัย',
|
||||
@@ -220,13 +193,11 @@ const th = {
|
||||
show_hidden: 'แสดงที่ซ่อนไว้',
|
||||
sign_in_with_puter: 'ลงชื่อเข้าใช้ด้วย Puter',
|
||||
sign_up: 'สมัครสมาชิก',
|
||||
signing_in: 'กำลังเข้าสู่ระบบ...',
|
||||
size: 'ขนาด',
|
||||
skip: 'ข้าม',
|
||||
something_went_wrong: 'บางสิ่งผิดพลาด',
|
||||
sort_by: 'จัดเรียงตาม',
|
||||
status: 'สถานะ',
|
||||
storage_usage: 'การใช้งานพื้นที่',
|
||||
storage_puter_used: 'ถูกใช้โดย Puter',
|
||||
taking_longer_than_usual: 'ใช้เวลานานกว่าปกติเล็กน้อย กรุณารอสักครู่...',
|
||||
terms: 'เงื่อนไข',
|
||||
@@ -254,29 +225,23 @@ const th = {
|
||||
videos: 'วีดีโอ',
|
||||
visibility: 'การมองเห็น',
|
||||
yes: 'ใช่',
|
||||
you_have_been_referred_to_puter_by_a_friend: 'เพื่อนของคุณได้แนะนำ Puter ให้คุณ!',
|
||||
zip: 'บีบอัด',
|
||||
zipping_file: 'กำลังบีบอัด %strong%',
|
||||
|
||||
// === 2FA Setup ===
|
||||
setup2fa_1_step_heading: 'เปิด authenticator แอฟ',
|
||||
setup2fa_1_instructions: `
|
||||
คุณสามารถใช้ authenticator แอฟ ที่รองรับ Time-based One-Time Password (TOTP)
|
||||
มีหลายๆแอฟให้เลือกใช้งาน, แต่ถ้าคุณไม่แน่ใจ
|
||||
<a target="_blank" href="https://authy.com/download">Authy</a>
|
||||
เป็นตัวเลือกที่ดีสำหรับ Android and iOS.
|
||||
`,
|
||||
setup2fa_2_step_heading: 'แสกนคิวอาร์โค้ด',
|
||||
setup2fa_3_step_heading: 'กรอกตัวเลข6หลัก',
|
||||
setup2fa_4_step_heading: 'คัดลอกรหัสกู้คืน',
|
||||
setup2fa_4_instructions: `
|
||||
รหัสกู้คืนเหล่านี้เป็นวิธีเดียวที่จะเข้าถึงบัญชีคุณกรณีไม่มีโทรศัพท์หรือเข้าถึง authenticator แอฟ
|
||||
แน่ใจว่าเก็บไว้ในที่ปลอดภัย
|
||||
`,
|
||||
setup2fa_5_step_heading: 'ยืนยันการตั้งค่า2FA',
|
||||
setup2fa_5_confirmation_1: 'ฉันได้เก็บรหัสกู้คืนไว้ในที่ปลอดภัย',
|
||||
setup2fa_5_confirmation_2: 'ฉันพร้อมที่จะเปิดการใช้งาน 2FA',
|
||||
setup2fa_5_button: 'เปิดการใช้งาน 2FA',
|
||||
|
||||
// === 2FA Login ===
|
||||
login2fa_otp_title: 'กรอกรหัส 2FA',
|
||||
@@ -284,7 +249,6 @@ const th = {
|
||||
login2fa_recovery_title: 'กรอกรหัสกู้คืน',
|
||||
login2fa_recovery_instructions: 'กรอกรหัสกู้คืนอันใดอันหนึ่งเพื่อเข้าถึงบัญชีของคุณ',
|
||||
login2fa_use_recovery_code: 'ใช้รหัสกู้คืน',
|
||||
login2fa_recovery_back: 'ย้อนกลับ',
|
||||
login2fa_recovery_placeholder: 'XXXXXXXX',
|
||||
|
||||
'change': 'เปลี่ยนแปลง', // In English: "Change"
|
||||
@@ -352,20 +316,13 @@ const th = {
|
||||
'billing.expanded': 'ขยาย', // In English: "Expanded"
|
||||
'billing.accelerated': 'เร่ง', // In English: "Accelerated"
|
||||
'billing.enjoy_msg': 'ขอให้สนุกกับพื้นที่จัดเก็บบนคลาด์ที่เพิ่มขึ้น %% ของคุณ', // In English: "Enjoy "" of Cloud Storage plus other benefits."
|
||||
'choose_publishing_option': 'เลือกวิธีที่คุณต้องการเผยแพร่เว็บไซต์ของคุณ:',
|
||||
'create_desktop_shortcut': 'สร้างทางลัด (เดสก์ท็อป)',
|
||||
'create_desktop_shortcut_s': 'สร้างทางลัด (เดสก์ท็อป)',
|
||||
'create_shortcut_s': 'สร้างทางลัด',
|
||||
'minimize': 'ย่อเล็กสุด',
|
||||
'reload_app': 'โหลดแอปใหม่',
|
||||
'publish_as_serverless_worker': 'เผยแพร่เป็น Worker',
|
||||
'toolbar.enter_fullscreen': 'เข้าสู่โหมดเต็มจอ',
|
||||
'toolbar.github': 'GitHub',
|
||||
'toolbar.refer': 'แนะนำ',
|
||||
'used_of': 'ใช้ {{used}} จาก {{available}}',
|
||||
'worker': 'Worker',
|
||||
'billing.offering.basic': 'พื้นฐาน',
|
||||
'too_many_attempts': 'พยายามหลายครั้งเกินไป กรุณาลองใหม่ภายหลัง',
|
||||
'server_timeout': 'เซิร์ฟเวอร์ใช้เวลานานเกินไปในการตอบสนอง กรุณาลองใหม่',
|
||||
'signup_error': 'เกิดข้อผิดพลาดระหว่างการสมัครสมาชิก กรุณาลองใหม่',
|
||||
'alert_error_title': 'ข้อผิดพลาด!',
|
||||
@@ -383,15 +340,10 @@ const th = {
|
||||
'window_title_open': 'เปิด',
|
||||
'window_title_change_password': 'เปลี่ยนรหัสผ่าน',
|
||||
'window_title_select_font': 'เลือกแบบอักษร…',
|
||||
'window_title_session_list': 'รายการเซสชั่น!',
|
||||
'window_title_set_new_password': 'ตั้งรหัสผ่านใหม่',
|
||||
'window_title_publish_website': 'เผยแพร่เว็บไซต์',
|
||||
'window_title_publish_worker': 'เผยแพร่ Worker',
|
||||
'window_title_authenticating': 'กำลังยืนยันตัวตน...',
|
||||
'window_title_refer_friend': 'แนะนำเพื่อน!',
|
||||
'desktop_exit_full_screen': 'ออกจากโหมดเต็มจอ',
|
||||
'desktop_enter_full_screen': 'เข้าสู่โหมดเต็มจอ',
|
||||
'item_shared_with_you': 'ผู้ใช้คนหนึ่งได้แชร์รายการนี้กับคุณ',
|
||||
'item_shared_by_you': 'คุณได้แชร์รายการนี้กับผู้ใช้อย่างน้อยหนึ่งคน',
|
||||
'item_shortcut': 'ทางลัด',
|
||||
'item_associated_websites': 'เว็บไซต์ที่เกี่ยวข้อง',
|
||||
@@ -400,9 +352,6 @@ const th = {
|
||||
'window_click_to_go_back': 'คลิกเพื่อย้อนกลับ',
|
||||
'window_click_to_go_forward': 'คลิกเพื่อไปข้างหน้า',
|
||||
'window_click_to_go_up': 'คลิกเพื่อขึ้นไปหนึ่งไดเรกทอรี',
|
||||
'window_title_public': 'สาธารณะ',
|
||||
'window_title_videos': 'วีดีโอ',
|
||||
'window_title_pictures': 'รูปภาพ',
|
||||
'window_title_puter': 'Puter',
|
||||
'window_folder_empty': 'โฟลเดอร์นี้ว่างเปล่า',
|
||||
},
|
||||
|
||||
@@ -31,7 +31,6 @@ const tr = {
|
||||
allow: 'İzin ver',
|
||||
ascending: 'Artan',
|
||||
associated_websites: 'İlişkilendirilmiş Web Siteleri',
|
||||
auto_arrange: 'Otomatik Düzenle',
|
||||
cancel: 'İptal',
|
||||
change_email: 'E-postayı Değiştir',
|
||||
change_language: 'Dili Değiştir',
|
||||
@@ -40,17 +39,10 @@ const tr = {
|
||||
close: 'Kapat',
|
||||
close_all_windows_and_log_out: 'Pencereleri Kapat ve Çıkış Yap',
|
||||
change_always_open_with: 'Bu tür dosyaları her zaman şununla açmak istiyor musunuz',
|
||||
confirm_2fa_setup: 'Kodu kimlik doğrulama uygulamama ekledim',
|
||||
confirm_2fa_recovery: 'Kurtarma kodlarımı güvenli bir yere kaydettim',
|
||||
confirm_account_for_free_referral_storage_c2a: '1 GB ücretsiz depolama alanı kazanmak için bir hesap oluşturun ve e-posta adresinizi onaylayın. Arkadaşınız da 1 GB ücretsiz depolama alanı kazanacak.',
|
||||
confirm_code_generic_incorrect: 'Hatalı Kod.',
|
||||
confirm_code_generic_too_many_requests: 'Çok fazla istek. Lütfen birkaç dakika bekleyin.',
|
||||
confirm_code_generic_submit: 'Kodu Gönder',
|
||||
confirm_code_generic_try_again: 'Tekrar Dene',
|
||||
confirm_code_generic_title: 'Doğrulama Kodunu Gir',
|
||||
confirm_code_2fa_instruction: 'Kimlik doğrulama uygulamanızdaki 6 haneli kodu girin',
|
||||
confirm_code_2fa_submit_btn: 'Gönder',
|
||||
confirm_code_2fa_title: 'İki faktörlü kimlik doğrulama kodunu girin', // Turkish abbreviation of 2FA doesn't exist
|
||||
confirm_delete_multiple_items: 'Bu öğeleri kalıcı olarak silmek istediğinize emin misiniz?',
|
||||
confirm_delete_single_item: 'Bu öğeyi kalıcı olarak silmek istiyor musunuz?',
|
||||
confirm_open_apps_log_out: 'Açık uygulamalarınız var. Çıkış yapmak istediğinize emin misiniz?',
|
||||
@@ -60,7 +52,6 @@ const tr = {
|
||||
confirm_session_revoke: 'Bu oturumu sonlandırmak istediğinize emin misiniz?',
|
||||
confirm_your_email_address: 'E-Posta Adresini Doğrula',
|
||||
contact_us: 'Bize Ulaşın',
|
||||
contact_us_verification_required: 'Bunu kullanmak için doğrulanmış bir e-posta adresiniz olmalıdır.',
|
||||
continue: 'Devam',
|
||||
copy: 'Kopyala',
|
||||
copy_link: 'Bağlantıyı Kopyala',
|
||||
@@ -82,17 +73,13 @@ const tr = {
|
||||
deploy_as_app: 'Uygulama olarak dağıt',
|
||||
descending: 'Azalan',
|
||||
desktop: 'Masaüstü',
|
||||
desktop_background_fit: 'Sığdır',
|
||||
developers: 'Geliştiriciler',
|
||||
dir_published_as_website: '%strong% şu adrese yayınlandı:',
|
||||
disable_2fa: 'İki faktörlü doğrulamayı kapat',
|
||||
disable_2fa_confirm: 'İki faktörlü doğrulamayı kapatmak istediğinize emin misiniz?',
|
||||
disable_2fa_instructions: 'İki faktörlü doğrulamayı kapatmak için parolanızı girin.',
|
||||
documents: 'Belgeler',
|
||||
dont_allow: 'İzin Verme',
|
||||
download: 'İndir',
|
||||
download_file: 'Dosyayı İndir',
|
||||
downloading: 'İndiriliyor',
|
||||
email: 'E-posta',
|
||||
email_change_confirmation_sent: 'Yeni e-posta adresinize bir onay e-postası gönderilmiştir. Lütfen gelen kutunuzu kontrol edin ve işlemi tamamlamak için talimatları takip edin.',
|
||||
email_invalid: 'Geçersiz E-Posta',
|
||||
@@ -117,13 +104,10 @@ const tr = {
|
||||
forgot_pass_c2a: 'Parolanızı mı unuttunuz?',
|
||||
from: 'Kimden',
|
||||
general: 'Genel',
|
||||
get_a_copy_of_on_puter: "'%' kopyasını Puter.com'da edinin!",
|
||||
get_copy_link: 'Kopyalama Bağlantısını Al',
|
||||
home: 'Anasayfa',
|
||||
html_document: 'HTML belgesi',
|
||||
hue: 'Renk Tonu',
|
||||
incorrect_password: 'Hatalı Parola',
|
||||
invite_link: 'Davet Bağlantısı',
|
||||
item: 'öğe',
|
||||
items_in_trash_cannot_be_renamed: 'Bu öğe, çöp kutusunda olduğu için yeniden adlandırılamaz. Bu öğeyi yeniden adlandırmak için önce çöp kutusundan çıkarın.',
|
||||
jpeg_image: 'JPEG görüntüsü',
|
||||
@@ -134,7 +118,6 @@ const tr = {
|
||||
loading: 'Yükleniyor',
|
||||
log_in: 'Giriş Yap',
|
||||
log_out: 'Çıkış Yap',
|
||||
looks_good: 'İyi görünüyor!',
|
||||
manage_sessions: 'Oturumları Yönet',
|
||||
modified: 'Değiştirilmiş',
|
||||
move: 'Taşı',
|
||||
@@ -159,7 +142,6 @@ const tr = {
|
||||
open_with: 'Şununla Aç',
|
||||
original_name: 'Orijinal Ad',
|
||||
original_path: 'Orijinal Yol',
|
||||
oss_code_and_content: 'Açık Kaynak Kodlu Yazılım ve İçerik',
|
||||
password: 'Parola',
|
||||
password_changed: 'Parola değiştirildi.',
|
||||
password_recovery_rate_limit: 'Hız sınırımıza ulaştınız; lütfen birkaç dakika bekleyin. Gelecekte bunu önlemek için sayfayı çok fazla yeniden yüklemekten kaçının.',
|
||||
@@ -171,26 +153,19 @@ const tr = {
|
||||
paste: 'Yapıştır',
|
||||
paste_into_folder: 'Klasöre Yapıştır',
|
||||
path: 'Yol',
|
||||
personalization: 'Kişiselleştirme',
|
||||
pick_name_for_website: 'Web siteniz için bir ad seçin:',
|
||||
pictures: 'Resimler',
|
||||
plural_suffix: '',
|
||||
powered_by_puter_js: '{{link=docs}}Puter.js{{/link}} tarafından güçlendirilmiştir',
|
||||
preparing: 'Hazırlanıyor...',
|
||||
preparing_for_upload: 'Yüklemeye hazırlanıyor...',
|
||||
print: 'Yazdır',
|
||||
privacy: 'Gizlilik',
|
||||
proceed_to_login: 'Giriş yapmak için devam et',
|
||||
proceed_with_account_deletion: 'Hesap Silme İşlemine Devam Et',
|
||||
properties: 'Özellikler',
|
||||
public: 'Genel',
|
||||
publish: 'Yayınla',
|
||||
publish_as_website: 'Web sitesi olarak yayınla',
|
||||
puter_description: 'Puter, tüm dosyalarınızı, uygulamalarınızı ve oyunlarınızı tek bir güvenli yerde tutmak için gizliliğe öncelik veren kişisel bir buluttur ve her yerden her zaman erişilebilir.',
|
||||
reading_file: '%strong% okunuyor',
|
||||
recover_password: 'Parolayı Kurtar',
|
||||
refer_friends_c2a: 'Hesap oluşturup onaylayan her arkadaşınız için 1 GB kazanın. Arkadaşınız da 1 GB kazanacak!',
|
||||
refer_friends_social_media_c2a: "Puter.com'da 1 GB ücretsiz depolama alanı kazanın!",
|
||||
refresh: 'Yenile',
|
||||
rename: 'Yeniden Adlandır',
|
||||
replace: 'Değiştir',
|
||||
@@ -200,11 +175,9 @@ const tr = {
|
||||
save: 'Kaydet',
|
||||
saturation: 'Doygunluk',
|
||||
save_account: 'Hesabı kaydet',
|
||||
save_account_to_get_copy_link: 'Devam etmek için lütfen bir hesap oluşturun.',
|
||||
save_account_to_publish: 'Devam etmek için lütfen bir hesap oluşturun.',
|
||||
save_session: 'Oturumu kaydet',
|
||||
save_session_c2a: 'Geçerli oturumunuzu kaydetmek ve çalışmalarınızı kaybetmemek için bir hesap oluşturun.',
|
||||
scan_qr_2fa: 'Karekodu kimlik doğrulama uygulamanız ile tarayın',
|
||||
search: 'Ara',
|
||||
seconds: 'saniye',
|
||||
security: 'Güvenlik',
|
||||
@@ -222,13 +195,11 @@ const tr = {
|
||||
show_hidden: 'Gizli dosyaları göster',
|
||||
sign_in_with_puter: 'Puter ile giriş yap',
|
||||
sign_up: 'Kaydol',
|
||||
signing_in: 'Giriş yapılıyor…',
|
||||
size: 'Boyut',
|
||||
skip: 'Atla',
|
||||
something_went_wrong: 'Bir şeyler ters gitti.',
|
||||
sort_by: 'Şuna göre sırala',
|
||||
status: 'Durum',
|
||||
storage_usage: 'Depolama Alanı Kullanımı',
|
||||
storage_puter_used: 'Puter tarafından kullanılıyor',
|
||||
taking_longer_than_usual: 'Normalden biraz daha uzun sürüyor. Lütfen bekleyin...',
|
||||
terms: 'Şartlar',
|
||||
@@ -256,12 +227,10 @@ const tr = {
|
||||
videos: 'Videolar',
|
||||
visibility: 'Görünürlük',
|
||||
yes: 'Evet',
|
||||
you_have_been_referred_to_puter_by_a_friend: "Bir arkadaşınız tarafından Puter'a yönlendirildiniz!",
|
||||
zip: 'Sıkıştır',
|
||||
zipping_file: '%strong% sıkıştırılıyor',
|
||||
|
||||
// === 2FA Setup ===
|
||||
setup2fa_1_step_heading: 'Kimlik doğrulama uygulamanızı açın',
|
||||
setup2fa_1_instructions: `
|
||||
Zaman tabanlı tek seferlik parola (TOTP) protokolünü
|
||||
destekleyen herhangi bir kimlik doğrulayıcı uygulamasını
|
||||
@@ -269,19 +238,15 @@ const tr = {
|
||||
sayıda uygulama var, ancak emin değilseniz <a target="_blank" href="https://authy.com/download">Authy</a>
|
||||
Android ve IOS için sağlam bir seçimdir.
|
||||
`,
|
||||
setup2fa_2_step_heading: 'Karekodu okut',
|
||||
setup2fa_3_step_heading: '6 haneli kodu girin',
|
||||
setup2fa_4_step_heading: 'Kurtarma kodlarınızı kopyalayın',
|
||||
setup2fa_4_instructions: `
|
||||
Bu kurtarma kodları, telefonunuzu kaybetmeniz veya
|
||||
kimlik doğrulayıcı uygulamanızı kullanamamanız durumunda
|
||||
hesabınıza erişmenin tek yoludur.
|
||||
Bunları güvenli bir yerde sakladığınızdan emin olun.
|
||||
`,
|
||||
setup2fa_5_step_heading: 'İki Faktörlü Kimlik Doğrulama kurulumunu onayla',
|
||||
setup2fa_5_confirmation_1: 'Kurtarma kodlarımı güvenli bir yere kaydettim',
|
||||
setup2fa_5_confirmation_2: 'İki Faktörlü Kimlik Doğrulamayı etkinleştirmeye hazırım',
|
||||
setup2fa_5_button: 'İki Faktörlü Kimlik Doğrulamayı etkinleştir',
|
||||
|
||||
// === 2FA Login ===
|
||||
login2fa_otp_title: 'İki Faktörlü Kimlik Doğrulama kodunu girin',
|
||||
@@ -289,7 +254,6 @@ const tr = {
|
||||
login2fa_recovery_title: 'Bir kurtarma kodu girin',
|
||||
login2fa_recovery_instructions: 'Hesabınıza erişmek için kurtarma kodlarınızdan birini girin.',
|
||||
login2fa_use_recovery_code: 'Bir kurtarma kodu kullan',
|
||||
login2fa_recovery_back: 'Geri',
|
||||
login2fa_recovery_placeholder: 'XXXXXXXX',
|
||||
|
||||
'change': 'Değiştir', // In English: "Change"
|
||||
@@ -355,20 +319,13 @@ const tr = {
|
||||
'billing.expanded': 'Genişletilmiş', // In English: "Expanded"
|
||||
'billing.accelerated': 'Hızlandırılmış', // In English: "Accelerated"
|
||||
'billing.enjoy_msg': 'Diğer avantajların yanı sıra %% Bulut Depolamanın keyfini çıkarın.', // In English: "Enjoy %% of Cloud Storage plus other benefits."
|
||||
'choose_publishing_option': 'Web sitenizi nasıl yayınlamak istediğinizi seçin:',
|
||||
'create_desktop_shortcut': 'Kısayol Oluştur (Masaüstü)',
|
||||
'create_desktop_shortcut_s': 'Kısayollar Oluştur (Masaüstü)',
|
||||
'create_shortcut_s': 'Kısayollar Oluştur',
|
||||
'minimize': 'Küçült',
|
||||
'reload_app': 'Uygulamayı Yeniden Yükle',
|
||||
'publish_as_serverless_worker': 'Worker olarak Yayınla',
|
||||
'toolbar.enter_fullscreen': 'Tam Ekrana Geç',
|
||||
'toolbar.github': 'GitHub',
|
||||
'toolbar.refer': 'Yönlendir',
|
||||
'used_of': '{{available}} alanın {{used}} kullanılıyor',
|
||||
'worker': 'Worker',
|
||||
'billing.offering.basic': 'Temel',
|
||||
'too_many_attempts': 'Çok fazla deneme. Lütfen daha sonra tekrar deneyin.',
|
||||
'server_timeout': 'Sunucu yanıt vermekte çok uzun sürdü. Lütfen tekrar deneyin.',
|
||||
'signup_error': 'Kayıt sırasında bir hata oluştu. Lütfen tekrar deneyin.',
|
||||
'alert_error_title': 'Hata!',
|
||||
@@ -386,15 +343,10 @@ const tr = {
|
||||
'window_title_open': 'Aç',
|
||||
'window_title_change_password': 'Parolayı Değiştir',
|
||||
'window_title_select_font': 'Yazı tipi seç…',
|
||||
'window_title_session_list': 'Oturum Listesi!',
|
||||
'window_title_set_new_password': 'Yeni Parola Belirle',
|
||||
'window_title_publish_website': 'Web Sitesi Yayınla',
|
||||
'window_title_publish_worker': 'Worker Yayınla',
|
||||
'window_title_authenticating': 'Kimlik doğrulanıyor...',
|
||||
'window_title_refer_friend': 'Bir arkadaşını yönlendir!',
|
||||
'desktop_exit_full_screen': 'Tam Ekrandan Çık',
|
||||
'desktop_enter_full_screen': 'Tam Ekrana Geç',
|
||||
'item_shared_with_you': 'Bir kullanıcı bu öğeyi sizinle paylaştı.',
|
||||
'item_shared_by_you': 'Bu öğeyi en az bir kullanıcıyla paylaştınız.',
|
||||
'item_shortcut': 'Kısayol',
|
||||
'item_associated_websites': 'İlişkilendirilmiş web sitesi',
|
||||
@@ -403,9 +355,6 @@ const tr = {
|
||||
'window_click_to_go_back': 'Geri gitmek için tıklayın.',
|
||||
'window_click_to_go_forward': 'İleri gitmek için tıklayın.',
|
||||
'window_click_to_go_up': 'Bir dizin yukarı çıkmak için tıklayın.',
|
||||
'window_title_public': 'Genel',
|
||||
'window_title_videos': 'Videolar',
|
||||
'window_title_pictures': 'Resimler',
|
||||
'window_title_puter': 'Puter',
|
||||
'window_folder_empty': 'Bu klasör boş',
|
||||
},
|
||||
|
||||
@@ -31,7 +31,6 @@ const ua = {
|
||||
allow: 'Дозволити',
|
||||
ascending: 'За зростанням',
|
||||
associated_websites: 'Асоційовані веб-сайти',
|
||||
auto_arrange: 'Автоупорядкування',
|
||||
cancel: 'Відміна',
|
||||
change: 'Змінити',
|
||||
change_email: 'Змінити Email',
|
||||
@@ -42,17 +41,10 @@ const ua = {
|
||||
close_all_windows_and_log_out: 'Закрити Вікна і Вийти',
|
||||
change_always_open_with: 'Бажаєте завжди відкривати файли цього типу в',
|
||||
confirm: 'Підтвердити',
|
||||
confirm_2fa_setup: 'Я додав код у свій додаток для аутентифікації',
|
||||
confirm_2fa_recovery: 'Я зберіг свої коди для відновлення в безпечному місці',
|
||||
confirm_account_for_free_referral_storage_c2a: 'Створіть обліковий запис і підтвердіть свою електронну адресу, щоб отримати 1 Гб безкоштовного дискового простору. Ваш друг також отримає 1 Гб безкоштовного дискового простору.',
|
||||
confirm_code_generic_incorrect: 'Код невірний',
|
||||
confirm_code_generic_too_many_requests: 'Забагато запитів. Будь ласка, зачекайте кілька хвилин',
|
||||
confirm_code_generic_submit: 'Прийняти код',
|
||||
confirm_code_generic_try_again: 'Спробувати знову',
|
||||
confirm_code_generic_title: 'Ввести код підтвердження',
|
||||
confirm_code_2fa_instruction: 'Введіть шестизначний код з вашого додатка для аутентифікації.',
|
||||
confirm_code_2fa_submit_btn: 'Прийняти',
|
||||
confirm_code_2fa_title: 'Введіть код для двофакторної аутентифікації',
|
||||
confirm_delete_multiple_items: 'Ви впевнені, що хочете назавжди видалити ці елементи?',
|
||||
confirm_delete_single_item: 'Ви впевнені, що хочете назавжди видалити цей елемент?',
|
||||
confirm_open_apps_log_out: 'У вас є відкриті додатки. Ви впевнені, що хочете вийти з системи?',
|
||||
@@ -62,7 +54,6 @@ const ua = {
|
||||
confirm_session_revoke: 'Ви впевнені, що хочете відкликати цей сеанс?',
|
||||
confirm_your_email_address: 'Підтвердити електронну адресу',
|
||||
contact_us: "Зв'яжіться з нами",
|
||||
contact_us_verification_required: 'Вам необхідно мати підтверджену електронну адресу для використання цієї функції',
|
||||
continue: 'Продовжити',
|
||||
copy: 'Копіювати',
|
||||
copy_link: 'Копіювати Посилання',
|
||||
@@ -84,17 +75,13 @@ const ua = {
|
||||
deploy_as_app: 'Розгорнути як додаток',
|
||||
descending: 'За спаданням',
|
||||
desktop: 'Робочий стіл',
|
||||
desktop_background_fit: 'Вмістити',
|
||||
developers: 'Розробники',
|
||||
dir_published_as_website: '%strong% опубліковано в:',
|
||||
disable_2fa: 'Вимкнути двофакторну аутентифікацію',
|
||||
disable_2fa_confirm: 'Ви впевнені, що хочете вимкнути двофакторну аутентифікацію?',
|
||||
disable_2fa_instructions: 'Введіть ваш пароль для вимкнення двофакторної аутентифікації',
|
||||
documents: 'Документи',
|
||||
dont_allow: 'Не дозволяти',
|
||||
download: 'Завантажити',
|
||||
download_file: 'Завантажити Файл',
|
||||
downloading: 'Завантажується',
|
||||
email: 'Email',
|
||||
email_change_confirmation_sent: 'На вашу нову електронну адресу було надіслано листа з підтвердженням. Будь ласка, перевірте свою поштову скриньку і дотримуйтесь інструкцій, щоб завершити процес.',
|
||||
email_invalid: 'Електронна адреса недійсна.',
|
||||
@@ -119,13 +106,10 @@ const ua = {
|
||||
forgot_pass_c2a: 'Забули пароль?',
|
||||
from: 'Від',
|
||||
general: 'Загальний',
|
||||
get_a_copy_of_on_puter: 'Отримайте копію \'%%\' на Puter.com!',
|
||||
get_copy_link: 'Отримати Посилання для Копіювання',
|
||||
home: 'Додому',
|
||||
html_document: 'HTML документ',
|
||||
hue: 'Колірна Гама',
|
||||
incorrect_password: 'Невірний пароль',
|
||||
invite_link: 'Невірне посилання',
|
||||
item: 'Елемент',
|
||||
items_in_trash_cannot_be_renamed: `Цей елемент неможливо переіменувати тому що він знаходиться у кошику. Спочатку
|
||||
перемістіть його з корзини`,
|
||||
@@ -137,7 +121,6 @@ const ua = {
|
||||
loading: 'Завантажується',
|
||||
log_in: 'Ввійти',
|
||||
log_out: 'Вийти',
|
||||
looks_good: 'Гарно виглядає!',
|
||||
manage_sessions: 'Управління Сеансами',
|
||||
modified: 'Змінено',
|
||||
move: 'Перемістити',
|
||||
@@ -162,7 +145,6 @@ const ua = {
|
||||
open_with: 'Відчинити за допомогою',
|
||||
original_name: "Оригінальне Ім'я",
|
||||
original_path: 'Оригінальний шлях',
|
||||
oss_code_and_content: 'Програмне забезпечення та контент з відкритим кодом',
|
||||
password: 'Пароль',
|
||||
password_changed: 'Пароль змінено.',
|
||||
password_recovery_rate_limit: 'Ви досягли ліміту; будь ласка, зачекайте кілька хвилин. Щоб уникнути цього в майбутньому, не перезавантажуйте сторінку занадто багато разів.',
|
||||
@@ -174,27 +156,20 @@ const ua = {
|
||||
paste: 'Вставити',
|
||||
paste_into_folder: 'Вставити в Папку',
|
||||
path: 'Шлях',
|
||||
personalization: 'Персоналізація',
|
||||
pick_name_for_website: "Виберіть ім'я для вашого сайту:",
|
||||
pictures: 'Зображення',
|
||||
plural_suffix: 's',
|
||||
powered_by_puter_js: 'Створено на {{link=docs}}Puter.js{{/link}}',
|
||||
preparing: 'Підготовка...',
|
||||
preparing_for_upload: 'Підготовка до завантаження...',
|
||||
print: 'Друкувати',
|
||||
privacy: 'Конфіденційність',
|
||||
proceed_to_login: 'Перейти до Входу',
|
||||
proceed_with_account_deletion: 'Продовжити Видалення Облікового Запису',
|
||||
properties: 'Властивості',
|
||||
public: 'Загальний',
|
||||
publish: 'Опублікувати',
|
||||
publish_as_website: 'Опублікувати як сайт',
|
||||
puter_description: 'Puter — це персональна хмара, яка забезпечує конфіденційність, дозволяючи зберігати всі ваші файли, додатки та ігри в одному безпечному місці, доступному з будь-якого місця в будь-який час.',
|
||||
reading: 'Читання %strong%',
|
||||
reading_file: 'Читання файлу',
|
||||
recover_password: 'Відновити Пароль',
|
||||
refer_friends_c2a: 'Отримайте 1 ГБ за кожного друга, який створить і підтвердить обліковий запис на Puter. Ваш друг також отримає 1 ГБ!',
|
||||
refer_friends_social_media_c2a: 'Отримайте 1 ГБ безкоштовного сховища на Puter.com!',
|
||||
refresh: 'Оновити',
|
||||
rename: 'Перейменувати',
|
||||
replace: 'Замінити',
|
||||
@@ -204,11 +179,9 @@ const ua = {
|
||||
save: 'Зберегти',
|
||||
saturation: 'Насиченість',
|
||||
save_account: 'Зберегти Обліковий запис',
|
||||
save_account_to_get_copy_link: 'Будь ласка, створіть обліковий запис, щоб продовжити.',
|
||||
save_account_to_publish: 'Будь ласка, створіть обліковий запис, щоб продовжити.',
|
||||
save_session: 'Зберегти сеанс',
|
||||
save_session_c2a: 'Створіть обліковий запис, щоб зберегти поточний сеанс і не втратити дані.',
|
||||
scan_qr_2fa: 'Скануйте код за допомогою вашого додатку для аутентифікації',
|
||||
search: 'Пошук',
|
||||
seconds: 'секунди',
|
||||
security: 'Безпека',
|
||||
@@ -226,12 +199,10 @@ const ua = {
|
||||
show_hidden: 'Показати приховані',
|
||||
sign_in_with_puter: 'Увійти з Puter',
|
||||
sign_up: 'Зареєструватися',
|
||||
signing_in: 'Вхід у систему…',
|
||||
size: 'Розмір',
|
||||
skip: 'Пропустити',
|
||||
sort_by: 'Відсортувати за',
|
||||
status: 'Статус',
|
||||
storage_usage: 'Використання сховища',
|
||||
storage_puter_used: 'використано Puter',
|
||||
taking_longer_than_usual: 'Це займає трохи більше часу, ніж зазвичай. будь ласка, зачекайте...',
|
||||
terms: 'Умови',
|
||||
@@ -261,28 +232,21 @@ const ua = {
|
||||
visibility: 'Видимість',
|
||||
writing: 'Написання %strong%',
|
||||
yes: 'Так',
|
||||
you_have_been_referred_to_puter_by_a_friend: 'Вас запросив друг у Puter!',
|
||||
zip: 'Архівувати',
|
||||
zipping: 'Архівування %strong%',
|
||||
zipping_file: 'Архівування %strong%',
|
||||
sequencing: 'Порядок %strong%',
|
||||
setup2fa_1_step_heading: 'Відкрийте ваш додаток для аутентифікації',
|
||||
setup2fa_1_instructions: 'Ви можете використовувати будь-який додаток, який підтримує Одноразовий Пароль на основі часу. Їх багато, але якщо ви не впевнені у виборі <a target="_blank" href="https://authy.com/download">Authy</a> є чудовим варіантом для Android і iOS.',
|
||||
setup2fa_2_step_heading: 'Скануйте QR код',
|
||||
setup2fa_3_step_heading: 'Введіть шестизначний код',
|
||||
setup2fa_4_step_heading: 'Скопіюйте ваші коди відновлення',
|
||||
setup2fa_4_instructions: 'Ці коди відновлення є єдиним способом входу у ваш обліковий запис, якщо ви втратите телефон або не зможете використовувати додаток для аутентифікації. Упевніться, що ви їх зберегли.',
|
||||
setup2fa_5_step_heading: 'Підтвердьте налаштування 2FA',
|
||||
setup2fa_5_confirmation_1: 'Я зберіг свої коди в надійному місці',
|
||||
setup2fa_5_confirmation_2: 'Я готовий використовувати 2FA',
|
||||
setup2fa_5_button: 'Увімкнути 2FA',
|
||||
something_went_wrong: 'Щось пішло не так.',
|
||||
login2fa_otp_title: 'Введіть код 2FA',
|
||||
login2fa_otp_instructions: 'Введіть шестизначний код з вашого додатку для аутентифікації',
|
||||
login2fa_recovery_title: 'Введіть код відновлення',
|
||||
login2fa_recovery_instructions: 'Введіть один з кодів відновлення для доступу до облікового запису',
|
||||
login2fa_use_recovery_code: 'Використовуйте код відновлення',
|
||||
login2fa_recovery_back: 'Назад',
|
||||
login2fa_recovery_placeholder: 'XXXXXXXX',
|
||||
Editor: 'Редактор',
|
||||
Viewer: 'Переглядач',
|
||||
@@ -338,20 +302,13 @@ const ua = {
|
||||
'billing.expanded': 'Розширений',
|
||||
'billing.accelerated': 'Прискорений',
|
||||
'billing.enjoy_msg': 'Насолоджуйтесь %% хмарного сховища та іншими перевагами.',
|
||||
'choose_publishing_option': 'Виберіть, як ви хочете опублікувати свій веб-сайт:',
|
||||
'create_desktop_shortcut': 'Створити ярлик (Робочий стіл)',
|
||||
'create_desktop_shortcut_s': 'Створити ярлики (Робочий стіл)',
|
||||
'create_shortcut_s': 'Створити ярлики',
|
||||
'minimize': 'Згорнути',
|
||||
'reload_app': 'Перезавантажити додаток',
|
||||
'publish_as_serverless_worker': 'Опублікувати як воркер',
|
||||
'toolbar.enter_fullscreen': 'Увійти в повноекранний режим',
|
||||
'toolbar.github': 'GitHub',
|
||||
'toolbar.refer': 'Рекомендувати',
|
||||
'used_of': '{{used}} використано з {{available}}',
|
||||
'worker': 'Воркер',
|
||||
'billing.offering.basic': 'Базовий',
|
||||
'too_many_attempts': 'Забагато спроб. Будь ласка, спробуйте пізніше.',
|
||||
'server_timeout': 'Сервер занадто довго відповідає. Будь ласка, спробуйте знову.',
|
||||
'signup_error': 'Під час реєстрації сталася помилка. Будь ласка, спробуйте знову.',
|
||||
'alert_error_title': 'Помилка!',
|
||||
@@ -369,15 +326,10 @@ const ua = {
|
||||
'window_title_open': 'Відкрити',
|
||||
'window_title_change_password': 'Змінити пароль',
|
||||
'window_title_select_font': 'Вибрати шрифт…',
|
||||
'window_title_session_list': 'Список сеансів!',
|
||||
'window_title_set_new_password': 'Встановити новий пароль',
|
||||
'window_title_publish_website': 'Опублікувати веб-сайт',
|
||||
'window_title_publish_worker': 'Опублікувати воркер',
|
||||
'window_title_authenticating': 'Аутентифікація...',
|
||||
'window_title_refer_friend': 'Запросити друга!',
|
||||
'desktop_exit_full_screen': 'Вийти з повноекранного режиму',
|
||||
'desktop_enter_full_screen': 'Увійти в повноекранний режим',
|
||||
'item_shared_with_you': 'Користувач поділився цим елементом з вами.',
|
||||
'item_shared_by_you': 'Ви поділилися цим елементом з принаймні одним іншим користувачем.',
|
||||
'item_shortcut': 'Ярлик',
|
||||
'item_associated_websites': "Пов'язаний веб-сайт",
|
||||
@@ -386,9 +338,6 @@ const ua = {
|
||||
'window_click_to_go_back': 'Натисніть, щоб повернутися назад.',
|
||||
'window_click_to_go_forward': 'Натисніть, щоб перейти вперед.',
|
||||
'window_click_to_go_up': 'Натисніть, щоб перейти на одну директорію вгору.',
|
||||
'window_title_public': 'Публічний',
|
||||
'window_title_videos': 'Відео',
|
||||
'window_title_pictures': 'Зображення',
|
||||
'window_title_puter': 'Puter',
|
||||
'window_folder_empty': 'Ця папка порожня',
|
||||
},
|
||||
|
||||
@@ -29,7 +29,6 @@ const ur = {
|
||||
add_another_account: 'دوسرا اکاؤنٹ شامل کریں',
|
||||
all_fields_required: 'تمام شعبوں کی ضرورت ہے',
|
||||
ascending: 'بڑھتی ہوئی',
|
||||
auto_arrange: 'خودکار ترتیب',
|
||||
cancel: 'منسوخ کریں',
|
||||
change_email: 'ای میل تبدیل کریں',
|
||||
change_language: 'زبان تبدیل کریں',
|
||||
@@ -38,21 +37,13 @@ const ur = {
|
||||
close: 'بند کریں',
|
||||
close_all_windows_and_log_out: 'ونڈوز بند کریں اور لاگ آؤٹ کریں۔',
|
||||
change_always_open_with: 'کیا آپ ہمیشہ اس قسم کی فائل کو کھولنا چاہتے ہیں۔',
|
||||
confirm_2fa_setup: 'میں نے کوڈ کو اپنی تصدیق کنندہ ایپ میں شامل کر دیا ہے۔',
|
||||
confirm_2fa_recovery:
|
||||
'میں نے اپنے ریکوری کوڈز کو محفوظ جگہ پر محفوظ کر لیا ہے۔',
|
||||
confirm_account_for_free_referral_storage_c2a:
|
||||
'1 GB مفت اسٹوریج حاصل کرنے کے لیے ایک اکاؤنٹ بنائیں اور اپنے ای میل ایڈریس کی تصدیق کریں۔ آپ کے دوست کو 1 GB مفت اسٹوریج بھی ملے گا۔',
|
||||
confirm_code_generic_incorrect: 'غلط کوڈ۔',
|
||||
confirm_code_generic_too_many_requests:
|
||||
'بہت زیادہ درخواستیں براہ کرم چند منٹ انتظار کریں۔',
|
||||
confirm_code_generic_submit: 'کوڈ جمع کروائیں۔',
|
||||
confirm_code_generic_try_again: 'دوبارہ کوشش کریں',
|
||||
confirm_code_generic_title: 'تصدیقی کوڈ درج کریں',
|
||||
confirm_code_2fa_instruction:
|
||||
'اپنی تصدیق کنندہ ایپ سے 6 ہندسوں کا کوڈ درج کریں۔',
|
||||
confirm_code_2fa_submit_btn: 'جمع کرائیں',
|
||||
confirm_code_2fa_title: '2FA کوڈ درج کریں۔',
|
||||
confirm_delete_multiple_items:
|
||||
'کیا آپ واقعی ان آئٹمز کو مستقل طور پر حذف کرنا چاہتے ہیں؟',
|
||||
confirm_delete_single_item:
|
||||
@@ -65,8 +56,6 @@ const ur = {
|
||||
confirm_delete_user_title: 'اکاؤنٹ حذف کرنا ہے؟',
|
||||
confirm_session_revoke: 'کیا آپ واقعی اس سیشن کو منسوخ کرنا چاہتے ہیں؟',
|
||||
contact_us: 'ہم سے رابطہ کریں',
|
||||
contact_us_verification_required:
|
||||
'اسے استعمال کرنے کے لیے آپ کے پاس تصدیق شدہ ای میل پتہ ہونا ضروری ہے۔',
|
||||
continue: 'جاری رہے',
|
||||
copy: 'کاپی کریں',
|
||||
copy_link: 'لنک کاپی کریں',
|
||||
@@ -86,17 +75,13 @@ const ur = {
|
||||
deploy_as_app: 'ایپ کے طور پر منتشر کریں',
|
||||
descending: 'گرتی ہوئی',
|
||||
desktop: 'ڈیسک ٹاپ',
|
||||
desktop_background_fit: 'ڈیسک ٹاپ کا پس منظر مناسب ہو',
|
||||
developers: 'ڈویلپرز',
|
||||
dir_published_as_website: 'ڈائریکٹری کو ویب سائٹ کے طور پر شائع کیا گیا',
|
||||
disable_2fa: '2FA کو غیر فعال کریں۔',
|
||||
disable_2fa_confirm: 'کیا آپ واقعی 2FA کو غیر فعال کرنا چاہتے ہیں؟',
|
||||
disable_2fa_instructions:
|
||||
'2FA کو غیر فعال کرنے کے لیے اپنا پاس ورڈ درج کریں۔',
|
||||
documents: 'دستاویزات',
|
||||
download: 'ڈاؤن لوڈ کریں ',
|
||||
download_file: 'فائل ڈاؤن لوڈ کریں',
|
||||
downloading: 'ڈاؤن لوڈ ہو رہا ہے ',
|
||||
email: 'ای میل',
|
||||
email_change_confirmation_sent:
|
||||
'ایک تصدیقی ای میل آپ کے نئے ای میل پتے پر بھیج دیا گیا ہے۔ براہ کرم اپنا ان باکس چیک کریں اور عمل کو مکمل کرنے کے لیے ہدایات پر عمل کریں۔',
|
||||
@@ -121,13 +106,10 @@ const ur = {
|
||||
forgot_pass_c2a: 'پاس ورڈ بھول گئے ہیں؟',
|
||||
from: 'سے',
|
||||
general: 'عام ',
|
||||
get_a_copy_of_on_puter: "Puter.com پر '%%' کی ایک کاپی حاصل کریں!",
|
||||
get_copy_link: 'کاپی لنک حاصل کریں',
|
||||
home: 'گھر',
|
||||
html_document: 'ایچ ٹی ایم ایل دستاویز',
|
||||
hue: 'رنگت',
|
||||
incorrect_password: 'غلط پاس ورڈ',
|
||||
invite_link: 'دعوتی لنک',
|
||||
item: 'آئٹم',
|
||||
items_in_trash_cannot_be_renamed:
|
||||
'کچرے میں موجود اشیاء کا نام تبدیل نہیں کیا جا سکتا',
|
||||
@@ -139,7 +121,6 @@ const ur = {
|
||||
loading: 'لوڈ ہو رہا ہے۔',
|
||||
log_in: 'لاگ ان کریں',
|
||||
log_out: 'لاگ آؤٹ',
|
||||
looks_good: 'اچھا لگ رہا ہے!',
|
||||
manage_sessions: 'سیشنز کا نظم کریں۔',
|
||||
move: 'منتقل کریں',
|
||||
moving_file: 'منتقل ہو رہا ہے %%',
|
||||
@@ -161,7 +142,6 @@ const ur = {
|
||||
open_in_new_tab: 'نئی ٹیب میں کھولیں',
|
||||
open_in_new_window: 'نئی ونڈو میں کھولیں ',
|
||||
open_with: 'کے ساتھ کھولیں ',
|
||||
oss_code_and_content: 'اوپن سورس سافٹ ویئر اور مواد',
|
||||
password: 'پاس ورڈ ',
|
||||
password_changed: 'پاس ورڈ تبدیل ہوگیا ',
|
||||
password_recovery_rate_limit:
|
||||
@@ -175,29 +155,20 @@ const ur = {
|
||||
passwords_do_not_match: 'پاس ورڈ میچ نہیں ہوتی',
|
||||
paste: 'چسپاں کریں',
|
||||
paste_into_folder: 'فولڈر میں چسپاں کریں',
|
||||
personalization: 'متشکل',
|
||||
pick_name_for_website: 'ویب سائٹ کے لئے نام منتخب کریں ',
|
||||
pictures: 'تصویریں',
|
||||
plural_suffix: 'س',
|
||||
powered_by_puter_js:
|
||||
'پیوٹر جے ایس کے زریعے محرک{{link=docs}}Puter.js{{/link}}',
|
||||
preparing: 'تیاری ',
|
||||
preparing_for_upload: 'اپلوڈ کے لئے تیاری ',
|
||||
print: 'پرنٹ کریں',
|
||||
privacy: 'رازداری',
|
||||
proceed_to_login: 'لاگ ان کرنے کے لیے آگے بڑھیں۔',
|
||||
proceed_with_account_deletion: 'اکاؤنٹ حذف کرنے کے ساتھ آگے بڑھیں۔',
|
||||
properties: 'خصوصیات ',
|
||||
public: 'عوام',
|
||||
publish: 'شائع کریں',
|
||||
publish_as_website: 'ویب سائٹ کے طور پر شائع کریں',
|
||||
puter_description: 'Puter ایک رازداری کا پہلا ذاتی کلاؤڈ ہے جو آپ کی تمام فائلوں، ایپس اور گیمز کو ایک محفوظ جگہ پر رکھتا ہے، کسی بھی وقت کہیں سے بھی قابل رسائی ہے۔',
|
||||
reading_file: 'پڑھنا %strong%',
|
||||
recover_password: 'پاس ورڈ بازیاب کریں ',
|
||||
refer_friends_c2a:
|
||||
'! ہر دوست کے اکاؤنٹ بنانے اور اکاؤنٹ کی تصدیق کرنے پر 1 گیگابائٹ حاصل کریں۔ آپ کا دوست بھی 1 گیگابائٹ حاصل کرے گا ',
|
||||
refer_friends_social_media_c2a:
|
||||
'پیوٹر ڈاٹ کام پر مفت 1 گیگابائٹ ذخیرہ حاصل کریں!',
|
||||
refresh: 'تازہ کریں ',
|
||||
rename: 'دوبارہ نام دیں',
|
||||
replace: 'بدل دیں۔',
|
||||
@@ -206,12 +177,9 @@ const ur = {
|
||||
restore: 'بحال کریں',
|
||||
saturation: 'سنترپتی',
|
||||
save_account: 'اکاؤنٹ محفوظ کریں۔',
|
||||
save_account_to_get_copy_link:
|
||||
'کاپی لنک حاصل کرنے کے لئے اکاؤنٹ محفوظ کریں',
|
||||
save_account_to_publish: 'شائع کرنے کے لئے اکاؤنٹ محفوظ کریں',
|
||||
save_session: 'سیشن محفوظ کریں۔',
|
||||
save_session_c2a: 'سیشن کو محفوظ کریں ',
|
||||
scan_qr_2fa: 'اپنی تصدیق کنندہ ایپ سے QR کوڈ اسکین کریں۔',
|
||||
search: 'تلاش کریں۔',
|
||||
seconds: 'سیکنڈ',
|
||||
security: 'سیکورٹی',
|
||||
@@ -226,13 +194,11 @@ const ur = {
|
||||
show_hidden: 'پوشیدہ دکھائیں ',
|
||||
sign_in_with_puter: 'پیوٹر کے ساتھ سائن ان کریں',
|
||||
sign_up: 'سائن اپ کریں',
|
||||
signing_in: 'لاگ ان کر رہے ہیں',
|
||||
size: 'سائز',
|
||||
skip: 'چھوڑ دو',
|
||||
something_went_wrong: 'کچھ غلط ہو گیا۔',
|
||||
sort_by: ' ترتیب دیں',
|
||||
status: 'حالت',
|
||||
storage_usage: 'اسٹوریج کا استعمال',
|
||||
storage_puter_used: 'Puter کی طرف سے استعمال کیا جاتا ہے',
|
||||
taking_longer_than_usual: 'عام طور پر سے زیادہ وقت لگ رہا ہے ',
|
||||
terms: 'شرائط',
|
||||
@@ -261,33 +227,26 @@ const ur = {
|
||||
videos: 'ویڈیوز',
|
||||
visibility: 'مرئیت',
|
||||
yes: 'جی ہاں',
|
||||
you_have_been_referred_to_puter_by_a_friend:
|
||||
'آپ کو ایک دوست نے پیوٹر کی جانب رجوع کیا ہے!',
|
||||
zip: 'زپ فائل',
|
||||
zipping_file: 'زپ %strong%',
|
||||
|
||||
// === 2FA Setup ===
|
||||
// === 2FA سیٹ اپ ===
|
||||
|
||||
setup2fa_1_step_heading: 'اپنا تصدیق کنندہ ایپ کھولیں۔',
|
||||
setup2fa_1_instructions: `
|
||||
آپ کوئی بھی مستند ایپ استعمال کر سکتے ہیں جو ٹائم بیسڈ ون ٹائم پاس ورڈ (TOTP) پروٹوکول کو سپورٹ کرتی ہو۔
|
||||
منتخب کرنے کے لیے بہت سے ہیں، لیکن اگر آپ کو یقین نہیں ہے۔
|
||||
<a target="_blank" href="https://authy.com/download">Authy</a>
|
||||
Android اور iOS کے لیے ایک ٹھوس انتخاب ہے۔
|
||||
`,
|
||||
setup2fa_2_step_heading: 'QR کوڈ اسکین کریں۔',
|
||||
setup2fa_3_step_heading: '6 ہندسوں کا کوڈ درج کریں۔',
|
||||
setup2fa_4_step_heading: 'اپنے ریکوری کوڈز کاپی کریں۔',
|
||||
setup2fa_4_instructions: `
|
||||
یہ ریکوری کوڈز آپ کے اکاؤنٹ تک رسائی حاصل کرنے کا واحد طریقہ ہیں اگر آپ اپنا فون کھو دیتے ہیں یا آپ اپنا مستند ایپ استعمال نہیں کر پاتے ہیں۔
|
||||
ان کو محفوظ جگہ پر رکھنا یقینی بنائیں۔
|
||||
`,
|
||||
setup2fa_5_step_heading: '2FA سیٹ اپ کی تصدیق کریں۔',
|
||||
setup2fa_5_confirmation_1:
|
||||
'میں نے اپنے ریکوری کوڈز کو محفوظ جگہ پر محفوظ کر لیا ہے۔',
|
||||
setup2fa_5_confirmation_2: 'میں 2FA کو فعال کرنے کے لیے تیار ہوں۔',
|
||||
setup2fa_5_button: '2FA کو فعال کریں۔',
|
||||
|
||||
// === 2FA Login ===
|
||||
login2fa_otp_title: '2FA کوڈ درج کریں۔',
|
||||
@@ -297,7 +256,6 @@ const ur = {
|
||||
login2fa_recovery_instructions:
|
||||
'اپنے اکاؤنٹ تک رسائی کے لیے اپنا ایک ریکوری کوڈ درج کریں۔',
|
||||
login2fa_use_recovery_code: 'ریکوری کوڈ استعمال کریں۔',
|
||||
login2fa_recovery_back: 'پیچھے',
|
||||
login2fa_recovery_placeholder: 'XXXXXXXX',
|
||||
|
||||
'allow': 'اجازت دینا', // In English: "Allow"
|
||||
@@ -379,20 +337,13 @@ const ur = {
|
||||
'billing.expanded': 'وسیع', // In English: "Expanded"
|
||||
'billing.accelerated': 'تیز رفتار', // In English: "Accelerated"
|
||||
'billing.enjoy_msg': 'کلاؤڈ اسٹوریج کے %% حصے کے ساتھ دیگر فوائد کا لطف اٹھائیں۔', // In English: "Enjoy %% of Cloud Storage plus other benefits."
|
||||
'choose_publishing_option': 'اپنی ویب سائٹ شائع کرنے کا طریقہ منتخب کریں:', // In English: "Choose how you want to publish your website:"
|
||||
'create_desktop_shortcut': 'شارٹ کٹ بنائیں (ڈیسک ٹاپ)', // In English: "Create Shortcut (Desktop)"
|
||||
'create_desktop_shortcut_s': 'شارٹ کٹس بنائیں (ڈیسک ٹاپ)', // In English: "Create Shortcuts (Desktop)"
|
||||
'create_shortcut_s': 'شارٹ کٹس بنائیں', // In English: "Create Shortcuts"
|
||||
'minimize': 'چھوٹا کریں', // In English: "Minimize"
|
||||
'reload_app': 'ایپ دوبارہ لوڈ کریں', // In English: "Reload App"
|
||||
'publish_as_serverless_worker': 'ورکر کے طور پر شائع کریں', // In English: "Publish as Worker"
|
||||
'toolbar.enter_fullscreen': 'فل اسکرین پر جائیں', // In English: "Enter Full Screen"
|
||||
'toolbar.github': 'گیٹ ہب', // In English: "GitHub"
|
||||
'toolbar.refer': 'ریفر کریں', // In English: "Refer"
|
||||
'used_of': '{{used}} استعمال شدہ از {{available}}', // In English: "{{used}} used of {{available}}"
|
||||
'worker': 'ورکر', // In English: "Worker"
|
||||
'billing.offering.basic': 'بنیادی', // In English: "Basic"
|
||||
'too_many_attempts': 'بہت زیادہ کوششیں۔ براہ کرم بعد میں دوبارہ کوشش کریں۔', // In English: "Too many attempts. Please try again later."
|
||||
'server_timeout': 'سرور کے جواب میں بہت زیادہ وقت لگ گیا۔ براہ کرم دوبارہ کوشش کریں۔', // In English: "The server took too long to respond. Please try again."
|
||||
'signup_error': 'سائن اپ کے دوران ایک خرابی پیش آئی۔ براہ کرم دوبارہ کوشش کریں۔', // In English: "An error occurred during signup. Please try again."
|
||||
'alert_error_title': 'خرابی!', // In English: "Error!"
|
||||
@@ -410,15 +361,10 @@ const ur = {
|
||||
'window_title_open': 'کھولیں', // In English: "Open"
|
||||
'window_title_change_password': 'پاس ورڈ تبدیل کریں', // In English: "Change Password"
|
||||
'window_title_select_font': 'فونٹ منتخب کریں…', // In English: "Select font…"
|
||||
'window_title_session_list': 'سیشن فہرست!', // In English: "Session List!"
|
||||
'window_title_set_new_password': 'نیا پاس ورڈ سیٹ کریں', // In English: "Set New Password"
|
||||
'window_title_publish_website': 'ویب سائٹ شائع کریں', // In English: "Publish Website"
|
||||
'window_title_publish_worker': 'ورکر شائع کریں', // In English: "Publish Worker"
|
||||
'window_title_authenticating': 'تصدیق جاری ہے...', // In English: "Authenticating..."
|
||||
'window_title_refer_friend': 'کسی دوست کو ریفر کریں!', // In English: "Refer a friend!"
|
||||
'desktop_exit_full_screen': 'فل اسکرین سے باہر نکلیں', // In English: "Exit Full Screen"
|
||||
'desktop_enter_full_screen': 'فل اسکرین پر جائیں', // In English: "Enter Full Screen"
|
||||
'item_shared_with_you': 'کسی صارف نے یہ آئٹم آپ کے ساتھ شیئر کیا ہے۔', // In English: "A user has shared this item with you."
|
||||
'item_shared_by_you': 'آپ نے یہ آئٹم کم از کم ایک دوسرے صارف کے ساتھ شیئر کیا ہے۔', // In English: "You have shared this item with at least one other user."
|
||||
'item_shortcut': 'شارٹ کٹ', // In English: "Shortcut"
|
||||
'item_associated_websites': 'وابستہ ویب سائٹ', // In English: "Associated website"
|
||||
@@ -427,9 +373,6 @@ const ur = {
|
||||
'window_click_to_go_back': 'واپس جانے کے لیے کلک کریں۔', // In English: "Click to go back."
|
||||
'window_click_to_go_forward': 'آگے جانے کے لیے کلک کریں۔', // In English: "Click to go forward."
|
||||
'window_click_to_go_up': 'ایک ڈائریکٹری اوپر جانے کے لیے کلک کریں۔', // In English: "Click to go one directory up."
|
||||
'window_title_public': 'عوامی', // In English: "Public"
|
||||
'window_title_videos': 'ویڈیوز', // In English: "Videos"
|
||||
'window_title_pictures': 'تصاویر', // In English: "Pictures"
|
||||
'window_title_puter': 'پیوٹر', // In English: "Puter"
|
||||
'window_folder_empty': 'یہ فولڈر خالی ہے', // In English: "This folder is empty"
|
||||
|
||||
|
||||
@@ -31,7 +31,6 @@ const vi = {
|
||||
allow: 'Cho phép',
|
||||
ascending: 'Tăng dần',
|
||||
associated_websites: 'Các trang web liên kết',
|
||||
auto_arrange: 'Tự động sắp xếp',
|
||||
cancel: 'Hủy',
|
||||
change_email: 'Thay đổi email',
|
||||
change_language: 'Thay đổi ngôn ngữ',
|
||||
@@ -41,17 +40,10 @@ const vi = {
|
||||
close_all_windows_and_log_out: 'Đóng cửa sổ và đăng xuất',
|
||||
change_always_open_with: 'Bạn có muốn luôn mở loại tệp này bằng',
|
||||
confirm: 'Xác nhận',
|
||||
confirm_2fa_setup: 'Tôi đã thêm mã vào ứng dụng xác thực của mình',
|
||||
confirm_2fa_recovery: 'Tôi đã lưu mã khôi phục của mình ở một nơi an toàn',
|
||||
confirm_account_for_free_referral_storage_c2a: 'Tạo tài khoản và xác nhận địa chỉ email của bạn để nhận 1 GB dung lượng lưu trữ miễn phí. Bạn của bạn cũng sẽ nhận được 1 GB dung lượng lưu trữ miễn phí.',
|
||||
confirm_code_generic_incorrect: 'Mã không chính xác.',
|
||||
confirm_code_generic_too_many_requests: 'Quá nhiều yêu cầu. Vui lòng đợi vài phút.',
|
||||
confirm_code_generic_submit: 'Gửi mã',
|
||||
confirm_code_generic_try_again: 'Thử lại',
|
||||
confirm_code_generic_title: 'Nhập mã xác nhận',
|
||||
confirm_code_2fa_instruction: 'Nhập mã 6 chữ số từ ứng dụng xác thực của bạn.',
|
||||
confirm_code_2fa_submit_btn: 'Gửi',
|
||||
confirm_code_2fa_title: 'Nhập mã 2FA',
|
||||
confirm_delete_multiple_items: 'Bạn có chắc chắn muốn xóa vĩnh viễn những mục này không?',
|
||||
confirm_delete_single_item: 'Bạn có muốn xóa vĩnh viễn mục này không?',
|
||||
confirm_open_apps_log_out: 'Bạn có ứng dụng đang mở. Bạn có chắc chắn muốn đăng xuất không?',
|
||||
@@ -61,7 +53,6 @@ const vi = {
|
||||
confirm_session_revoke: 'Bạn có chắc chắn muốn thu hồi phiên này không?',
|
||||
confirm_your_email_address: 'Xác nhận địa chỉ email của bạn',
|
||||
contact_us: 'Liên hệ chúng tôi',
|
||||
contact_us_verification_required: 'Bạn phải có địa chỉ email đã xác minh để sử dụng tính năng này.',
|
||||
continue: 'Tiếp tục',
|
||||
copy: 'Sao chép',
|
||||
copy_link: 'Sao chép liên kết',
|
||||
@@ -83,17 +74,13 @@ const vi = {
|
||||
deploy_as_app: 'Triển khai như ứng dụng',
|
||||
descending: 'Giảm dần',
|
||||
desktop: 'Màn hình chính',
|
||||
desktop_background_fit: 'Vừa khít',
|
||||
developers: 'Nhà phát triển',
|
||||
dir_published_as_website: '%strong% đã được xuất bản tại:',
|
||||
disable_2fa: 'Tắt 2FA',
|
||||
disable_2fa_confirm: 'Bạn có chắc chắn muốn tắt 2FA không?',
|
||||
disable_2fa_instructions: 'Nhập mật khẩu của bạn để tắt 2FA.',
|
||||
documents: 'Tài liệu',
|
||||
dont_allow: 'Không cho phép',
|
||||
download: 'Tải xuống',
|
||||
download_file: 'Tải xuống tệp',
|
||||
downloading: 'Đang tải xuống',
|
||||
email: 'Email',
|
||||
email_change_confirmation_sent: 'Một email xác nhận đã được gửi đến địa chỉ email mới của bạn. Vui lòng kiểm tra hộp thư đến và làm theo hướng dẫn để hoàn tất quy trình.',
|
||||
email_invalid: 'Email không hợp lệ.',
|
||||
@@ -118,13 +105,10 @@ const vi = {
|
||||
forgot_pass_c2a: 'Quên mật khẩu?',
|
||||
from: 'Từ',
|
||||
general: 'Chung',
|
||||
get_a_copy_of_on_puter: 'Nhận một bản sao của \'%%\' trên Puter.com!',
|
||||
get_copy_link: 'Lấy liên kết sao chép',
|
||||
home: 'Trang chủ',
|
||||
html_document: 'Tài liệu HTML',
|
||||
hue: 'Màu sắc',
|
||||
incorrect_password: 'Mật khẩu không chính xác',
|
||||
invite_link: 'Liên kết mời',
|
||||
item: 'mục',
|
||||
items_in_trash_cannot_be_renamed: 'Mục này không thể đổi tên vì nó đang ở trong thùng rác. Để đổi tên mục này, trước tiên hãy kéo nó ra khỏi Thùng rác.',
|
||||
jpeg_image: 'Hình ảnh JPEG',
|
||||
@@ -135,7 +119,6 @@ const vi = {
|
||||
loading: 'Đang tải',
|
||||
log_in: 'Đăng nhập',
|
||||
log_out: 'Đăng xuất',
|
||||
looks_good: 'Trông tốt!',
|
||||
manage_sessions: 'Quản lý phiên',
|
||||
modified: 'Đã sửa đổi',
|
||||
move: 'Di chuyển',
|
||||
@@ -160,7 +143,6 @@ const vi = {
|
||||
open_with: 'Mở bằng',
|
||||
original_name: 'Tên gốc',
|
||||
original_path: 'Đường dẫn gốc',
|
||||
oss_code_and_content: 'Phần mềm mã nguồn mở và nội dung',
|
||||
password: 'Mật khẩu',
|
||||
password_changed: 'Đã thay đổi mật khẩu.',
|
||||
password_recovery_rate_limit: 'Bạn đã đạt đến giới hạn tốc độ của chúng tôi; vui lòng đợi vài phút. Để tránh điều này trong tương lai, hãy tránh tải lại trang quá nhiều lần.',
|
||||
@@ -172,26 +154,19 @@ const vi = {
|
||||
paste: 'Dán',
|
||||
paste_into_folder: 'Dán vào thư mục',
|
||||
path: 'Đường dẫn',
|
||||
personalization: 'Cá nhân hóa',
|
||||
pick_name_for_website: 'Chọn một tên cho trang web của bạn:',
|
||||
pictures: 'Hình ảnh',
|
||||
plural_suffix: '',
|
||||
powered_by_puter_js: 'Được hỗ trợ bởi {{link=docs}}Puter.js{{/link}}',
|
||||
preparing: 'Đang chuẩn bị...',
|
||||
preparing_for_upload: 'Đang chuẩn bị để tải lên...',
|
||||
print: 'In',
|
||||
privacy: 'Quyền riêng tư',
|
||||
proceed_to_login: 'Tiếp tục đăng nhập',
|
||||
proceed_with_account_deletion: 'Tiếp tục xóa tài khoản',
|
||||
properties: 'Thuộc tính',
|
||||
public: 'Công khai',
|
||||
publish: 'Xuất bản',
|
||||
publish_as_website: 'Xuất bản như trang web',
|
||||
puter_description: 'Puter là một đám mây cá nhân đặt quyền riêng tư lên hàng đầu để lưu trữ tất cả các tệp, ứng dụng và trò chơi của bạn trong một nơi an toàn, có thể truy cập từ mọi nơi vào bất kỳ lúc nào.',
|
||||
reading_file: 'Đang đọc %strong%',
|
||||
recover_password: 'Khôi phục mật khẩu',
|
||||
refer_friends_c2a: 'Nhận 1 GB cho mỗi người bạn tạo và xác nhận tài khoản trên Puter. Bạn của bạn cũng sẽ nhận được 1 GB!',
|
||||
refer_friends_social_media_c2a: 'Nhận 1 GB dung lượng lưu trữ miễn phí trên Puter.com!',
|
||||
refresh: 'Làm mới',
|
||||
rename: 'Đổi tên',
|
||||
replace: 'Thay thế',
|
||||
@@ -201,11 +176,9 @@ const vi = {
|
||||
save: 'Lưu',
|
||||
saturation: 'Độ bão hòa',
|
||||
save_account: 'Lưu tài khoản',
|
||||
save_account_to_get_copy_link: 'Vui lòng tạo một tài khoản để tiếp tục.',
|
||||
save_account_to_publish: 'Vui lòng tạo một tài khoản để tiếp tục.',
|
||||
save_session: 'Lưu phiên',
|
||||
save_session_c2a: 'Tạo một tài khoản để lưu phiên hiện tại của bạn và tránh mất công việc của bạn.',
|
||||
scan_qr_2fa: 'Quét mã QR bằng ứng dụng xác thực của bạn',
|
||||
search: 'Tìm kiếm',
|
||||
seconds: 'giây',
|
||||
security: 'Bảo mật',
|
||||
@@ -223,13 +196,11 @@ const vi = {
|
||||
show_hidden: 'Hiển thị mục ẩn',
|
||||
sign_in_with_puter: 'Đăng nhập bằng Puter',
|
||||
sign_up: 'Đăng ký',
|
||||
signing_in: 'Đang đăng nhập…',
|
||||
size: 'Kích thước',
|
||||
skip: 'Bỏ qua',
|
||||
something_went_wrong: 'Đã xảy ra lỗi.',
|
||||
sort_by: 'Sắp xếp theo',
|
||||
status: 'Trạng thái',
|
||||
storage_usage: 'Sử dụng bộ nhớ',
|
||||
storage_puter_used: 'đã sử dụng bởi Puter',
|
||||
taking_longer_than_usual: 'Đang mất nhiều thời gian hơn bình thường. Vui lòng đợi...',
|
||||
terms: 'Điều khoản',
|
||||
@@ -257,29 +228,23 @@ const vi = {
|
||||
videos: 'Video',
|
||||
visibility: 'Hiển thị',
|
||||
yes: 'Có',
|
||||
you_have_been_referred_to_puter_by_a_friend: 'Bạn đã được giới thiệu đến Puter bởi một người bạn!',
|
||||
zip: 'Nén',
|
||||
zipping_file: 'Đang nén %strong%',
|
||||
|
||||
// === 2FA Setup ===
|
||||
setup2fa_1_step_heading: 'Mở ứng dụng xác thực của bạn',
|
||||
setup2fa_1_instructions: `
|
||||
Bạn có thể sử dụng bất kỳ ứng dụng xác thực nào hỗ trợ giao thức Mật khẩu một lần dựa trên thời gian (TOTP).
|
||||
Có nhiều lựa chọn, nhưng nếu bạn không chắc chắn
|
||||
<a target="_blank" href="https://authy.com/download">Authy</a>
|
||||
là một lựa chọn tốt cho Android và iOS.
|
||||
`,
|
||||
setup2fa_2_step_heading: 'Quét mã QR',
|
||||
setup2fa_3_step_heading: 'Nhập mã 6 chữ số',
|
||||
setup2fa_4_step_heading: 'Sao chép mã khôi phục của bạn',
|
||||
setup2fa_4_instructions: `
|
||||
Những mã khôi phục này là cách duy nhất để truy cập tài khoản của bạn nếu bạn mất điện thoại hoặc không thể sử dụng ứng dụng xác thực.
|
||||
Hãy đảm bảo lưu trữ chúng ở một nơi an toàn.
|
||||
`,
|
||||
setup2fa_5_step_heading: 'Xác nhận thiết lập 2FA',
|
||||
setup2fa_5_confirmation_1: 'Tôi đã lưu mã khôi phục của mình ở một nơi an toàn',
|
||||
setup2fa_5_confirmation_2: 'Tôi đã sẵn sàng để bật 2FA',
|
||||
setup2fa_5_button: 'Bật 2FA',
|
||||
|
||||
// === 2FA Login ===
|
||||
login2fa_otp_title: 'Nhập mã 2FA',
|
||||
@@ -287,7 +252,6 @@ const vi = {
|
||||
login2fa_recovery_title: 'Nhập mã khôi phục',
|
||||
login2fa_recovery_instructions: 'Nhập một trong các mã khôi phục của bạn để truy cập tài khoản.',
|
||||
login2fa_use_recovery_code: 'Sử dụng mã khôi phục',
|
||||
login2fa_recovery_back: 'Quay lại',
|
||||
login2fa_recovery_placeholder: 'XXXXXXXX',
|
||||
|
||||
'change': 'Thay đổi', // In English: "Change"
|
||||
@@ -352,20 +316,13 @@ const vi = {
|
||||
'billing.expanded': 'Mở rộng', // In English: "Expanded"
|
||||
'billing.accelerated': 'Tăng tốc', // In English: "Accelerated"
|
||||
'billing.enjoy_msg': 'Tận hưởng %% Lưu trữ đám mây và các tiện ích khác.', // In English: "Enjoy %% of Cloud Storage plus other benefits."
|
||||
'choose_publishing_option': 'Chọn cách xuất bản trang web của bạn:', // In English: "Choose how you want to publish your website:"
|
||||
'create_desktop_shortcut': 'Tạo lối tắt (Desktop)', // In English: "Create Shortcut (Desktop)"
|
||||
'create_desktop_shortcut_s': 'Tạo các lối tắt (Desktop)', // In English: "Create Shortcuts (Desktop)"
|
||||
'create_shortcut_s': 'Tạo các lối tắt', // In English: "Create Shortcuts"
|
||||
'minimize': 'Thu nhỏ', // In English: "Minimize"
|
||||
'reload_app': 'Tải lại ứng dụng', // In English: "Reload App"
|
||||
'publish_as_serverless_worker': 'Xuất bản dưới dạng Worker', // In English: "Publish as Worker"
|
||||
'toolbar.enter_fullscreen': 'Vào chế độ toàn màn hình', // In English: "Enter Full Screen"
|
||||
'toolbar.github': 'GitHub', // In English: "GitHub"
|
||||
'toolbar.refer': 'Giới thiệu', // In English: "Refer"
|
||||
'used_of': '{{used}} đã dùng trong tổng {{available}}', // In English: "{{used}} used of {{available}}"
|
||||
'worker': 'Worker', // In English: "Worker"
|
||||
'billing.offering.basic': 'Gói cơ bản', // In English: "Basic"
|
||||
'too_many_attempts': 'Quá nhiều lần thử. Vui lòng thử lại sau.', // In English: "Too many attempts. Please try again later."
|
||||
'server_timeout': 'Máy chủ phản hồi quá lâu. Vui lòng thử lại.', // In English: "The server took too long to respond. Please try again."
|
||||
'signup_error': 'Có lỗi xảy ra khi đăng ký. Vui lòng thử lại.', // In English: "An error occurred during signup. Please try again."
|
||||
'alert_error_title': 'Lỗi!', // In English: "Error!"
|
||||
@@ -383,15 +340,10 @@ const vi = {
|
||||
'window_title_open': 'Mở', // In English: "Open"
|
||||
'window_title_change_password': 'Đổi mật khẩu', // In English: "Change Password"
|
||||
'window_title_select_font': 'Chọn phông chữ…', // In English: "Select font…"
|
||||
'window_title_session_list': 'Danh sách phiên!', // In English: "Session List!"
|
||||
'window_title_set_new_password': 'Đặt mật khẩu mới', // In English: "Set New Password"
|
||||
'window_title_publish_website': 'Xuất bản Trang web', // In English: "Publish Website"
|
||||
'window_title_publish_worker': 'Xuất bản Worker', // In English: "Publish Worker"
|
||||
'window_title_authenticating': 'Đang xác thực...', // In English: "Authenticating..."
|
||||
'window_title_refer_friend': 'Giới thiệu bạn bè!', // In English: "Refer a friend!"
|
||||
'desktop_exit_full_screen': 'Thoát chế độ toàn màn hình', // In English: "Exit Full Screen"
|
||||
'desktop_enter_full_screen': 'Vào chế độ toàn màn hình', // In English: "Enter Full Screen"
|
||||
'item_shared_with_you': 'Một người dùng đã chia sẻ mục này với bạn.', // In English: "A user has shared this item with you."
|
||||
'item_shared_by_you': 'Bạn đã chia sẻ mục này với ít nhất một người dùng khác.', // In English: "You have shared this item with at least one other user."
|
||||
'item_shortcut': 'Lối tắt', // In English: "Shortcut"
|
||||
'item_associated_websites': 'Trang web liên kết', // In English: "Associated website"
|
||||
@@ -400,9 +352,6 @@ const vi = {
|
||||
'window_click_to_go_back': 'Nhấp để quay lại.', // In English: "Click to go back."
|
||||
'window_click_to_go_forward': 'Nhấp để đi tiếp.', // In English: "Click to go forward."
|
||||
'window_click_to_go_up': 'Nhấp để lên thư mục cha.', // In English: "Click to go one directory up."
|
||||
'window_title_public': 'Công khai', // In English: "Public"
|
||||
'window_title_videos': 'Video', // In English: "Videos"
|
||||
'window_title_pictures': 'Hình ảnh', // In English: "Pictures"
|
||||
'window_title_puter': 'Puter', // In English: "Puter"
|
||||
'window_folder_empty': 'Thư mục này trống', // In English: "This folder is empty"
|
||||
},
|
||||
|
||||
Loaded 100 of 127 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user