mirror of
https://github.com/perfect-panel/ppanel-web.git
synced 2026-02-06 03:30:25 -05:00
Compare commits
11 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3aa1becf7a | ||
|
|
1bfebb698a | ||
|
|
d5d8d7e0df | ||
|
|
7d0866e2dc | ||
|
|
ea3964ebe5 | ||
|
|
5eac6a9f4a | ||
|
|
2182400adc | ||
|
|
5318b9cf44 | ||
|
|
705391f82a | ||
|
|
4429c9ddc9 | ||
|
|
ad60ea9b18 |
53
CHANGELOG.md
53
CHANGELOG.md
@ -1,23 +1,60 @@
|
||||
<a name="readme-top"></a>
|
||||
# Changelog
|
||||
|
||||
## [1.6.3](https://github.com/perfect-panel/ppanel-web/compare/v1.6.2...v1.6.3) (2025-12-08)
|
||||
|
||||
|
||||
### 🐛 Bug Fixes
|
||||
|
||||
* **docker**: Update Dockerfiles to create non-root user with proper permissions ([1bfebb6](https://github.com/perfect-panel/ppanel-web/commit/1bfebb6))
|
||||
|
||||
## [1.6.2](https://github.com/perfect-panel/ppanel-web/compare/v1.6.1...v1.6.2) (2025-12-08)
|
||||
|
||||
|
||||
### 🐛 Bug Fixes
|
||||
|
||||
* **package**: Update dependencies and upgrade React and Next.js versions. ([7d0866e](https://github.com/perfect-panel/ppanel-web/commit/7d0866e))
|
||||
|
||||
## [1.6.1](https://github.com/perfect-panel/ppanel-web/compare/v1.6.0...v1.6.1) (2025-11-05)
|
||||
|
||||
|
||||
### 🐛 Bug Fixes
|
||||
|
||||
* Fixing issues with generating standard and quantum-resistant encryption keys ([5eac6a9](https://github.com/perfect-panel/ppanel-web/commit/5eac6a9))
|
||||
|
||||
<a name="readme-top"></a>
|
||||
|
||||
# Changelog
|
||||
|
||||
# [1.6.0](https://github.com/perfect-panel/ppanel-web/compare/v1.5.4...v1.6.0) (2025-10-28)
|
||||
|
||||
### ✨ Features
|
||||
|
||||
- Add server installation dialog and commands ([4429c9d](https://github.com/perfect-panel/ppanel-web/commit/4429c9d))
|
||||
|
||||
### 🐛 Bug Fixes
|
||||
|
||||
- Add typeRoots configuration to ensure type definitions are resolved correctly ([ad60ea9](https://github.com/perfect-panel/ppanel-web/commit/ad60ea9))
|
||||
|
||||
<a name="readme-top"></a>
|
||||
|
||||
# Changelog
|
||||
|
||||
## [1.5.4](https://github.com/perfect-panel/ppanel-web/compare/v1.5.3...v1.5.4) (2025-10-26)
|
||||
|
||||
|
||||
### 🐛 Bug Fixes
|
||||
|
||||
* Update generateRealityKeyPair to use async key generation ([e60e369](https://github.com/perfect-panel/ppanel-web/commit/e60e369))
|
||||
* Update the wallet localization file and add new fields such as automatic reset and recharge ([88aa965](https://github.com/perfect-panel/ppanel-web/commit/88aa965))
|
||||
- Update generateRealityKeyPair to use async key generation ([e60e369](https://github.com/perfect-panel/ppanel-web/commit/e60e369))
|
||||
- Update the wallet localization file and add new fields such as automatic reset and recharge ([88aa965](https://github.com/perfect-panel/ppanel-web/commit/88aa965))
|
||||
|
||||
## [1.5.3](https://github.com/perfect-panel/ppanel-web/compare/v1.5.2...v1.5.3) (2025-10-21)
|
||||
|
||||
|
||||
### 🐛 Bug Fixes
|
||||
|
||||
* Fix bugs ([a46657d](https://github.com/perfect-panel/ppanel-web/commit/a46657d))
|
||||
* Fix dependencies ([8bd25d6](https://github.com/perfect-panel/ppanel-web/commit/8bd25d6))
|
||||
* Remove unnecessary migration function code and add device configuration options ([521a7a9](https://github.com/perfect-panel/ppanel-web/commit/521a7a9))
|
||||
* Update bun.lockb to reflect dependency changes ([ca892dd](https://github.com/perfect-panel/ppanel-web/commit/ca892dd))
|
||||
- Fix bugs ([a46657d](https://github.com/perfect-panel/ppanel-web/commit/a46657d))
|
||||
- Fix dependencies ([8bd25d6](https://github.com/perfect-panel/ppanel-web/commit/8bd25d6))
|
||||
- Remove unnecessary migration function code and add device configuration options ([521a7a9](https://github.com/perfect-panel/ppanel-web/commit/521a7a9))
|
||||
- Update bun.lockb to reflect dependency changes ([ca892dd](https://github.com/perfect-panel/ppanel-web/commit/ca892dd))
|
||||
|
||||
<a name="readme-top"></a>
|
||||
|
||||
|
||||
@ -444,7 +444,16 @@ export const PROTOCOL_FIELDS: Record<string, FieldConfig[]> = {
|
||||
placeholder: (t) => t('encryption_private_key_placeholder'),
|
||||
group: 'encryption',
|
||||
generate: {
|
||||
function: generateMLKEM768KeyPair,
|
||||
functions: [
|
||||
{
|
||||
label: (t) => t('generate_standard_encryption_key'),
|
||||
function: generateRealityKeyPair,
|
||||
},
|
||||
{
|
||||
label: (t) => t('generate_quantum_resistant_key'),
|
||||
function: generateMLKEM768KeyPair,
|
||||
},
|
||||
],
|
||||
updateFields: {
|
||||
encryption_private_key: 'privateKey',
|
||||
encryption_password: 'publicKey',
|
||||
|
||||
@ -12,7 +12,11 @@ export type FieldConfig = {
|
||||
step?: number;
|
||||
suffix?: string;
|
||||
generate?: {
|
||||
function: () => Promise<string | Record<string, string>> | string | Record<string, string>;
|
||||
function?: () => Promise<string | Record<string, string>> | string | Record<string, string>;
|
||||
functions?: {
|
||||
label: string | ((t: (key: string) => string, protocol: any) => string);
|
||||
function: () => Promise<string | Record<string, string>> | string | Record<string, string>;
|
||||
}[];
|
||||
updateFields?: Record<string, string>;
|
||||
};
|
||||
condition?: (protocol: any, values: any) => boolean;
|
||||
|
||||
@ -1,11 +1,11 @@
|
||||
import * as x25519 from '@noble/ed25519';
|
||||
import { x25519 } from '@noble/curves/ed25519.js';
|
||||
import { toB64Url } from './util';
|
||||
|
||||
/**
|
||||
* Generate a Reality key pair
|
||||
* @returns An object containing the private and public keys in base64url format
|
||||
*/
|
||||
export async function generateRealityKeyPair() {
|
||||
const { secretKey, publicKey } = await x25519.keygenAsync();
|
||||
export function generateRealityKeyPair() {
|
||||
const { secretKey, publicKey } = x25519.keygen();
|
||||
return { privateKey: toB64Url(secretKey), publicKey: toB64Url(publicKey) };
|
||||
}
|
||||
|
||||
@ -21,6 +21,7 @@ import DynamicMultiplier from './dynamic-multiplier';
|
||||
import OnlineUsersCell from './online-users-cell';
|
||||
import ServerConfig from './server-config';
|
||||
import ServerForm from './server-form';
|
||||
import ServerInstall from './server-install';
|
||||
|
||||
function PctBar({ value }: { value: number }) {
|
||||
const v = value.toFixed(2);
|
||||
@ -60,7 +61,6 @@ export default function ServersPage() {
|
||||
const { fetchServers } = useServer();
|
||||
|
||||
const [loading, setLoading] = useState(false);
|
||||
const [migrating, setMigrating] = useState(false);
|
||||
const ref = useRef<ProTableActions>(null);
|
||||
|
||||
return (
|
||||
@ -224,6 +224,7 @@ export default function ServersPage() {
|
||||
}
|
||||
}}
|
||||
/>,
|
||||
<ServerInstall key='install' server={row} />,
|
||||
<ConfirmButton
|
||||
key='delete'
|
||||
trigger={
|
||||
|
||||
@ -10,6 +10,12 @@ import {
|
||||
} from '@workspace/ui/components/accordion';
|
||||
import { Badge } from '@workspace/ui/components/badge';
|
||||
import { Button } from '@workspace/ui/components/button';
|
||||
import {
|
||||
DropdownMenu,
|
||||
DropdownMenuContent,
|
||||
DropdownMenuItem,
|
||||
DropdownMenuTrigger,
|
||||
} from '@workspace/ui/components/dropdown-menu';
|
||||
import {
|
||||
Form,
|
||||
FormControl,
|
||||
@ -99,29 +105,68 @@ function DynamicField({
|
||||
onValueChange={(v) => fieldProps.onChange(v)}
|
||||
suffix={
|
||||
field.generate ? (
|
||||
<Button
|
||||
type='button'
|
||||
variant='ghost'
|
||||
onClick={async () => {
|
||||
const result = await field.generate!.function();
|
||||
if (typeof result === 'string') {
|
||||
fieldProps.onChange(result);
|
||||
} else if (field.generate!.updateFields) {
|
||||
Object.entries(field.generate!.updateFields).forEach(
|
||||
([fieldName, resultKey]) => {
|
||||
const fullFieldName = `protocols.${protocolIndex}.${fieldName}`;
|
||||
form.setValue(fullFieldName, (result as any)[resultKey]);
|
||||
},
|
||||
);
|
||||
} else {
|
||||
if (result.privateKey) {
|
||||
fieldProps.onChange(result.privateKey);
|
||||
field.generate.functions && field.generate.functions.length > 0 ? (
|
||||
<DropdownMenu>
|
||||
<DropdownMenuTrigger asChild>
|
||||
<Button type='button' variant='ghost' size='sm'>
|
||||
<Icon icon='mdi:key' className='h-4 w-4' />
|
||||
</Button>
|
||||
</DropdownMenuTrigger>
|
||||
<DropdownMenuContent align='end'>
|
||||
{field.generate.functions.map((genFunc, idx) => (
|
||||
<DropdownMenuItem
|
||||
key={idx}
|
||||
onClick={async () => {
|
||||
const result = await genFunc.function();
|
||||
if (typeof result === 'string') {
|
||||
fieldProps.onChange(result);
|
||||
} else if (field.generate!.updateFields) {
|
||||
Object.entries(field.generate!.updateFields).forEach(
|
||||
([fieldName, resultKey]) => {
|
||||
const fullFieldName = `protocols.${protocolIndex}.${fieldName}`;
|
||||
form.setValue(fullFieldName, (result as any)[resultKey]);
|
||||
},
|
||||
);
|
||||
} else {
|
||||
if (result.privateKey) {
|
||||
fieldProps.onChange(result.privateKey);
|
||||
}
|
||||
}
|
||||
}}
|
||||
>
|
||||
{typeof genFunc.label === 'function'
|
||||
? genFunc.label(t, protocolData)
|
||||
: genFunc.label}
|
||||
</DropdownMenuItem>
|
||||
))}
|
||||
</DropdownMenuContent>
|
||||
</DropdownMenu>
|
||||
) : field.generate.function ? (
|
||||
<Button
|
||||
type='button'
|
||||
variant='ghost'
|
||||
size='sm'
|
||||
onClick={async () => {
|
||||
const result = await field.generate!.function!();
|
||||
if (typeof result === 'string') {
|
||||
fieldProps.onChange(result);
|
||||
} else if (field.generate!.updateFields) {
|
||||
Object.entries(field.generate!.updateFields).forEach(
|
||||
([fieldName, resultKey]) => {
|
||||
const fullFieldName = `protocols.${protocolIndex}.${fieldName}`;
|
||||
form.setValue(fullFieldName, (result as any)[resultKey]);
|
||||
},
|
||||
);
|
||||
} else {
|
||||
if (result.privateKey) {
|
||||
fieldProps.onChange(result.privateKey);
|
||||
}
|
||||
}
|
||||
}
|
||||
}}
|
||||
>
|
||||
<Icon icon='mdi:key' className='h-4 w-4' />
|
||||
</Button>
|
||||
}}
|
||||
>
|
||||
<Icon icon='mdi:key' className='h-4 w-4' />
|
||||
</Button>
|
||||
) : null
|
||||
) : (
|
||||
field.suffix
|
||||
)
|
||||
@ -356,7 +401,8 @@ export default function ServerForm(props: {
|
||||
...initialValues,
|
||||
protocols: PROTOCOLS.map((type) => {
|
||||
const existingProtocol = initialValues.protocols?.find((p) => p.type === type);
|
||||
return existingProtocol || getProtocolDefaultConfig(type);
|
||||
const defaultConfig = getProtocolDefaultConfig(type);
|
||||
return existingProtocol ? { ...defaultConfig, ...existingProtocol } : defaultConfig;
|
||||
}),
|
||||
});
|
||||
}
|
||||
|
||||
119
apps/admin/app/dashboard/servers/server-install.tsx
Normal file
119
apps/admin/app/dashboard/servers/server-install.tsx
Normal file
@ -0,0 +1,119 @@
|
||||
'use client';
|
||||
|
||||
import { getNodeConfig } from '@/services/admin/system';
|
||||
import { useQuery } from '@tanstack/react-query';
|
||||
import { Button } from '@workspace/ui/components/button';
|
||||
import {
|
||||
Dialog,
|
||||
DialogContent,
|
||||
DialogFooter,
|
||||
DialogHeader,
|
||||
DialogTitle,
|
||||
DialogTrigger,
|
||||
} from '@workspace/ui/components/dialog';
|
||||
import { Input } from '@workspace/ui/components/input';
|
||||
import { Label } from '@workspace/ui/components/label';
|
||||
import { useTranslations } from 'next-intl';
|
||||
import React, { useCallback, useEffect, useMemo, useState } from 'react';
|
||||
import { toast } from 'sonner';
|
||||
|
||||
type Props = {
|
||||
server: API.Server;
|
||||
};
|
||||
|
||||
export default function ServerInstall({ server }: Props) {
|
||||
const t = useTranslations('servers');
|
||||
const [open, setOpen] = useState(false);
|
||||
const [domain, setDomain] = useState('');
|
||||
|
||||
const { data: cfgResp } = useQuery({
|
||||
queryKey: ['getNodeConfig'],
|
||||
queryFn: async () => {
|
||||
const { data } = await getNodeConfig();
|
||||
return data.data as API.NodeConfig | undefined;
|
||||
},
|
||||
enabled: open,
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
if (open) {
|
||||
const host = localStorage.getItem('API_HOST') ?? window.location.origin;
|
||||
setDomain(host);
|
||||
}
|
||||
}, [open]);
|
||||
|
||||
const installCommand = useMemo(() => {
|
||||
const secret = cfgResp?.node_secret ?? '';
|
||||
return `wget -N https://raw.githubusercontent.com/perfect-panel/ppanel-node/master/scripts/install.sh && bash install.sh --api-host ${domain} --server-id ${server.id} --secret-key ${secret}`;
|
||||
}, [domain, server.id, cfgResp?.node_secret]);
|
||||
|
||||
async function handleCopy() {
|
||||
try {
|
||||
if (navigator?.clipboard?.writeText) {
|
||||
await navigator.clipboard.writeText(installCommand);
|
||||
} else {
|
||||
// fallback for environments without clipboard API
|
||||
const el = document.createElement('textarea');
|
||||
el.value = installCommand;
|
||||
document.body.appendChild(el);
|
||||
el.select();
|
||||
document.execCommand('copy');
|
||||
document.body.removeChild(el);
|
||||
}
|
||||
toast.success(t('copied'));
|
||||
setOpen(false);
|
||||
} catch (error) {
|
||||
toast.error(t('copyFailed'));
|
||||
}
|
||||
}
|
||||
|
||||
const onDomainChange = useCallback((e: React.ChangeEvent<HTMLInputElement>) => {
|
||||
setDomain(e.target.value);
|
||||
localStorage.setItem('API_HOST', e.target.value);
|
||||
}, []);
|
||||
return (
|
||||
<Dialog open={open} onOpenChange={setOpen}>
|
||||
<DialogTrigger asChild>
|
||||
<Button variant='secondary'>{t('connect')}</Button>
|
||||
</DialogTrigger>
|
||||
|
||||
<DialogContent className='w-[720px] max-w-full md:max-w-screen-md'>
|
||||
<DialogHeader>
|
||||
<DialogTitle>{t('oneClickInstall')}</DialogTitle>
|
||||
</DialogHeader>
|
||||
|
||||
<div className='space-y-4'>
|
||||
<div>
|
||||
<Label>{t('apiHost')}</Label>
|
||||
<div className='flex items-center gap-2'>
|
||||
<Input
|
||||
value={domain}
|
||||
placeholder={t('apiHostPlaceholder')}
|
||||
onChange={onDomainChange}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<Label>{t('installCommand')}</Label>
|
||||
<div className='flex flex-col gap-2'>
|
||||
<textarea
|
||||
readOnly
|
||||
aria-label={t('installCommand')}
|
||||
value={installCommand}
|
||||
className='min-h-[88px] w-full rounded border p-2 font-mono text-sm'
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<DialogFooter className='flex-row justify-end gap-2 pt-3'>
|
||||
<Button variant='outline' onClick={() => setOpen(false)}>
|
||||
{t('close')}
|
||||
</Button>
|
||||
<Button onClick={handleCopy}>{t('copyAndClose')}</Button>
|
||||
</DialogFooter>
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
);
|
||||
}
|
||||
@ -5,6 +5,8 @@
|
||||
},
|
||||
"address": "Adresa",
|
||||
"address_placeholder": "Adresa serveru",
|
||||
"apiHost": "API hostitel",
|
||||
"apiHostPlaceholder": "http(s)://example.com",
|
||||
"bandwidth_placeholder": "Zadejte šířku pásma, nechte prázdné pro BBR",
|
||||
"basic": "Základní konfigurace",
|
||||
"cancel": "Zrušit",
|
||||
@ -17,6 +19,7 @@
|
||||
"confirmDeleteDesc": "Tuto akci nelze vrátit zpět.",
|
||||
"confirmDeleteTitle": "Smazat tento server?",
|
||||
"congestion_controller": "Ovladač přetížení",
|
||||
"connect": "Připojit",
|
||||
"copied": "Zkopírováno",
|
||||
"copy": "Kopírovat",
|
||||
"country": "Země",
|
||||
@ -47,11 +50,14 @@
|
||||
"expired": "Vypršelo",
|
||||
"extra": "Další konfigurace",
|
||||
"flow": "Tok",
|
||||
"generate_quantum_resistant_key": "Generovat kvantově odolný klíč",
|
||||
"generate_standard_encryption_key": "Generovat standardní šifrovací klíč",
|
||||
"hop_interval": "Interval skoku",
|
||||
"hop_ports": "Porty skoku",
|
||||
"hop_ports_placeholder": "např. 1-65535",
|
||||
"host": "Hostitel",
|
||||
"id": "ID",
|
||||
"installCommand": "Instalační příkaz",
|
||||
"ipAddresses": "IP adresy",
|
||||
"memory": "Paměť",
|
||||
"migrate": "Migrace dat",
|
||||
@ -69,6 +75,7 @@
|
||||
"obfs_password_placeholder": "Zadejte heslo pro obfuskaci",
|
||||
"obfs_path": "Obfs cesta",
|
||||
"offline": "Offline",
|
||||
"oneClickInstall": "Instalace jedním kliknutím",
|
||||
"online": "Online",
|
||||
"onlineUsers": "Online uživatelé",
|
||||
"padding_scheme": "Schéma vycpání",
|
||||
|
||||
@ -5,6 +5,8 @@
|
||||
},
|
||||
"address": "Adresse",
|
||||
"address_placeholder": "Serveradresse",
|
||||
"apiHost": "API-Host",
|
||||
"apiHostPlaceholder": "http(s)://beispiel.de",
|
||||
"bandwidth_placeholder": "Geben Sie die Bandbreite ein, lassen Sie das Feld leer für BBR",
|
||||
"basic": "Grundkonfiguration",
|
||||
"cancel": "Abbrechen",
|
||||
@ -17,6 +19,7 @@
|
||||
"confirmDeleteDesc": "Diese Aktion kann nicht rückgängig gemacht werden.",
|
||||
"confirmDeleteTitle": "Diesen Server löschen?",
|
||||
"congestion_controller": "Staukontroller",
|
||||
"connect": "Verbinden",
|
||||
"copied": "Kopiert",
|
||||
"copy": "Kopieren",
|
||||
"country": "Land",
|
||||
@ -47,11 +50,14 @@
|
||||
"expired": "Abgelaufen",
|
||||
"extra": "Zusätzliche Konfiguration",
|
||||
"flow": "Fluss",
|
||||
"generate_quantum_resistant_key": "Quantenresistenten Schlüssel generieren",
|
||||
"generate_standard_encryption_key": "Standard-Verschlüsselungsschlüssel generieren",
|
||||
"hop_interval": "Hop-Intervall",
|
||||
"hop_ports": "Hop-Ports",
|
||||
"hop_ports_placeholder": "z.B. 1-65535",
|
||||
"host": "Host",
|
||||
"id": "ID",
|
||||
"installCommand": "Installationsbefehl",
|
||||
"ipAddresses": "IP-Adressen",
|
||||
"memory": "Speicher",
|
||||
"migrate": "Daten migrieren",
|
||||
@ -69,6 +75,7 @@
|
||||
"obfs_password_placeholder": "Obfuskationspasswort eingeben",
|
||||
"obfs_path": "Obfs-Pfad",
|
||||
"offline": "Offline",
|
||||
"oneClickInstall": "Ein-Klick-Installation",
|
||||
"online": "Online",
|
||||
"onlineUsers": "Online-Benutzer",
|
||||
"padding_scheme": "Polsterungsschema",
|
||||
|
||||
@ -5,6 +5,8 @@
|
||||
},
|
||||
"address": "Address",
|
||||
"address_placeholder": "Server address",
|
||||
"apiHost": "API Host",
|
||||
"apiHostPlaceholder": "http(s)://example.com",
|
||||
"bandwidth_placeholder": "Enter bandwidth, leave empty for BBR",
|
||||
"basic": "Basic Configuration",
|
||||
"cancel": "Cancel",
|
||||
@ -17,6 +19,7 @@
|
||||
"confirmDeleteDesc": "This action cannot be undone.",
|
||||
"confirmDeleteTitle": "Delete this server?",
|
||||
"congestion_controller": "Congestion controller",
|
||||
"connect": "Connect",
|
||||
"copied": "Copied",
|
||||
"copy": "Copy",
|
||||
"country": "Country",
|
||||
@ -47,11 +50,14 @@
|
||||
"expired": "Expired",
|
||||
"extra": "Extra Configuration",
|
||||
"flow": "Flow",
|
||||
"generate_quantum_resistant_key": "Generate Quantum-Resistant Key",
|
||||
"generate_standard_encryption_key": "Generate Standard Encryption Key",
|
||||
"hop_interval": "Hop interval",
|
||||
"hop_ports": "Hop ports",
|
||||
"hop_ports_placeholder": "e.g. 1-65535",
|
||||
"host": "Host",
|
||||
"id": "ID",
|
||||
"installCommand": "Install command",
|
||||
"ipAddresses": "IP addresses",
|
||||
"memory": "Memory",
|
||||
"migrate": "Migrate Data",
|
||||
@ -69,6 +75,7 @@
|
||||
"obfs_password_placeholder": "Enter obfuscation password",
|
||||
"obfs_path": "Obfs Path",
|
||||
"offline": "Offline",
|
||||
"oneClickInstall": "One-click Install",
|
||||
"online": "Online",
|
||||
"onlineUsers": "Online users",
|
||||
"padding_scheme": "Padding Scheme",
|
||||
|
||||
@ -5,6 +5,8 @@
|
||||
},
|
||||
"address": "Dirección",
|
||||
"address_placeholder": "Dirección del servidor",
|
||||
"apiHost": "Host de API",
|
||||
"apiHostPlaceholder": "http(s)://ejemplo.com",
|
||||
"bandwidth_placeholder": "Introduce el ancho de banda, deja vacío para BBR",
|
||||
"basic": "Configuración Básica",
|
||||
"cancel": "Cancelar",
|
||||
@ -17,6 +19,7 @@
|
||||
"confirmDeleteDesc": "Esta acción no se puede deshacer.",
|
||||
"confirmDeleteTitle": "¿Eliminar este servidor?",
|
||||
"congestion_controller": "Controlador de congestión",
|
||||
"connect": "Conectar",
|
||||
"copied": "Copiado",
|
||||
"copy": "Copiar",
|
||||
"country": "País",
|
||||
@ -47,11 +50,14 @@
|
||||
"expired": "Expirado",
|
||||
"extra": "Configuración Extra",
|
||||
"flow": "Flujo",
|
||||
"generate_quantum_resistant_key": "Generar clave resistente a cuánticos",
|
||||
"generate_standard_encryption_key": "Generar clave de cifrado estándar",
|
||||
"hop_interval": "Intervalo de salto",
|
||||
"hop_ports": "Puertos de salto",
|
||||
"hop_ports_placeholder": "p. ej. 1-65535",
|
||||
"host": "Host",
|
||||
"id": "ID",
|
||||
"installCommand": "Comando de instalación",
|
||||
"ipAddresses": "Direcciones IP",
|
||||
"memory": "Memoria",
|
||||
"migrate": "Migrar datos",
|
||||
@ -69,6 +75,7 @@
|
||||
"obfs_password_placeholder": "Ingrese la contraseña de ofuscación",
|
||||
"obfs_path": "Ruta de Ofuscación",
|
||||
"offline": "Desconectado",
|
||||
"oneClickInstall": "Instalación con un clic",
|
||||
"online": "Conectado",
|
||||
"onlineUsers": "Usuarios en línea",
|
||||
"padding_scheme": "Esquema de Relleno",
|
||||
|
||||
@ -5,6 +5,8 @@
|
||||
},
|
||||
"address": "Dirección",
|
||||
"address_placeholder": "Dirección del servidor",
|
||||
"apiHost": "Host de API",
|
||||
"apiHostPlaceholder": "http(s)://ejemplo.com",
|
||||
"bandwidth_placeholder": "Ingresa el ancho de banda, deja vacío para BBR",
|
||||
"basic": "Configuración Básica",
|
||||
"cancel": "Cancelar",
|
||||
@ -17,6 +19,7 @@
|
||||
"confirmDeleteDesc": "Esta acción no se puede deshacer.",
|
||||
"confirmDeleteTitle": "¿Eliminar este servidor?",
|
||||
"congestion_controller": "Controlador de congestión",
|
||||
"connect": "Conectar",
|
||||
"copied": "Copiado",
|
||||
"copy": "Copiar",
|
||||
"country": "País",
|
||||
@ -47,11 +50,14 @@
|
||||
"expired": "Expirado",
|
||||
"extra": "Configuración Extra",
|
||||
"flow": "Flujo",
|
||||
"generate_quantum_resistant_key": "Generar clave resistente a cuánticos",
|
||||
"generate_standard_encryption_key": "Generar clave de cifrado estándar",
|
||||
"hop_interval": "Intervalo de salto",
|
||||
"hop_ports": "Puertos de salto",
|
||||
"hop_ports_placeholder": "p. ej. 1-65535",
|
||||
"host": "Host",
|
||||
"id": "ID",
|
||||
"installCommand": "Comando de instalación",
|
||||
"ipAddresses": "Direcciones IP",
|
||||
"memory": "Memoria",
|
||||
"migrate": "Migrar datos",
|
||||
@ -69,6 +75,7 @@
|
||||
"obfs_password_placeholder": "Ingresa la contraseña de ofuscación",
|
||||
"obfs_path": "Ruta de Ofuscación",
|
||||
"offline": "Desconectado",
|
||||
"oneClickInstall": "Instalación con un clic",
|
||||
"online": "Conectado",
|
||||
"onlineUsers": "Usuarios en línea",
|
||||
"padding_scheme": "Esquema de Relleno",
|
||||
|
||||
@ -5,6 +5,8 @@
|
||||
},
|
||||
"address": "آدرس",
|
||||
"address_placeholder": "آدرس سرور",
|
||||
"apiHost": "میزبان API",
|
||||
"apiHostPlaceholder": "http(s)://example.com",
|
||||
"bandwidth_placeholder": "عرض پهنای باند، برای BBR خالی بگذارید",
|
||||
"basic": "پیکربندی پایه",
|
||||
"cancel": "لغو",
|
||||
@ -17,6 +19,7 @@
|
||||
"confirmDeleteDesc": "این عمل قابل بازگشت نیست.",
|
||||
"confirmDeleteTitle": "آیا این سرور را حذف کنید؟",
|
||||
"congestion_controller": "کنترلکننده ترافیک",
|
||||
"connect": "اتصال",
|
||||
"copied": "کپی شد",
|
||||
"copy": "کپی",
|
||||
"country": "کشور",
|
||||
@ -47,11 +50,14 @@
|
||||
"expired": "منقضی شده",
|
||||
"extra": "پیکربندی اضافی",
|
||||
"flow": "جریان",
|
||||
"generate_quantum_resistant_key": "تولید کلید مقاوم در برابر کوانتوم",
|
||||
"generate_standard_encryption_key": "تولید کلید رمزگذاری استاندارد",
|
||||
"hop_interval": "فاصله پرش",
|
||||
"hop_ports": "پورتهای پرش",
|
||||
"hop_ports_placeholder": "مثلاً 1-65535",
|
||||
"host": "میزبان",
|
||||
"id": "شناسه",
|
||||
"installCommand": "دستور نصب",
|
||||
"ipAddresses": "آدرسهای IP",
|
||||
"memory": "حافظه",
|
||||
"migrate": "انتقال داده",
|
||||
@ -69,6 +75,7 @@
|
||||
"obfs_password_placeholder": "رمز عبور اختفا را وارد کنید",
|
||||
"obfs_path": "مسیر پنهانسازی",
|
||||
"offline": "آفلاین",
|
||||
"oneClickInstall": "نصب با یک کلیک",
|
||||
"online": "آنلاین",
|
||||
"onlineUsers": "کاربران آنلاین",
|
||||
"padding_scheme": "طرح پدینگ",
|
||||
|
||||
@ -5,6 +5,8 @@
|
||||
},
|
||||
"address": "Osoite",
|
||||
"address_placeholder": "Palvelimen osoite",
|
||||
"apiHost": "API-isäntä",
|
||||
"apiHostPlaceholder": "http(s)://esimerkki.com",
|
||||
"bandwidth_placeholder": "Syötä kaistanleveys, jätä tyhjäksi BBR:lle",
|
||||
"basic": "Perusasetukset",
|
||||
"cancel": "Peruuta",
|
||||
@ -17,6 +19,7 @@
|
||||
"confirmDeleteDesc": "Tätä toimintoa ei voi peruuttaa.",
|
||||
"confirmDeleteTitle": "Poista tämä palvelin?",
|
||||
"congestion_controller": "Ruuhkansäätö",
|
||||
"connect": "Yhdistä",
|
||||
"copied": "Kopioitu",
|
||||
"copy": "Kopioi",
|
||||
"country": "Maa",
|
||||
@ -47,11 +50,14 @@
|
||||
"expired": "Vanhentunut",
|
||||
"extra": "Lisäasetukset",
|
||||
"flow": "Virta",
|
||||
"generate_quantum_resistant_key": "Luo kvanttikestävä avain",
|
||||
"generate_standard_encryption_key": "Luo standardi salausavain",
|
||||
"hop_interval": "Hyppyvälit",
|
||||
"hop_ports": "Hyppysatamat",
|
||||
"hop_ports_placeholder": "esim. 1-65535",
|
||||
"host": "Isäntä",
|
||||
"id": "ID",
|
||||
"installCommand": "Asennuskomento",
|
||||
"ipAddresses": "IP-osoitteet",
|
||||
"memory": "Muisti",
|
||||
"migrate": "Siirrä tiedot",
|
||||
@ -69,6 +75,7 @@
|
||||
"obfs_password_placeholder": "Syötä häilytyssalasana",
|
||||
"obfs_path": "Häilytys polku",
|
||||
"offline": "Offline",
|
||||
"oneClickInstall": "Yhden napsautuksen asennus",
|
||||
"online": "Online",
|
||||
"onlineUsers": "Verkossa olevat käyttäjät",
|
||||
"padding_scheme": "Täyttökaavio",
|
||||
|
||||
@ -5,6 +5,8 @@
|
||||
},
|
||||
"address": "Adresse",
|
||||
"address_placeholder": "Adresse du serveur",
|
||||
"apiHost": "Hôte API",
|
||||
"apiHostPlaceholder": "http(s)://exemple.com",
|
||||
"bandwidth_placeholder": "Entrez la bande passante, laissez vide pour BBR",
|
||||
"basic": "Configuration de base",
|
||||
"cancel": "Annuler",
|
||||
@ -17,6 +19,7 @@
|
||||
"confirmDeleteDesc": "Cette action ne peut pas être annulée.",
|
||||
"confirmDeleteTitle": "Supprimer ce serveur ?",
|
||||
"congestion_controller": "Contrôleur de congestion",
|
||||
"connect": "Se connecter",
|
||||
"copied": "Copié",
|
||||
"copy": "Copier",
|
||||
"country": "Pays",
|
||||
@ -47,11 +50,14 @@
|
||||
"expired": "Expiré",
|
||||
"extra": "Configuration supplémentaire",
|
||||
"flow": "Flux",
|
||||
"generate_quantum_resistant_key": "Générer une clé résistante aux quantiques",
|
||||
"generate_standard_encryption_key": "Générer une clé de chiffrement standard",
|
||||
"hop_interval": "Intervalle de saut",
|
||||
"hop_ports": "Ports de saut",
|
||||
"hop_ports_placeholder": "ex. 1-65535",
|
||||
"host": "Hôte",
|
||||
"id": "ID",
|
||||
"installCommand": "Commande d'installation",
|
||||
"ipAddresses": "Adresses IP",
|
||||
"memory": "Mémoire",
|
||||
"migrate": "Migrer les données",
|
||||
@ -69,6 +75,7 @@
|
||||
"obfs_password_placeholder": "Entrez le mot de passe d'obfuscation",
|
||||
"obfs_path": "Chemin Obfs",
|
||||
"offline": "Hors ligne",
|
||||
"oneClickInstall": "Installation en un clic",
|
||||
"online": "En ligne",
|
||||
"onlineUsers": "Utilisateurs en ligne",
|
||||
"padding_scheme": "Schéma de remplissage",
|
||||
|
||||
@ -5,6 +5,8 @@
|
||||
},
|
||||
"address": "पता",
|
||||
"address_placeholder": "सर्वर का पता",
|
||||
"apiHost": "एपीआई होस्ट",
|
||||
"apiHostPlaceholder": "http(s)://example.com",
|
||||
"bandwidth_placeholder": "बैंडविड्थ दर्ज करें, BBR के लिए खाली छोड़ें",
|
||||
"basic": "बुनियादी कॉन्फ़िगरेशन",
|
||||
"cancel": "रद्द करें",
|
||||
@ -17,6 +19,7 @@
|
||||
"confirmDeleteDesc": "यह क्रिया पूर्ववत नहीं की जा सकती।",
|
||||
"confirmDeleteTitle": "क्या इस सर्वर को हटाएं?",
|
||||
"congestion_controller": "भीड़ नियंत्रण",
|
||||
"connect": "जोड़ें",
|
||||
"copied": "कॉपी किया गया",
|
||||
"copy": "कॉपी करें",
|
||||
"country": "देश",
|
||||
@ -47,11 +50,14 @@
|
||||
"expired": "समय समाप्त",
|
||||
"extra": "अतिरिक्त कॉन्फ़िगरेशन",
|
||||
"flow": "प्रवाह",
|
||||
"generate_quantum_resistant_key": "क्वांटम-प्रतिरोधी कुंजी उत्पन्न करें",
|
||||
"generate_standard_encryption_key": "मानक एन्क्रिप्शन कुंजी उत्पन्न करें",
|
||||
"hop_interval": "हॉप अंतराल",
|
||||
"hop_ports": "हॉप पोर्ट",
|
||||
"hop_ports_placeholder": "जैसे 1-65535",
|
||||
"host": "होस्ट",
|
||||
"id": "आईडी",
|
||||
"installCommand": "इंस्टॉल कमांड",
|
||||
"ipAddresses": "आईपी पते",
|
||||
"memory": "मेमोरी",
|
||||
"migrate": "डेटा माइग्रेट करें",
|
||||
@ -69,6 +75,7 @@
|
||||
"obfs_password_placeholder": "अवशोषण पासवर्ड दर्ज करें",
|
||||
"obfs_path": "ओबफ्स पथ",
|
||||
"offline": "ऑफलाइन",
|
||||
"oneClickInstall": "एक-क्लिक इंस्टॉलेशन",
|
||||
"online": "ऑनलाइन",
|
||||
"onlineUsers": "ऑनलाइन उपयोगकर्ता",
|
||||
"padding_scheme": "पैडिंग योजना",
|
||||
|
||||
@ -5,6 +5,8 @@
|
||||
},
|
||||
"address": "Cím",
|
||||
"address_placeholder": "Szerver cím",
|
||||
"apiHost": "API gazda",
|
||||
"apiHostPlaceholder": "http(s)://pelda.com",
|
||||
"bandwidth_placeholder": "Adja meg a sávszélességet, hagyja üresen a BBR-hez",
|
||||
"basic": "Alapértelmezett Beállítások",
|
||||
"cancel": "Mégse",
|
||||
@ -17,6 +19,7 @@
|
||||
"confirmDeleteDesc": "Ez a művelet nem vonható vissza.",
|
||||
"confirmDeleteTitle": "Törölni szeretné ezt a szervert?",
|
||||
"congestion_controller": "Torlaszkezelő",
|
||||
"connect": "Csatlakozás",
|
||||
"copied": "Másolva",
|
||||
"copy": "Másolás",
|
||||
"country": "Ország",
|
||||
@ -47,11 +50,14 @@
|
||||
"expired": "Lejárt",
|
||||
"extra": "További konfiguráció",
|
||||
"flow": "Forgalom",
|
||||
"generate_quantum_resistant_key": "Kvantumálló kulcs generálása",
|
||||
"generate_standard_encryption_key": "Szabványos titkosítási kulcs generálása",
|
||||
"hop_interval": "Ugrás időköz",
|
||||
"hop_ports": "Ugrás portok",
|
||||
"hop_ports_placeholder": "pl. 1-65535",
|
||||
"host": "Gazda",
|
||||
"id": "ID",
|
||||
"installCommand": "Telepítési parancs",
|
||||
"ipAddresses": "IP címek",
|
||||
"memory": "Memória",
|
||||
"migrate": "Adatok migrálása",
|
||||
@ -69,6 +75,7 @@
|
||||
"obfs_password_placeholder": "Adja meg az obfuszkálás jelszót",
|
||||
"obfs_path": "Obfs útvonal",
|
||||
"offline": "Offline",
|
||||
"oneClickInstall": "Egylépéses telepítés",
|
||||
"online": "Online",
|
||||
"onlineUsers": "Online felhasználók",
|
||||
"padding_scheme": "Kitöltési Sémák",
|
||||
|
||||
@ -5,6 +5,8 @@
|
||||
},
|
||||
"address": "アドレス",
|
||||
"address_placeholder": "サーバーアドレス",
|
||||
"apiHost": "APIホスト",
|
||||
"apiHostPlaceholder": "http(s)://example.com",
|
||||
"bandwidth_placeholder": "帯域幅を入力してください。BBRの場合は空白のままにしてください。",
|
||||
"basic": "基本設定",
|
||||
"cancel": "キャンセル",
|
||||
@ -17,6 +19,7 @@
|
||||
"confirmDeleteDesc": "この操作は元に戻せません。",
|
||||
"confirmDeleteTitle": "このサーバーを削除しますか?",
|
||||
"congestion_controller": "混雑制御",
|
||||
"connect": "接続",
|
||||
"copied": "コピーしました",
|
||||
"copy": "コピー",
|
||||
"country": "国",
|
||||
@ -47,11 +50,14 @@
|
||||
"expired": "期限切れ",
|
||||
"extra": "追加設定",
|
||||
"flow": "フロー",
|
||||
"generate_quantum_resistant_key": "量子耐性キーを生成",
|
||||
"generate_standard_encryption_key": "標準暗号化キーを生成",
|
||||
"hop_interval": "ホップ間隔",
|
||||
"hop_ports": "ホップポート",
|
||||
"hop_ports_placeholder": "例: 1-65535",
|
||||
"host": "ホスト",
|
||||
"id": "ID",
|
||||
"installCommand": "インストールコマンド",
|
||||
"ipAddresses": "IPアドレス",
|
||||
"memory": "メモリ",
|
||||
"migrate": "データを移行する",
|
||||
@ -69,6 +75,7 @@
|
||||
"obfs_password_placeholder": "難読化パスワードを入力してください",
|
||||
"obfs_path": "難読化パス",
|
||||
"offline": "オフライン",
|
||||
"oneClickInstall": "ワンクリックインストール",
|
||||
"online": "オンライン",
|
||||
"onlineUsers": "オンラインユーザー",
|
||||
"padding_scheme": "パディングスキーム",
|
||||
|
||||
@ -5,6 +5,8 @@
|
||||
},
|
||||
"address": "주소",
|
||||
"address_placeholder": "서버 주소",
|
||||
"apiHost": "API 호스트",
|
||||
"apiHostPlaceholder": "http(s)://example.com",
|
||||
"bandwidth_placeholder": "대역폭을 입력하세요. BBR을 사용하려면 비워 두세요.",
|
||||
"basic": "기본 설정",
|
||||
"cancel": "취소",
|
||||
@ -17,6 +19,7 @@
|
||||
"confirmDeleteDesc": "이 작업은 실행 취소할 수 없습니다.",
|
||||
"confirmDeleteTitle": "이 서버를 삭제하시겠습니까?",
|
||||
"congestion_controller": "혼잡 제어기",
|
||||
"connect": "연결",
|
||||
"copied": "복사됨",
|
||||
"copy": "복사",
|
||||
"country": "국가",
|
||||
@ -47,11 +50,14 @@
|
||||
"expired": "만료됨",
|
||||
"extra": "추가 구성",
|
||||
"flow": "흐름",
|
||||
"generate_quantum_resistant_key": "양자 저항 키 생성",
|
||||
"generate_standard_encryption_key": "표준 암호화 키 생성",
|
||||
"hop_interval": "홉 간격",
|
||||
"hop_ports": "홉 포트",
|
||||
"hop_ports_placeholder": "예: 1-65535",
|
||||
"host": "호스트",
|
||||
"id": "ID",
|
||||
"installCommand": "설치 명령",
|
||||
"ipAddresses": "IP 주소",
|
||||
"memory": "메모리",
|
||||
"migrate": "데이터 마이그레이션",
|
||||
@ -69,6 +75,7 @@
|
||||
"obfs_password_placeholder": "난독화 비밀번호를 입력하세요",
|
||||
"obfs_path": "난독화 경로",
|
||||
"offline": "오프라인",
|
||||
"oneClickInstall": "원클릭 설치",
|
||||
"online": "온라인",
|
||||
"onlineUsers": "온라인 사용자",
|
||||
"padding_scheme": "패딩 규칙",
|
||||
|
||||
@ -5,6 +5,8 @@
|
||||
},
|
||||
"address": "Adresse",
|
||||
"address_placeholder": "Serveradresse",
|
||||
"apiHost": "API-vert",
|
||||
"apiHostPlaceholder": "http(s)://eksempel.com",
|
||||
"bandwidth_placeholder": "Skriv inn båndbredde, la stå tomt for BBR",
|
||||
"basic": "Grunnleggende Konfigurasjon",
|
||||
"cancel": "Avbryt",
|
||||
@ -17,6 +19,7 @@
|
||||
"confirmDeleteDesc": "Denne handlingen kan ikke angres.",
|
||||
"confirmDeleteTitle": "Slette denne serveren?",
|
||||
"congestion_controller": "Kongestjonskontroller",
|
||||
"connect": "Koble til",
|
||||
"copied": "Kopiert",
|
||||
"copy": "Kopier",
|
||||
"country": "Land",
|
||||
@ -47,11 +50,14 @@
|
||||
"expired": "Utløpt",
|
||||
"extra": "Ekstra konfigurasjon",
|
||||
"flow": "Flyt",
|
||||
"generate_quantum_resistant_key": "Generer kvantumresistent nøkkel",
|
||||
"generate_standard_encryption_key": "Generer standard krypteringsnøkkel",
|
||||
"hop_interval": "Hoppintervall",
|
||||
"hop_ports": "Hoppporter",
|
||||
"hop_ports_placeholder": "f.eks. 1-65535",
|
||||
"host": "Vert",
|
||||
"id": "ID",
|
||||
"installCommand": "Installasjonskommando",
|
||||
"ipAddresses": "IP-adresser",
|
||||
"memory": "Minne",
|
||||
"migrate": "Migrer data",
|
||||
@ -69,6 +75,7 @@
|
||||
"obfs_password_placeholder": "Skriv inn obfuskasjonspassord",
|
||||
"obfs_path": "Obfs Sti",
|
||||
"offline": "Frakoblet",
|
||||
"oneClickInstall": "Én-klikk installasjon",
|
||||
"online": "På nett",
|
||||
"onlineUsers": "Brukere på nett",
|
||||
"padding_scheme": "Polstring Skjema",
|
||||
|
||||
@ -5,6 +5,8 @@
|
||||
},
|
||||
"address": "Adres",
|
||||
"address_placeholder": "Adres serwera",
|
||||
"apiHost": "Host API",
|
||||
"apiHostPlaceholder": "http(s)://przyklad.com",
|
||||
"bandwidth_placeholder": "Wprowadź przepustowość, pozostaw puste dla BBR",
|
||||
"basic": "Podstawowa konfiguracja",
|
||||
"cancel": "Anuluj",
|
||||
@ -17,6 +19,7 @@
|
||||
"confirmDeleteDesc": "Ta akcja nie może być cofnięta.",
|
||||
"confirmDeleteTitle": "Usunąć ten serwer?",
|
||||
"congestion_controller": "Kontroler przeciążenia",
|
||||
"connect": "Połącz",
|
||||
"copied": "Skopiowano",
|
||||
"copy": "Kopiuj",
|
||||
"country": "Kraj",
|
||||
@ -47,11 +50,14 @@
|
||||
"expired": "Wygasł",
|
||||
"extra": "Dodatkowa konfiguracja",
|
||||
"flow": "Przepływ",
|
||||
"generate_quantum_resistant_key": "Generuj klucz odporny na kwanty",
|
||||
"generate_standard_encryption_key": "Generuj standardowy klucz szyfrowania",
|
||||
"hop_interval": "Interwał skoku",
|
||||
"hop_ports": "Porty skoku",
|
||||
"hop_ports_placeholder": "np. 1-65535",
|
||||
"host": "Host",
|
||||
"id": "ID",
|
||||
"installCommand": "Polecenie instalacji",
|
||||
"ipAddresses": "Adresy IP",
|
||||
"memory": "Pamięć",
|
||||
"migrate": "Migracja danych",
|
||||
@ -69,6 +75,7 @@
|
||||
"obfs_password_placeholder": "Wprowadź hasło obfuskacji",
|
||||
"obfs_path": "Ścieżka obfuskacji",
|
||||
"offline": "Offline",
|
||||
"oneClickInstall": "Instalacja jednym kliknięciem",
|
||||
"online": "Online",
|
||||
"onlineUsers": "Użytkownicy online",
|
||||
"padding_scheme": "Schemat wypełnienia",
|
||||
|
||||
@ -5,6 +5,8 @@
|
||||
},
|
||||
"address": "Endereço",
|
||||
"address_placeholder": "Endereço do servidor",
|
||||
"apiHost": "Host da API",
|
||||
"apiHostPlaceholder": "http(s)://exemplo.com",
|
||||
"bandwidth_placeholder": "Insira a largura de banda, deixe em branco para BBR",
|
||||
"basic": "Configuração Básica",
|
||||
"cancel": "Cancelar",
|
||||
@ -17,6 +19,7 @@
|
||||
"confirmDeleteDesc": "Esta ação não pode ser desfeita.",
|
||||
"confirmDeleteTitle": "Excluir este servidor?",
|
||||
"congestion_controller": "Controlador de congestionamento",
|
||||
"connect": "Conectar",
|
||||
"copied": "Copiado",
|
||||
"copy": "Copiar",
|
||||
"country": "País",
|
||||
@ -47,11 +50,14 @@
|
||||
"expired": "Expirado",
|
||||
"extra": "Configuração Extra",
|
||||
"flow": "Fluxo",
|
||||
"generate_quantum_resistant_key": "Gerar chave resistente a quânticos",
|
||||
"generate_standard_encryption_key": "Gerar chave de criptografia padrão",
|
||||
"hop_interval": "Intervalo de salto",
|
||||
"hop_ports": "Portas de salto",
|
||||
"hop_ports_placeholder": "ex. 1-65535",
|
||||
"host": "Host",
|
||||
"id": "ID",
|
||||
"installCommand": "Comando de instalação",
|
||||
"ipAddresses": "Endereços IP",
|
||||
"memory": "Memória",
|
||||
"migrate": "Migrar Dados",
|
||||
@ -69,6 +75,7 @@
|
||||
"obfs_password_placeholder": "Insira a senha de ofuscação",
|
||||
"obfs_path": "Caminho de Ofuscação",
|
||||
"offline": "Offline",
|
||||
"oneClickInstall": "Instalação com um clique",
|
||||
"online": "Online",
|
||||
"onlineUsers": "Usuários online",
|
||||
"padding_scheme": "Esquema de Preenchimento",
|
||||
|
||||
@ -5,6 +5,8 @@
|
||||
},
|
||||
"address": "Adresă",
|
||||
"address_placeholder": "Adresă server",
|
||||
"apiHost": "Gazda API",
|
||||
"apiHostPlaceholder": "http(s)://exemplu.com",
|
||||
"bandwidth_placeholder": "Introduceți lățimea de bandă, lăsați liber pentru BBR",
|
||||
"basic": "Configurare de bază",
|
||||
"cancel": "Anulează",
|
||||
@ -17,6 +19,7 @@
|
||||
"confirmDeleteDesc": "Această acțiune nu poate fi anulată.",
|
||||
"confirmDeleteTitle": "Șterge acest server?",
|
||||
"congestion_controller": "Controler de congestie",
|
||||
"connect": "Conectare",
|
||||
"copied": "Copiat",
|
||||
"copy": "Copiază",
|
||||
"country": "Țară",
|
||||
@ -47,11 +50,14 @@
|
||||
"expired": "Expirat",
|
||||
"extra": "Configurație suplimentară",
|
||||
"flow": "Flux",
|
||||
"generate_quantum_resistant_key": "Generează cheie rezistentă la cuantică",
|
||||
"generate_standard_encryption_key": "Generează cheie de criptare standard",
|
||||
"hop_interval": "Interval de hop",
|
||||
"hop_ports": "Porturi hop",
|
||||
"hop_ports_placeholder": "de ex. 1-65535",
|
||||
"host": "Gazdă",
|
||||
"id": "ID",
|
||||
"installCommand": "Comandă de instalare",
|
||||
"ipAddresses": "Adrese IP",
|
||||
"memory": "Memorie",
|
||||
"migrate": "Migrați datele",
|
||||
@ -69,6 +75,7 @@
|
||||
"obfs_password_placeholder": "Introdu parola de obfuscare",
|
||||
"obfs_path": "Cale Obfs",
|
||||
"offline": "Offline",
|
||||
"oneClickInstall": "Instalare cu un singur clic",
|
||||
"online": "Online",
|
||||
"onlineUsers": "Utilizatori online",
|
||||
"padding_scheme": "Schema de umplere",
|
||||
|
||||
@ -5,6 +5,8 @@
|
||||
},
|
||||
"address": "Адрес",
|
||||
"address_placeholder": "Адрес сервера",
|
||||
"apiHost": "API хост",
|
||||
"apiHostPlaceholder": "http(s)://пример.ком",
|
||||
"bandwidth_placeholder": "Введите пропускную способность, оставьте пустым для BBR",
|
||||
"basic": "Базовая конфигурация",
|
||||
"cancel": "Отмена",
|
||||
@ -17,6 +19,7 @@
|
||||
"confirmDeleteDesc": "Это действие нельзя отменить.",
|
||||
"confirmDeleteTitle": "Удалить этот сервер?",
|
||||
"congestion_controller": "Контроллер перегрузки",
|
||||
"connect": "Подключить",
|
||||
"copied": "Скопировано",
|
||||
"copy": "Копировать",
|
||||
"country": "Страна",
|
||||
@ -47,11 +50,14 @@
|
||||
"expired": "Истекло",
|
||||
"extra": "Дополнительная конфигурация",
|
||||
"flow": "Поток",
|
||||
"generate_quantum_resistant_key": "Генерировать квантово-устойчивый ключ",
|
||||
"generate_standard_encryption_key": "Генерировать стандартный ключ шифрования",
|
||||
"hop_interval": "Интервал перехода",
|
||||
"hop_ports": "Порты перехода",
|
||||
"hop_ports_placeholder": "например, 1-65535",
|
||||
"host": "Хост",
|
||||
"id": "ID",
|
||||
"installCommand": "Команда установки",
|
||||
"ipAddresses": "IP-адреса",
|
||||
"memory": "Память",
|
||||
"migrate": "Перенести данные",
|
||||
@ -69,6 +75,7 @@
|
||||
"obfs_password_placeholder": "Введите пароль обфускации",
|
||||
"obfs_path": "Обфусцированный путь",
|
||||
"offline": "Офлайн",
|
||||
"oneClickInstall": "Установка в один клик",
|
||||
"online": "Онлайн",
|
||||
"onlineUsers": "Онлайн пользователи",
|
||||
"padding_scheme": "Схема выравнивания",
|
||||
|
||||
@ -5,6 +5,8 @@
|
||||
},
|
||||
"address": "ที่อยู่",
|
||||
"address_placeholder": "ที่อยู่เซิร์ฟเวอร์",
|
||||
"apiHost": "โฮสต์ API",
|
||||
"apiHostPlaceholder": "http(s)://example.com",
|
||||
"bandwidth_placeholder": "กรุณากรอกแบนด์วิธ ทิ้งว่างไว้สำหรับ BBR",
|
||||
"basic": "การตั้งค่าพื้นฐาน",
|
||||
"cancel": "ยกเลิก",
|
||||
@ -17,6 +19,7 @@
|
||||
"confirmDeleteDesc": "การกระทำนี้ไม่สามารถย้อนกลับได้",
|
||||
"confirmDeleteTitle": "ลบเซิร์ฟเวอร์นี้หรือไม่?",
|
||||
"congestion_controller": "ตัวควบคุมความแออัด",
|
||||
"connect": "เชื่อมต่อ",
|
||||
"copied": "คัดลอกแล้ว",
|
||||
"copy": "คัดลอก",
|
||||
"country": "ประเทศ",
|
||||
@ -47,11 +50,14 @@
|
||||
"expired": "หมดอายุ",
|
||||
"extra": "การกำหนดค่าพิเศษ",
|
||||
"flow": "การไหล",
|
||||
"generate_quantum_resistant_key": "สร้างคีย์ต้านทานควอนตัม",
|
||||
"generate_standard_encryption_key": "สร้างคีย์เข้ารหัสมาตรฐาน",
|
||||
"hop_interval": "ช่วงเวลาการกระโดด",
|
||||
"hop_ports": "พอร์ตการกระโดด",
|
||||
"hop_ports_placeholder": "เช่น 1-65535",
|
||||
"host": "โฮสต์",
|
||||
"id": "ID",
|
||||
"installCommand": "คำสั่งติดตั้ง",
|
||||
"ipAddresses": "ที่อยู่ IP",
|
||||
"memory": "หน่วยความจำ",
|
||||
"migrate": "ย้ายข้อมูล",
|
||||
@ -69,6 +75,7 @@
|
||||
"obfs_password_placeholder": "กรอกรหัสผ่านการปกปิด",
|
||||
"obfs_path": "เส้นทางการทำให้ไม่สามารถอ่านได้",
|
||||
"offline": "ออฟไลน์",
|
||||
"oneClickInstall": "ติดตั้งด้วยคลิกเดียว",
|
||||
"online": "ออนไลน์",
|
||||
"onlineUsers": "ผู้ใช้งานออนไลน์",
|
||||
"padding_scheme": "รูปแบบการเติม",
|
||||
|
||||
@ -5,6 +5,8 @@
|
||||
},
|
||||
"address": "Adres",
|
||||
"address_placeholder": "Sunucu adresi",
|
||||
"apiHost": "API Sunucusu",
|
||||
"apiHostPlaceholder": "http(s)://ornek.com",
|
||||
"bandwidth_placeholder": "Bant genişliğini girin, BBR için boş bırakın",
|
||||
"basic": "Temel Yapılandırma",
|
||||
"cancel": "İptal",
|
||||
@ -17,6 +19,7 @@
|
||||
"confirmDeleteDesc": "Bu işlem geri alınamaz.",
|
||||
"confirmDeleteTitle": "Bu sunucuyu silmek istiyor musunuz?",
|
||||
"congestion_controller": "Tıkanıklık kontrolörü",
|
||||
"connect": "Bağlan",
|
||||
"copied": "Kopyalandı",
|
||||
"copy": "Kopyala",
|
||||
"country": "Ülke",
|
||||
@ -47,11 +50,14 @@
|
||||
"expired": "Süresi dolmuş",
|
||||
"extra": "Ek Yapılandırma",
|
||||
"flow": "Akış",
|
||||
"generate_quantum_resistant_key": "Kuantuma Dayanıklı Anahtar Oluştur",
|
||||
"generate_standard_encryption_key": "Standart Şifreleme Anahtarı Oluştur",
|
||||
"hop_interval": "Atlama aralığı",
|
||||
"hop_ports": "Atlama portları",
|
||||
"hop_ports_placeholder": "örn. 1-65535",
|
||||
"host": "Ana bilgisayar",
|
||||
"id": "ID",
|
||||
"installCommand": "Kurulum komutu",
|
||||
"ipAddresses": "IP adresleri",
|
||||
"memory": "Bellek",
|
||||
"migrate": "Veri Taşı",
|
||||
@ -69,6 +75,7 @@
|
||||
"obfs_password_placeholder": "Gizleme şifresini girin",
|
||||
"obfs_path": "Obfs Yolu",
|
||||
"offline": "Çevrimdışı",
|
||||
"oneClickInstall": "Tek Tıkla Kurulum",
|
||||
"online": "Çevrimiçi",
|
||||
"onlineUsers": "Çevrimiçi kullanıcılar",
|
||||
"padding_scheme": "Dolgu Şeması",
|
||||
|
||||
@ -5,6 +5,8 @@
|
||||
},
|
||||
"address": "Адреса",
|
||||
"address_placeholder": "Адреса сервера",
|
||||
"apiHost": "API хост",
|
||||
"apiHostPlaceholder": "http(s)://example.com",
|
||||
"bandwidth_placeholder": "Введіть пропускну здатність, залиште порожнім для BBR",
|
||||
"basic": "Базова конфігурація",
|
||||
"cancel": "Скасувати",
|
||||
@ -17,6 +19,7 @@
|
||||
"confirmDeleteDesc": "Цю дію не можна скасувати.",
|
||||
"confirmDeleteTitle": "Видалити цей сервер?",
|
||||
"congestion_controller": "Контролер перевантаження",
|
||||
"connect": "Підключити",
|
||||
"copied": "Скопійовано",
|
||||
"copy": "Копіювати",
|
||||
"country": "Країна",
|
||||
@ -47,11 +50,14 @@
|
||||
"expired": "Термін дії закінчився",
|
||||
"extra": "Додаткова конфігурація",
|
||||
"flow": "Потік",
|
||||
"generate_quantum_resistant_key": "Згенерувати квантово-стійкий ключ",
|
||||
"generate_standard_encryption_key": "Згенерувати стандартний ключ шифрування",
|
||||
"hop_interval": "Інтервал стрибка",
|
||||
"hop_ports": "Порти стрибка",
|
||||
"hop_ports_placeholder": "наприклад, 1-65535",
|
||||
"host": "Хост",
|
||||
"id": "ID",
|
||||
"installCommand": "Команда встановлення",
|
||||
"ipAddresses": "IP адреси",
|
||||
"memory": "Пам'ять",
|
||||
"migrate": "Міграція даних",
|
||||
@ -69,6 +75,7 @@
|
||||
"obfs_password_placeholder": "Введіть пароль обфускації",
|
||||
"obfs_path": "Обфускаційний шлях",
|
||||
"offline": "Офлайн",
|
||||
"oneClickInstall": "Встановлення в один клік",
|
||||
"online": "Онлайн",
|
||||
"onlineUsers": "Онлайн користувачі",
|
||||
"padding_scheme": "Схема заповнення",
|
||||
|
||||
@ -5,6 +5,8 @@
|
||||
},
|
||||
"address": "Địa chỉ",
|
||||
"address_placeholder": "Địa chỉ máy chủ",
|
||||
"apiHost": "Máy chủ API",
|
||||
"apiHostPlaceholder": "http(s)://example.com",
|
||||
"bandwidth_placeholder": "Nhập băng thông, để trống cho BBR",
|
||||
"basic": "Cấu Hình Cơ Bản",
|
||||
"cancel": "Hủy",
|
||||
@ -17,6 +19,7 @@
|
||||
"confirmDeleteDesc": "Hành động này không thể hoàn tác.",
|
||||
"confirmDeleteTitle": "Xóa máy chủ này?",
|
||||
"congestion_controller": "Bộ điều khiển tắc nghẽn",
|
||||
"connect": "Kết nối",
|
||||
"copied": "Đã sao chép",
|
||||
"copy": "Sao chép",
|
||||
"country": "Quốc gia",
|
||||
@ -47,11 +50,14 @@
|
||||
"expired": "Đã hết hạn",
|
||||
"extra": "Cấu hình thêm",
|
||||
"flow": "Lưu lượng",
|
||||
"generate_quantum_resistant_key": "Tạo khóa chống lượng tử",
|
||||
"generate_standard_encryption_key": "Tạo khóa mã hóa tiêu chuẩn",
|
||||
"hop_interval": "Khoảng thời gian nhảy",
|
||||
"hop_ports": "Cổng nhảy",
|
||||
"hop_ports_placeholder": "vd. 1-65535",
|
||||
"host": "Máy chủ",
|
||||
"id": "ID",
|
||||
"installCommand": "Lệnh cài đặt",
|
||||
"ipAddresses": "Địa chỉ IP",
|
||||
"memory": "Bộ nhớ",
|
||||
"migrate": "Di chuyển dữ liệu",
|
||||
@ -69,6 +75,7 @@
|
||||
"obfs_password_placeholder": "Nhập mật khẩu làm mờ",
|
||||
"obfs_path": "Đường dẫn Obfs",
|
||||
"offline": "Ngoại tuyến",
|
||||
"oneClickInstall": "Cài đặt một lần nhấp",
|
||||
"online": "Trực tuyến",
|
||||
"onlineUsers": "Người dùng trực tuyến",
|
||||
"padding_scheme": "Sơ Đồ Đệm",
|
||||
|
||||
@ -5,6 +5,8 @@
|
||||
},
|
||||
"address": "地址",
|
||||
"address_placeholder": "服务器地址",
|
||||
"apiHost": "API Host",
|
||||
"apiHostPlaceholder": "http(s)://example.com",
|
||||
"bandwidth_placeholder": "请输入带宽,留空则使用BBR",
|
||||
"basic": "基础配置",
|
||||
"cancel": "取消",
|
||||
@ -13,12 +15,16 @@
|
||||
"cert_mode": "证书模式",
|
||||
"cipher": "加密算法",
|
||||
"city": "城市",
|
||||
"close": "关闭",
|
||||
"confirm": "确认",
|
||||
"confirmDeleteDesc": "该操作不可撤销。",
|
||||
"confirmDeleteTitle": "确认删除该服务器?",
|
||||
"congestion_controller": "拥塞控制",
|
||||
"connect": "对接",
|
||||
"copied": "已复制",
|
||||
"copy": "复制",
|
||||
"copyAndClose": "复制并关闭",
|
||||
"copyFailed": "复制失败",
|
||||
"country": "国家",
|
||||
"cpu": "CPU",
|
||||
"create": "新建",
|
||||
@ -47,11 +53,14 @@
|
||||
"expired": "已过期",
|
||||
"extra": "额外配置",
|
||||
"flow": "流控",
|
||||
"generate_quantum_resistant_key": "生成抗量子密钥",
|
||||
"generate_standard_encryption_key": "生成标准加密密钥",
|
||||
"hop_interval": "跳跃端口间隔",
|
||||
"hop_ports": "跳跃端口",
|
||||
"hop_ports_placeholder": "例如 1-65535",
|
||||
"host": "Host",
|
||||
"id": "编号",
|
||||
"installCommand": "一键安装命令",
|
||||
"ipAddresses": "IP 地址",
|
||||
"memory": "内存",
|
||||
"migrate": "迁移数据",
|
||||
@ -69,6 +78,7 @@
|
||||
"obfs_password_placeholder": "输入混淆密码",
|
||||
"obfs_path": "混淆路径",
|
||||
"offline": "离线",
|
||||
"oneClickInstall": "一键接入",
|
||||
"online": "在线",
|
||||
"onlineUsers": "在线人数",
|
||||
"padding_scheme": "填充方案",
|
||||
|
||||
@ -5,6 +5,8 @@
|
||||
},
|
||||
"address": "地址",
|
||||
"address_placeholder": "伺服器地址",
|
||||
"apiHost": "API 主機",
|
||||
"apiHostPlaceholder": "http(s)://example.com",
|
||||
"bandwidth_placeholder": "輸入帶寬,留空以使用BBR",
|
||||
"basic": "基本配置",
|
||||
"cancel": "取消",
|
||||
@ -17,6 +19,7 @@
|
||||
"confirmDeleteDesc": "此操作無法撤銷。",
|
||||
"confirmDeleteTitle": "刪除此伺服器?",
|
||||
"congestion_controller": "擁塞控制器",
|
||||
"connect": "連接",
|
||||
"copied": "已複製",
|
||||
"copy": "複製",
|
||||
"country": "國家",
|
||||
@ -47,11 +50,14 @@
|
||||
"expired": "已過期",
|
||||
"extra": "額外配置",
|
||||
"flow": "流量",
|
||||
"generate_quantum_resistant_key": "生成抗量子密鑰",
|
||||
"generate_standard_encryption_key": "生成標準加密密鑰",
|
||||
"hop_interval": "跳躍間隔",
|
||||
"hop_ports": "跳躍端口",
|
||||
"hop_ports_placeholder": "例如 1-65535",
|
||||
"host": "主機",
|
||||
"id": "ID",
|
||||
"installCommand": "安裝命令",
|
||||
"ipAddresses": "IP 地址",
|
||||
"memory": "內存",
|
||||
"migrate": "遷移數據",
|
||||
@ -69,6 +75,7 @@
|
||||
"obfs_password_placeholder": "輸入混淆密碼",
|
||||
"obfs_path": "混淆路徑",
|
||||
"offline": "離線",
|
||||
"oneClickInstall": "一鍵安裝",
|
||||
"online": "在線",
|
||||
"onlineUsers": "在線用戶",
|
||||
"padding_scheme": "填充方案",
|
||||
|
||||
@ -11,6 +11,7 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@lottiefiles/dotlottie-react": "^0.15.1",
|
||||
"@noble/curves": "^2.0.1",
|
||||
"@noble/ed25519": "^3.0.0",
|
||||
"@tanstack/react-query": "^5.85.5",
|
||||
"@tanstack/react-query-next-experimental": "^5.85.5",
|
||||
@ -20,14 +21,14 @@
|
||||
"js-yaml": "^4.1.0",
|
||||
"mlkem-wasm": "^0.0.6",
|
||||
"nanoid": "^5.1.5",
|
||||
"next": "^15.5.2",
|
||||
"next": "^15.5.7",
|
||||
"next-intl": "^3.26.3",
|
||||
"next-runtime-env": "^3.3.0",
|
||||
"next-themes": "^0.4.6",
|
||||
"nextjs-toploader": "^3.8.16",
|
||||
"radash": "^12.1.1",
|
||||
"react": "^19.1.1",
|
||||
"react-dom": "^19.1.1",
|
||||
"react": "^19.2.1",
|
||||
"react-dom": "^19.2.1",
|
||||
"react-turnstile": "^1.1.4",
|
||||
"universal-cookie": "^8.0.1",
|
||||
"zustand": "^5.0.8"
|
||||
@ -35,8 +36,8 @@
|
||||
"devDependencies": {
|
||||
"@types/js-yaml": "^4.0.9",
|
||||
"@types/node": "^24.3.0",
|
||||
"@types/react": "^19.1.11",
|
||||
"@types/react-dom": "^19.1.8",
|
||||
"@types/react": "^19.2.7",
|
||||
"@types/react-dom": "^19.2.3",
|
||||
"@types/rtl-detect": "^1.0.3",
|
||||
"@workspace/eslint-config": "workspace:*",
|
||||
"@workspace/typescript-config": "workspace:*",
|
||||
|
||||
@ -20,16 +20,16 @@
|
||||
"framer-motion": "^12.23.12",
|
||||
"gray-matter": "^4.0.3",
|
||||
"lucide-react": "^0.542.0",
|
||||
"next": "^15.5.2",
|
||||
"next": "^15.5.7",
|
||||
"next-intl": "^3.26.3",
|
||||
"next-runtime-env": "^3.3.0",
|
||||
"next-themes": "^0.4.6",
|
||||
"nextjs-toploader": "^3.8.16",
|
||||
"qrcode.react": "^4.2.0",
|
||||
"radash": "^12.1.1",
|
||||
"react": "^19.1.1",
|
||||
"react": "^19.2.1",
|
||||
"react-copy-to-clipboard": "^5.1.0",
|
||||
"react-dom": "^19.1.1",
|
||||
"react-dom": "^19.2.1",
|
||||
"react-turnstile": "^1.1.4",
|
||||
"rtl-detect": "^1.1.2",
|
||||
"ua-parser-js": "^2.0.4",
|
||||
@ -38,9 +38,9 @@
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "^24.3.0",
|
||||
"@types/react": "^19.1.11",
|
||||
"@types/react": "^19.2.7",
|
||||
"@types/react-copy-to-clipboard": "^5.0.7",
|
||||
"@types/react-dom": "^19.1.8",
|
||||
"@types/react-dom": "^19.2.3",
|
||||
"@types/rtl-detect": "^1.0.3",
|
||||
"@workspace/eslint-config": "workspace:*",
|
||||
"@workspace/typescript-config": "workspace:*",
|
||||
|
||||
79
bun.lock
79
bun.lock
@ -1,5 +1,6 @@
|
||||
{
|
||||
"lockfileVersion": 1,
|
||||
"configVersion": 0,
|
||||
"workspaces": {
|
||||
"": {
|
||||
"name": "ppanel-web",
|
||||
@ -16,6 +17,7 @@
|
||||
"@iconify/react": "^5.2.0",
|
||||
"@lottiefiles/dotlottie-react": "^0.15.1",
|
||||
"@monaco-editor/react": "^4.7.0",
|
||||
"@noble/curves": "^2.0.1",
|
||||
"@radix-ui/react-accordion": "^1.2.12",
|
||||
"@radix-ui/react-alert-dialog": "^1.1.15",
|
||||
"@radix-ui/react-aspect-ratio": "^1.1.7",
|
||||
@ -91,8 +93,8 @@
|
||||
"lint-staged": "^16.1.5",
|
||||
"postcss": "^8.5.6",
|
||||
"prettier": "^3.4.2",
|
||||
"react": "^19.1.1",
|
||||
"react-dom": "^19.1.1",
|
||||
"react": "^19.2.1",
|
||||
"react-dom": "^19.2.1",
|
||||
"semantic-release": "21.1.2",
|
||||
"semantic-release-config-gitmoji": "^1.5.3",
|
||||
"tailwindcss": "^3.4.17",
|
||||
@ -104,6 +106,7 @@
|
||||
"name": "ppanel-admin-web",
|
||||
"dependencies": {
|
||||
"@lottiefiles/dotlottie-react": "^0.15.1",
|
||||
"@noble/curves": "^2.0.1",
|
||||
"@noble/ed25519": "^3.0.0",
|
||||
"@tanstack/react-query": "^5.85.5",
|
||||
"@tanstack/react-query-next-experimental": "^5.85.5",
|
||||
@ -113,14 +116,14 @@
|
||||
"js-yaml": "^4.1.0",
|
||||
"mlkem-wasm": "^0.0.6",
|
||||
"nanoid": "^5.1.5",
|
||||
"next": "^15.5.2",
|
||||
"next": "^15.5.7",
|
||||
"next-intl": "^3.26.3",
|
||||
"next-runtime-env": "^3.3.0",
|
||||
"next-themes": "^0.4.6",
|
||||
"nextjs-toploader": "^3.8.16",
|
||||
"radash": "^12.1.1",
|
||||
"react": "^19.1.1",
|
||||
"react-dom": "^19.1.1",
|
||||
"react": "^19.2.1",
|
||||
"react-dom": "^19.2.1",
|
||||
"react-turnstile": "^1.1.4",
|
||||
"universal-cookie": "^8.0.1",
|
||||
"zustand": "^5.0.8",
|
||||
@ -128,8 +131,8 @@
|
||||
"devDependencies": {
|
||||
"@types/js-yaml": "^4.0.9",
|
||||
"@types/node": "^24.3.0",
|
||||
"@types/react": "^19.1.11",
|
||||
"@types/react-dom": "^19.1.8",
|
||||
"@types/react": "^19.2.7",
|
||||
"@types/react-dom": "^19.2.3",
|
||||
"@types/rtl-detect": "^1.0.3",
|
||||
"@workspace/eslint-config": "workspace:*",
|
||||
"@workspace/typescript-config": "workspace:*",
|
||||
@ -149,16 +152,16 @@
|
||||
"framer-motion": "^12.23.12",
|
||||
"gray-matter": "^4.0.3",
|
||||
"lucide-react": "^0.542.0",
|
||||
"next": "^15.5.2",
|
||||
"next": "^15.5.7",
|
||||
"next-intl": "^3.26.3",
|
||||
"next-runtime-env": "^3.3.0",
|
||||
"next-themes": "^0.4.6",
|
||||
"nextjs-toploader": "^3.8.16",
|
||||
"qrcode.react": "^4.2.0",
|
||||
"radash": "^12.1.1",
|
||||
"react": "^19.1.1",
|
||||
"react": "^19.2.1",
|
||||
"react-copy-to-clipboard": "^5.1.0",
|
||||
"react-dom": "^19.1.1",
|
||||
"react-dom": "^19.2.1",
|
||||
"react-turnstile": "^1.1.4",
|
||||
"rtl-detect": "^1.1.2",
|
||||
"ua-parser-js": "^2.0.4",
|
||||
@ -167,9 +170,9 @@
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "^24.3.0",
|
||||
"@types/react": "^19.1.11",
|
||||
"@types/react": "^19.2.7",
|
||||
"@types/react-copy-to-clipboard": "^5.0.7",
|
||||
"@types/react-dom": "^19.1.8",
|
||||
"@types/react-dom": "^19.2.3",
|
||||
"@types/rtl-detect": "^1.0.3",
|
||||
"@workspace/eslint-config": "workspace:*",
|
||||
"@workspace/typescript-config": "workspace:*",
|
||||
@ -298,16 +301,16 @@
|
||||
"devDependencies": {
|
||||
"@turbo/gen": "^2.5.6",
|
||||
"@types/node": "^24.3.0",
|
||||
"@types/react": "^19.1.12",
|
||||
"@types/react-dom": "^19.1.9",
|
||||
"@types/react": "^19.2.7",
|
||||
"@types/react-dom": "^19.2.3",
|
||||
"@types/react-syntax-highlighter": "^15.5.13",
|
||||
"@types/rtl-detect": "^1.0.3",
|
||||
"@workspace/eslint-config": "workspace:*",
|
||||
"@workspace/typescript-config": "workspace:*",
|
||||
"autoprefixer": "^10.4.21",
|
||||
"postcss": "^8.5.6",
|
||||
"react": "^19.1.1",
|
||||
"react-dom": "^19.1.1",
|
||||
"react": "^19.2.1",
|
||||
"react-dom": "^19.2.1",
|
||||
"tailwindcss": "^3.4.17",
|
||||
"typescript": "^5.9.2",
|
||||
},
|
||||
@ -526,30 +529,34 @@
|
||||
|
||||
"@netlify/plugin-nextjs": ["@netlify/plugin-nextjs@5.14.0", "", {}, "sha512-8WEnVm88Ed6v6j/D0iqXDSnAW8Mf9P2CDVgBG3x2+vkiEI48X6Na7KnoQRyi6oulgA6foHIPWqgQIClsPiW20A=="],
|
||||
|
||||
"@next/env": ["@next/env@15.5.6", "", {}, "sha512-3qBGRW+sCGzgbpc5TS1a0p7eNxnOarGVQhZxfvTdnV0gFI61lX7QNtQ4V1TSREctXzYn5NetbUsLvyqwLFJM6Q=="],
|
||||
"@next/env": ["@next/env@15.5.7", "", {}, "sha512-4h6Y2NyEkIEN7Z8YxkA27pq6zTkS09bUSYC0xjd0NpwFxjnIKeZEeH591o5WECSmjpUhLn3H2QLJcDye3Uzcvg=="],
|
||||
|
||||
"@next/eslint-plugin-next": ["@next/eslint-plugin-next@15.5.6", "", { "dependencies": { "fast-glob": "3.3.1" } }, "sha512-YxDvsT2fwy1j5gMqk3ppXlsgDopHnkM4BoxSVASbvvgh5zgsK8lvWerDzPip8k3WVzsTZ1O7A7si1KNfN4OZfQ=="],
|
||||
|
||||
"@next/swc-darwin-arm64": ["@next/swc-darwin-arm64@15.5.6", "", { "os": "darwin", "cpu": "arm64" }, "sha512-ES3nRz7N+L5Umz4KoGfZ4XX6gwHplwPhioVRc25+QNsDa7RtUF/z8wJcbuQ2Tffm5RZwuN2A063eapoJ1u4nPg=="],
|
||||
"@next/swc-darwin-arm64": ["@next/swc-darwin-arm64@15.5.7", "", { "os": "darwin", "cpu": "arm64" }, "sha512-IZwtxCEpI91HVU/rAUOOobWSZv4P2DeTtNaCdHqLcTJU4wdNXgAySvKa/qJCgR5m6KI8UsKDXtO2B31jcaw1Yw=="],
|
||||
|
||||
"@next/swc-darwin-x64": ["@next/swc-darwin-x64@15.5.6", "", { "os": "darwin", "cpu": "x64" }, "sha512-JIGcytAyk9LQp2/nuVZPAtj8uaJ/zZhsKOASTjxDug0SPU9LAM3wy6nPU735M1OqacR4U20LHVF5v5Wnl9ptTA=="],
|
||||
"@next/swc-darwin-x64": ["@next/swc-darwin-x64@15.5.7", "", { "os": "darwin", "cpu": "x64" }, "sha512-UP6CaDBcqaCBuiq/gfCEJw7sPEoX1aIjZHnBWN9v9qYHQdMKvCKcAVs4OX1vIjeE+tC5EIuwDTVIoXpUes29lg=="],
|
||||
|
||||
"@next/swc-linux-arm64-gnu": ["@next/swc-linux-arm64-gnu@15.5.6", "", { "os": "linux", "cpu": "arm64" }, "sha512-qvz4SVKQ0P3/Im9zcS2RmfFL/UCQnsJKJwQSkissbngnB/12c6bZTCB0gHTexz1s6d/mD0+egPKXAIRFVS7hQg=="],
|
||||
"@next/swc-linux-arm64-gnu": ["@next/swc-linux-arm64-gnu@15.5.7", "", { "os": "linux", "cpu": "arm64" }, "sha512-NCslw3GrNIw7OgmRBxHtdWFQYhexoUCq+0oS2ccjyYLtcn1SzGzeM54jpTFonIMUjNbHmpKpziXnpxhSWLcmBA=="],
|
||||
|
||||
"@next/swc-linux-arm64-musl": ["@next/swc-linux-arm64-musl@15.5.6", "", { "os": "linux", "cpu": "arm64" }, "sha512-FsbGVw3SJz1hZlvnWD+T6GFgV9/NYDeLTNQB2MXoPN5u9VA9OEDy6fJEfePfsUKAhJufFbZLgp0cPxMuV6SV0w=="],
|
||||
"@next/swc-linux-arm64-musl": ["@next/swc-linux-arm64-musl@15.5.7", "", { "os": "linux", "cpu": "arm64" }, "sha512-nfymt+SE5cvtTrG9u1wdoxBr9bVB7mtKTcj0ltRn6gkP/2Nu1zM5ei8rwP9qKQP0Y//umK+TtkKgNtfboBxRrw=="],
|
||||
|
||||
"@next/swc-linux-x64-gnu": ["@next/swc-linux-x64-gnu@15.5.6", "", { "os": "linux", "cpu": "x64" }, "sha512-3QnHGFWlnvAgyxFxt2Ny8PTpXtQD7kVEeaFat5oPAHHI192WKYB+VIKZijtHLGdBBvc16tiAkPTDmQNOQ0dyrA=="],
|
||||
"@next/swc-linux-x64-gnu": ["@next/swc-linux-x64-gnu@15.5.7", "", { "os": "linux", "cpu": "x64" }, "sha512-hvXcZvCaaEbCZcVzcY7E1uXN9xWZfFvkNHwbe/n4OkRhFWrs1J1QV+4U1BN06tXLdaS4DazEGXwgqnu/VMcmqw=="],
|
||||
|
||||
"@next/swc-linux-x64-musl": ["@next/swc-linux-x64-musl@15.5.6", "", { "os": "linux", "cpu": "x64" }, "sha512-OsGX148sL+TqMK9YFaPFPoIaJKbFJJxFzkXZljIgA9hjMjdruKht6xDCEv1HLtlLNfkx3c5w2GLKhj7veBQizQ=="],
|
||||
"@next/swc-linux-x64-musl": ["@next/swc-linux-x64-musl@15.5.7", "", { "os": "linux", "cpu": "x64" }, "sha512-4IUO539b8FmF0odY6/SqANJdgwn1xs1GkPO5doZugwZ3ETF6JUdckk7RGmsfSf7ws8Qb2YB5It33mvNL/0acqA=="],
|
||||
|
||||
"@next/swc-win32-arm64-msvc": ["@next/swc-win32-arm64-msvc@15.5.6", "", { "os": "win32", "cpu": "arm64" }, "sha512-ONOMrqWxdzXDJNh2n60H6gGyKed42Ieu6UTVPZteXpuKbLZTH4G4eBMsr5qWgOBA+s7F+uB4OJbZnrkEDnZ5Fg=="],
|
||||
"@next/swc-win32-arm64-msvc": ["@next/swc-win32-arm64-msvc@15.5.7", "", { "os": "win32", "cpu": "arm64" }, "sha512-CpJVTkYI3ZajQkC5vajM7/ApKJUOlm6uP4BknM3XKvJ7VXAvCqSjSLmM0LKdYzn6nBJVSjdclx8nYJSa3xlTgQ=="],
|
||||
|
||||
"@next/swc-win32-ia32-msvc": ["@next/swc-win32-ia32-msvc@14.2.33", "", { "os": "win32", "cpu": "ia32" }, "sha512-pc9LpGNKhJ0dXQhZ5QMmYxtARwwmWLpeocFmVG5Z0DzWq5Uf0izcI8tLc+qOpqxO1PWqZ5A7J1blrUIKrIFc7Q=="],
|
||||
|
||||
"@next/swc-win32-x64-msvc": ["@next/swc-win32-x64-msvc@15.5.6", "", { "os": "win32", "cpu": "x64" }, "sha512-pxK4VIjFRx1MY92UycLOOw7dTdvccWsNETQ0kDHkBlcFH1GrTLUjSiHU1ohrznnux6TqRHgv5oflhfIWZwVROQ=="],
|
||||
"@next/swc-win32-x64-msvc": ["@next/swc-win32-x64-msvc@15.5.7", "", { "os": "win32", "cpu": "x64" }, "sha512-gMzgBX164I6DN+9/PGA+9dQiwmTkE4TloBNx8Kv9UiGARsr9Nba7IpcBRA1iTV9vwlYnrE3Uy6I7Aj6qLjQuqw=="],
|
||||
|
||||
"@noble/curves": ["@noble/curves@2.0.1", "", { "dependencies": { "@noble/hashes": "2.0.1" } }, "sha512-vs1Az2OOTBiP4q0pwjW5aF0xp9n4MxVrmkFBxc6EKZc6ddYx5gaZiAsZoq0uRRXWbi3AT/sBqn05eRPtn1JCPw=="],
|
||||
|
||||
"@noble/ed25519": ["@noble/ed25519@3.0.0", "", {}, "sha512-QyteqMNm0GLqfa5SoYbSC3+Pvykwpn95Zgth4MFVSMKBB75ELl9tX1LAVsN4c3HXOrakHsF2gL4zWDAYCcsnzg=="],
|
||||
|
||||
"@noble/hashes": ["@noble/hashes@2.0.1", "", {}, "sha512-XlOlEbQcE9fmuXxrVTXCTlG2nlRXa9Rj3rr5Ue/+tX+nmkgbX720YHh0VR3hBF9xDvwnb8D2shVGOwNx+ulArw=="],
|
||||
|
||||
"@nodelib/fs.scandir": ["@nodelib/fs.scandir@2.1.5", "", { "dependencies": { "@nodelib/fs.stat": "2.0.5", "run-parallel": "^1.1.9" } }, "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g=="],
|
||||
|
||||
"@nodelib/fs.stat": ["@nodelib/fs.stat@2.0.5", "", {}, "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A=="],
|
||||
@ -814,11 +821,11 @@
|
||||
|
||||
"@types/parse-json": ["@types/parse-json@4.0.2", "", {}, "sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw=="],
|
||||
|
||||
"@types/react": ["@types/react@19.2.2", "", { "dependencies": { "csstype": "^3.0.2" } }, "sha512-6mDvHUFSjyT2B2yeNx2nUgMxh9LtOWvkhIU3uePn2I2oyNymUAX1NIsdgviM4CH+JSrp2D2hsMvJOkxY+0wNRA=="],
|
||||
"@types/react": ["@types/react@19.2.7", "", { "dependencies": { "csstype": "^3.2.2" } }, "sha512-MWtvHrGZLFttgeEj28VXHxpmwYbor/ATPYbBfSFZEIRK0ecCFLl2Qo55z52Hss+UV9CRN7trSeq1zbgx7YDWWg=="],
|
||||
|
||||
"@types/react-copy-to-clipboard": ["@types/react-copy-to-clipboard@5.0.7", "", { "dependencies": { "@types/react": "*" } }, "sha512-Gft19D+as4M+9Whq1oglhmK49vqPhcLzk8WfvfLvaYMIPYanyfLy0+CwFucMJfdKoSFyySPmkkWn8/E6voQXjQ=="],
|
||||
|
||||
"@types/react-dom": ["@types/react-dom@19.2.2", "", { "peerDependencies": { "@types/react": "^19.2.0" } }, "sha512-9KQPoO6mZCi7jcIStSnlOWn2nEF3mNmyr3rIAsGnAbQKYbRLyqmeSc39EVgtxXVia+LMT8j3knZLAZAh+xLmrw=="],
|
||||
"@types/react-dom": ["@types/react-dom@19.2.3", "", { "peerDependencies": { "@types/react": "^19.2.0" } }, "sha512-jp2L/eY6fn+KgVVQAOqYItbF0VY/YApe5Mz2F0aykSO8gx31bYCZyvSeYxCHKvzHG5eZjc+zyaS5BrBWya2+kQ=="],
|
||||
|
||||
"@types/react-syntax-highlighter": ["@types/react-syntax-highlighter@15.5.13", "", { "dependencies": { "@types/react": "*" } }, "sha512-uLGJ87j6Sz8UaBAooU0T6lWJ0dBmjZgN1PZTrj05TNql2/XpC6+4HhMT5syIdFUUt+FASfCeLLv4kBygNU+8qA=="],
|
||||
|
||||
@ -1090,7 +1097,7 @@
|
||||
|
||||
"cssesc": ["cssesc@3.0.0", "", { "bin": { "cssesc": "bin/cssesc" } }, "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg=="],
|
||||
|
||||
"csstype": ["csstype@3.1.3", "", {}, "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw=="],
|
||||
"csstype": ["csstype@3.2.3", "", {}, "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ=="],
|
||||
|
||||
"d": ["d@1.0.2", "", { "dependencies": { "es5-ext": "^0.10.64", "type": "^2.7.2" } }, "sha512-MOqHvMWF9/9MX6nza0KgvFH4HpMU0EF5uUDXqX/BtxtU8NfB0QzRtJ8Oe/6SuS4kbhyzVJwjd97EA4PKrzJ8bw=="],
|
||||
|
||||
@ -1912,7 +1919,7 @@
|
||||
|
||||
"netmask": ["netmask@2.0.2", "", {}, "sha512-dBpDMdxv9Irdq66304OLfEmQ9tbNRFnFTuZiLo+bD+r332bBmMJ8GBLXklIXXgxd3+v9+KUnZaUR5PJMa75Gsg=="],
|
||||
|
||||
"next": ["next@15.5.6", "", { "dependencies": { "@next/env": "15.5.6", "@swc/helpers": "0.5.15", "caniuse-lite": "^1.0.30001579", "postcss": "8.4.31", "styled-jsx": "5.1.6" }, "optionalDependencies": { "@next/swc-darwin-arm64": "15.5.6", "@next/swc-darwin-x64": "15.5.6", "@next/swc-linux-arm64-gnu": "15.5.6", "@next/swc-linux-arm64-musl": "15.5.6", "@next/swc-linux-x64-gnu": "15.5.6", "@next/swc-linux-x64-musl": "15.5.6", "@next/swc-win32-arm64-msvc": "15.5.6", "@next/swc-win32-x64-msvc": "15.5.6", "sharp": "^0.34.3" }, "peerDependencies": { "@opentelemetry/api": "^1.1.0", "@playwright/test": "^1.51.1", "babel-plugin-react-compiler": "*", "react": "^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0", "react-dom": "^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0", "sass": "^1.3.0" }, "optionalPeers": ["@opentelemetry/api", "@playwright/test", "babel-plugin-react-compiler", "sass"], "bin": { "next": "dist/bin/next" } }, "sha512-zTxsnI3LQo3c9HSdSf91O1jMNsEzIXDShXd4wVdg9y5shwLqBXi4ZtUUJyB86KGVSJLZx0PFONvO54aheGX8QQ=="],
|
||||
"next": ["next@15.5.7", "", { "dependencies": { "@next/env": "15.5.7", "@swc/helpers": "0.5.15", "caniuse-lite": "^1.0.30001579", "postcss": "8.4.31", "styled-jsx": "5.1.6" }, "optionalDependencies": { "@next/swc-darwin-arm64": "15.5.7", "@next/swc-darwin-x64": "15.5.7", "@next/swc-linux-arm64-gnu": "15.5.7", "@next/swc-linux-arm64-musl": "15.5.7", "@next/swc-linux-x64-gnu": "15.5.7", "@next/swc-linux-x64-musl": "15.5.7", "@next/swc-win32-arm64-msvc": "15.5.7", "@next/swc-win32-x64-msvc": "15.5.7", "sharp": "^0.34.3" }, "peerDependencies": { "@opentelemetry/api": "^1.1.0", "@playwright/test": "^1.51.1", "babel-plugin-react-compiler": "*", "react": "^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0", "react-dom": "^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0", "sass": "^1.3.0" }, "optionalPeers": ["@opentelemetry/api", "@playwright/test", "babel-plugin-react-compiler", "sass"], "bin": { "next": "dist/bin/next" } }, "sha512-+t2/0jIJ48kUpGKkdlhgkv+zPTEOoXyr60qXe68eB/pl3CMJaLeIGjzp5D6Oqt25hCBiBTt8wEeeAzfJvUKnPQ=="],
|
||||
|
||||
"next-intl": ["next-intl@3.26.5", "", { "dependencies": { "@formatjs/intl-localematcher": "^0.5.4", "negotiator": "^1.0.0", "use-intl": "^3.26.5" }, "peerDependencies": { "next": "^10.0.0 || ^11.0.0 || ^12.0.0 || ^13.0.0 || ^14.0.0 || ^15.0.0", "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || >=19.0.0-rc <19.0.0 || ^19.0.0" } }, "sha512-EQlCIfY0jOhRldiFxwSXG+ImwkQtDEfQeSOEQp6ieAGSLWGlgjdb/Ck/O7wMfC430ZHGeUKVKax8KGusTPKCgg=="],
|
||||
|
||||
@ -2124,13 +2131,13 @@
|
||||
|
||||
"rc": ["rc@1.2.8", "", { "dependencies": { "deep-extend": "^0.6.0", "ini": "~1.3.0", "minimist": "^1.2.0", "strip-json-comments": "~2.0.1" }, "bin": { "rc": "./cli.js" } }, "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw=="],
|
||||
|
||||
"react": ["react@19.2.0", "", {}, "sha512-tmbWg6W31tQLeB5cdIBOicJDJRR2KzXsV7uSK9iNfLWQ5bIZfxuPEHp7M8wiHyHnn0DD1i7w3Zmin0FtkrwoCQ=="],
|
||||
"react": ["react@19.2.1", "", {}, "sha512-DGrYcCWK7tvYMnWh79yrPHt+vdx9tY+1gPZa7nJQtO/p8bLTDaHp4dzwEhQB7pZ4Xe3ok4XKuEPrVuc+wlpkmw=="],
|
||||
|
||||
"react-copy-to-clipboard": ["react-copy-to-clipboard@5.1.0", "", { "dependencies": { "copy-to-clipboard": "^3.3.1", "prop-types": "^15.8.1" }, "peerDependencies": { "react": "^15.3.0 || 16 || 17 || 18" } }, "sha512-k61RsNgAayIJNoy9yDsYzDe/yAZAzEbEgcz3DZMhF686LEyukcE1hzurxe85JandPUG+yTfGVFzuEw3xt8WP/A=="],
|
||||
|
||||
"react-day-picker": ["react-day-picker@9.11.1", "", { "dependencies": { "@date-fns/tz": "^1.4.1", "date-fns": "^4.1.0", "date-fns-jalali": "^4.1.0-0" }, "peerDependencies": { "react": ">=16.8.0" } }, "sha512-l3ub6o8NlchqIjPKrRFUCkTUEq6KwemQlfv3XZzzwpUeGwmDJ+0u0Upmt38hJyd7D/vn2dQoOoLV/qAp0o3uUw=="],
|
||||
|
||||
"react-dom": ["react-dom@19.2.0", "", { "dependencies": { "scheduler": "^0.27.0" }, "peerDependencies": { "react": "^19.2.0" } }, "sha512-UlbRu4cAiGaIewkPyiRGJk0imDN2T3JjieT6spoL2UeSf5od4n5LB/mQ4ejmxhCFT1tYe8IvaFulzynWovsEFQ=="],
|
||||
"react-dom": ["react-dom@19.2.1", "", { "dependencies": { "scheduler": "^0.27.0" }, "peerDependencies": { "react": "^19.2.1" } }, "sha512-ibrK8llX2a4eOskq1mXKu/TGZj9qzomO+sNfO98M6d9zIPOEhlBkMkBUBLd1vgS0gQsLDBzA+8jJBVXDnfHmJg=="],
|
||||
|
||||
"react-fast-compare": ["react-fast-compare@3.2.2", "", {}, "sha512-nsO+KSNgo1SbJqJEYRE9ERzo7YtYbou/OqjSQKxV7jcKox7+usiUVZOAC+XnDOABXggQTno0Y1CpVnuWEc1boQ=="],
|
||||
|
||||
@ -2700,6 +2707,10 @@
|
||||
|
||||
"@types/minimatch/minimatch": ["minimatch@9.0.5", "", { "dependencies": { "brace-expansion": "^2.0.1" } }, "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow=="],
|
||||
|
||||
"@types/react-copy-to-clipboard/@types/react": ["@types/react@19.2.2", "", { "dependencies": { "csstype": "^3.0.2" } }, "sha512-6mDvHUFSjyT2B2yeNx2nUgMxh9LtOWvkhIU3uePn2I2oyNymUAX1NIsdgviM4CH+JSrp2D2hsMvJOkxY+0wNRA=="],
|
||||
|
||||
"@types/react-syntax-highlighter/@types/react": ["@types/react@19.2.2", "", { "dependencies": { "csstype": "^3.0.2" } }, "sha512-6mDvHUFSjyT2B2yeNx2nUgMxh9LtOWvkhIU3uePn2I2oyNymUAX1NIsdgviM4CH+JSrp2D2hsMvJOkxY+0wNRA=="],
|
||||
|
||||
"@typescript-eslint/eslint-plugin/ignore": ["ignore@7.0.5", "", {}, "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg=="],
|
||||
|
||||
"@typescript-eslint/typescript-estree/minimatch": ["minimatch@9.0.5", "", { "dependencies": { "brace-expansion": "^2.0.1" } }, "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow=="],
|
||||
@ -2740,6 +2751,8 @@
|
||||
|
||||
"del/slash": ["slash@3.0.0", "", {}, "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q=="],
|
||||
|
||||
"dom-helpers/csstype": ["csstype@3.1.3", "", {}, "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw=="],
|
||||
|
||||
"env-ci/execa": ["execa@7.2.0", "", { "dependencies": { "cross-spawn": "^7.0.3", "get-stream": "^6.0.1", "human-signals": "^4.3.0", "is-stream": "^3.0.0", "merge-stream": "^2.0.0", "npm-run-path": "^5.1.0", "onetime": "^6.0.0", "signal-exit": "^3.0.7", "strip-final-newline": "^3.0.0" } }, "sha512-UduyVP7TLB5IcAQl+OzLyLcS/l32W/GLg+AhHJ+ow40FOk2U3SAllPwR44v4vmdFwIWqpdwxxpQbF1n5ta9seA=="],
|
||||
|
||||
"eslint-plugin-react/resolve": ["resolve@2.0.0-next.5", "", { "dependencies": { "is-core-module": "^2.13.0", "path-parse": "^1.0.7", "supports-preserve-symlinks-flag": "^1.0.0" }, "bin": { "resolve": "bin/resolve" } }, "sha512-U7WjGVG9sH8tvjW5SmGbQuui75FiyjAX72HX15DwBBwF9dNiQZRQAg9nnPhYy+TUnE0+VcrttuvNI8oSxZcocA=="],
|
||||
@ -3398,6 +3411,10 @@
|
||||
|
||||
"@types/minimatch/minimatch/brace-expansion": ["brace-expansion@2.0.2", "", { "dependencies": { "balanced-match": "^1.0.0" } }, "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ=="],
|
||||
|
||||
"@types/react-copy-to-clipboard/@types/react/csstype": ["csstype@3.1.3", "", {}, "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw=="],
|
||||
|
||||
"@types/react-syntax-highlighter/@types/react/csstype": ["csstype@3.1.3", "", {}, "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw=="],
|
||||
|
||||
"@typescript-eslint/typescript-estree/minimatch/brace-expansion": ["brace-expansion@2.0.2", "", { "dependencies": { "balanced-match": "^1.0.0" } }, "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ=="],
|
||||
|
||||
"cli-truncate/string-width/strip-ansi": ["strip-ansi@7.1.2", "", { "dependencies": { "ansi-regex": "^6.0.1" } }, "sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA=="],
|
||||
|
||||
@ -5,17 +5,21 @@ FROM oven/bun:latest AS base
|
||||
WORKDIR /app
|
||||
|
||||
# Create a non-root user for running the production application
|
||||
RUN addgroup --system --gid 1001 nodejs \
|
||||
&& adduser --system --uid 1001 nextjs
|
||||
|
||||
# Change to non-root user
|
||||
USER nextjs
|
||||
RUN apt-get update \
|
||||
&& apt-get install -y --no-install-recommends adduser \
|
||||
&& rm -rf /var/lib/apt/lists/* \
|
||||
&& addgroup --system --gid 1001 nodejs \
|
||||
&& adduser --system --uid 1001 --ingroup nodejs --home /nonexistent --shell /usr/sbin/nologin nextjs
|
||||
|
||||
# Copy necessary files for production
|
||||
COPY ./apps/admin/.next/standalone ./
|
||||
COPY ./apps/admin/.next/static ./apps/admin/.next/static
|
||||
COPY ./apps/admin/public ./apps/admin/public
|
||||
|
||||
# Change to non-root user
|
||||
RUN chown -R nextjs:nodejs /app
|
||||
USER nextjs
|
||||
|
||||
# Disable Next.js telemetry at runtime
|
||||
ENV NEXT_TELEMETRY_DISABLED=1
|
||||
|
||||
|
||||
@ -5,17 +5,19 @@ FROM oven/bun:latest AS base
|
||||
WORKDIR /app
|
||||
|
||||
# Create non-root user and set permissions
|
||||
RUN addgroup --system --gid 1001 nodejs \
|
||||
&& adduser --system --uid 1001 nextjs
|
||||
RUN apt-get update \
|
||||
&& apt-get install -y --no-install-recommends adduser \
|
||||
&& rm -rf /var/lib/apt/lists/* \
|
||||
&& addgroup --system --gid 1001 nodejs \
|
||||
&& adduser --system --uid 1001 --ingroup nodejs --home /nonexistent --shell /usr/sbin/nologin nextjs
|
||||
|
||||
# Copy build output and static files
|
||||
COPY ./apps/user/.next/standalone ./
|
||||
COPY ./apps/user/.next/static ./apps/user/.next/static
|
||||
COPY ./apps/user/public ./apps/user/public
|
||||
|
||||
# Change ownership to non-root user
|
||||
# Change to non-root user
|
||||
RUN chown -R nextjs:nodejs /app
|
||||
|
||||
USER nextjs
|
||||
|
||||
# Disable Next.js telemetry
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "ppanel-web",
|
||||
"version": "1.5.4",
|
||||
"version": "1.6.3",
|
||||
"private": true,
|
||||
"homepage": "https://github.com/perfect-panel/ppanel-web",
|
||||
"bugs": {
|
||||
@ -60,6 +60,7 @@
|
||||
"@iconify/react": "^5.2.0",
|
||||
"@lottiefiles/dotlottie-react": "^0.15.1",
|
||||
"@monaco-editor/react": "^4.7.0",
|
||||
"@noble/curves": "^2.0.1",
|
||||
"@radix-ui/react-accordion": "^1.2.12",
|
||||
"@radix-ui/react-alert-dialog": "^1.1.15",
|
||||
"@radix-ui/react-aspect-ratio": "^1.1.7",
|
||||
@ -135,8 +136,8 @@
|
||||
"lint-staged": "^16.1.5",
|
||||
"postcss": "^8.5.6",
|
||||
"prettier": "^3.4.2",
|
||||
"react": "^19.1.1",
|
||||
"react-dom": "^19.1.1",
|
||||
"react": "^19.2.1",
|
||||
"react-dom": "^19.2.1",
|
||||
"semantic-release": "21.1.2",
|
||||
"semantic-release-config-gitmoji": "^1.5.3",
|
||||
"tailwindcss": "^3.4.17",
|
||||
|
||||
@ -11,6 +11,7 @@
|
||||
"moduleDetection": "force",
|
||||
"moduleResolution": "NodeNext",
|
||||
"noUncheckedIndexedAccess": true,
|
||||
"typeRoots": ["./node_modules/@types"],
|
||||
"resolveJsonModule": true,
|
||||
"skipLibCheck": true,
|
||||
"strict": true,
|
||||
|
||||
@ -91,16 +91,16 @@
|
||||
"devDependencies": {
|
||||
"@turbo/gen": "^2.5.6",
|
||||
"@types/node": "^24.3.0",
|
||||
"@types/react": "^19.1.12",
|
||||
"@types/react-dom": "^19.1.9",
|
||||
"@types/react": "^19.2.7",
|
||||
"@types/react-dom": "^19.2.3",
|
||||
"@types/react-syntax-highlighter": "^15.5.13",
|
||||
"@types/rtl-detect": "^1.0.3",
|
||||
"@workspace/eslint-config": "workspace:*",
|
||||
"@workspace/typescript-config": "workspace:*",
|
||||
"autoprefixer": "^10.4.21",
|
||||
"postcss": "^8.5.6",
|
||||
"react": "^19.1.1",
|
||||
"react-dom": "^19.1.1",
|
||||
"react": "^19.2.1",
|
||||
"react-dom": "^19.2.1",
|
||||
"tailwindcss": "^3.4.17",
|
||||
"typescript": "^5.9.2"
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user