fix(frontend): align listener config form with backend schema (hy2 fields + grpc-opts/mekya inputs)

HIGH-1: remove max-idle-time from hysteria2 form + set()
HIGH-2: remove handshake-timeout from hysteria2 form + set() (kept for sudoku)
MEDIUM-1: narrow UDP_PROTOCOLS to ['shadowsocks', 'snell'] — vmess/vless/trojan udp toggle was dead (backend compile_modules.go strips it)
MEDIUM-2: add 5 R-M4 grpc-opts client-metadata Form.Items (grpc-user-agent, ping-interval, max-connections, min-streams, max-streams) on vmess/vless/trojan, with formValuesToConfig set() and configToFormValues reads
MEDIUM-3: add 2 R-M3 mekya-config client-metadata Form.Items (polling-interval-initial, h2-pool-size) on vmess, with mekya-config builder/reader fields
i18n: add 7 new keys + 6 hints to en.ts and zh.ts listeners section
Lint PASS (0 errors, 33 pre-existing fast-refresh warnings)
Build PASS (tsc -b + vite build OK)
fix(frontend): align listener config form with backend schema (hy2 fields + grpc-opts/mekya inputs)
HIGH-1: remove max-idle-time from hysteria2 form + set()
HIGH-2: remove handshake-timeout from hysteria2 form + set() (kept for sudoku)
MEDIUM-1: narrow UDP_PROTOCOLS to ['shadowsocks', 'snell'] — vmess/vless/trojan udp toggle was dead (backend compile_modules.go strips it)
MEDIUM-2: add 5 R-M4 grpc-opts client-metadata Form.Items (grpc-user-agent, ping-interval, max-connections, min-streams, max-streams) on vmess/vless/trojan, with formValuesToConfig set() and configToFormValues reads
MEDIUM-3: add 2 R-M3 mekya-config client-metadata Form.Items (polling-interval-initial, h2-pool-size) on vmess, with mekya-config builder/reader fields
i18n: add 7 new keys + 6 hints to en.ts and zh.ts listeners section
Lint PASS (0 errors, 33 pre-existing fast-refresh warnings)
Build PASS (tsc -b + vite build OK)
fix(frontend): align listener config form with backend schema (hy2 fields + grpc-opts/mekya inputs)
HIGH-1: remove max-idle-time from hysteria2 form + set()
HIGH-2: remove handshake-timeout from hysteria2 form + set() (kept for sudoku)
MEDIUM-1: narrow UDP_PROTOCOLS to ['shadowsocks', 'snell'] — vmess/vless/trojan udp toggle was dead (backend compile_modules.go strips it)
MEDIUM-2: add 5 R-M4 grpc-opts client-metadata Form.Items (grpc-user-agent, ping-interval, max-connections, min-streams, max-streams) on vmess/vless/trojan, with formValuesToConfig set() and configToFormValues reads
MEDIUM-3: add 2 R-M3 mekya-config client-metadata Form.Items (polling-interval-initial, h2-pool-size) on vmess, with mekya-config builder/reader fields
i18n: add 7 new keys + 6 hints to en.ts and zh.ts listeners section
Lint PASS (0 errors, 33 pre-existing fast-refresh warnings)
Build PASS (tsc -b + vite build OK)
fix(frontend): align listener config form with backend schema (hy2 fields + grpc-opts/mekya inputs)
HIGH-1: remove max-idle-time from hysteria2 form + set()
HIGH-2: remove handshake-timeout from hysteria2 form + set() (kept for sudoku)
MEDIUM-1: narrow UDP_PROTOCOLS to ['shadowsocks', 'snell'] — vmess/vless/trojan udp toggle was dead (backend compile_modules.go strips it)
MEDIUM-2: add 5 R-M4 grpc-opts client-metadata Form.Items (grpc-user-agent, ping-interval, max-connections, min-streams, max-streams) on vmess/vless/trojan, with formValuesToConfig set() and configToFormValues reads
MEDIUM-3: add 2 R-M3 mekya-config client-metadata Form.Items (polling-interval-initial, h2-pool-size) on vmess, with mekya-config builder/reader fields
i18n: add 7 new keys + 6 hints to en.ts and zh.ts listeners section
Lint PASS (0 errors, 33 pre-existing fast-refresh warnings)
Build PASS (tsc -b + vite build OK)
fix(frontend): align listener config form with backend schema (hy2 fields + grpc-opts/mekya inputs)
HIGH-1: remove max-idle-time from hysteria2 form + set()
HIGH-2: remove handshake-timeout from hysteria2 form + set() (kept for sudoku)
MEDIUM-1: narrow UDP_PROTOCOLS to ['shadowsocks', 'snell'] — vmess/vless/trojan udp toggle was dead (backend compile_modules.go strips it)
MEDIUM-2: add 5 R-M4 grpc-opts client-metadata Form.Items (grpc-user-agent, ping-interval, max-connections, min-streams, max-streams) on vmess/vless/trojan, with formValuesToConfig set() and configToFormValues reads
MEDIUM-3: add 2 R-M3 mekya-config client-metadata Form.Items (polling-interval-initial, h2-pool-size) on vmess, with mekya-config builder/reader fields
i18n: add 7 new keys + 6 hints to en.ts and zh.ts listeners section
Lint PASS (0 errors, 33 pre-existing fast-refresh warnings)
Build PASS (tsc -b + vite build OK)
fix(frontend): align listener config form with backend schema (hy2 fields + grpc-opts/mekya inputs)
HIGH-1: remove max-idle-time from hysteria2 form + set()
HIGH-2: remove handshake-timeout from hysteria2 form + set() (kept for sudoku)
MEDIUM-1: narrow UDP_PROTOCOLS to ['shadowsocks', 'snell'] — vmess/vless/trojan udp toggle was dead (backend compile_modules.go strips it)
MEDIUM-2: add 5 R-M4 grpc-opts client-metadata Form.Items (grpc-user-agent, ping-interval, max-connections, min-streams, max-streams) on vmess/vless/trojan, with formValuesToConfig set() and configToFormValues reads
MEDIUM-3: add 2 R-M3 mekya-config client-metadata Form.Items (polling-interval-initial, h2-pool-size) on vmess, with mekya-config builder/reader fields
i18n: add 7 new keys + 6 hints to en.ts and zh.ts listeners section
Lint PASS (0 errors, 33 pre-existing fast-refresh warnings)
Build PASS (tsc -b + vite build OK)
fix(frontend): align listener config form with backend schema (hy2 fields + grpc-opts/mekya inputs)
HIGH-1: remove max-idle-time from hysteria2 form + set()
HIGH-2: remove handshake-timeout from hysteria2 form + set() (kept for sudoku)
MEDIUM-1: narrow UDP_PROTOCOLS to ['shadowsocks', 'snell'] — vmess/vless/trojan udp toggle was dead (backend compile_modules.go strips it)
MEDIUM-2: add 5 R-M4 grpc-opts client-metadata Form.Items (grpc-user-agent, ping-interval, max-connections, min-streams, max-streams) on vmess/vless/trojan, with formValuesToConfig set() and configToFormValues reads
MEDIUM-3: add 2 R-M3 mekya-config client-metadata Form.Items (polling-interval-initial, h2-pool-size) on vmess, with mekya-config builder/reader fields
i18n: add 7 new keys + 6 hints to en.ts and zh.ts listeners section
Lint PASS (0 errors, 33 pre-existing fast-refresh warnings)
Build PASS (tsc -b + vite build OK)
fix(frontend): align listener config form with backend schema (hy2 fields + grpc-opts/mekya inputs)
HIGH-1: remove max-idle-time from hysteria2 form + set()
HIGH-2: remove handshake-timeout from hysteria2 form + set() (kept for sudoku)
MEDIUM-1: narrow UDP_PROTOCOLS to ['shadowsocks', 'snell'] — vmess/vless/trojan udp toggle was dead (backend compile_modules.go strips it)
MEDIUM-2: add 5 R-M4 grpc-opts client-metadata Form.Items (grpc-user-agent, ping-interval, max-connections, min-streams, max-streams) on vmess/vless/trojan, with formValuesToConfig set() and configToFormValues reads
MEDIUM-3: add 2 R-M3 mekya-config client-metadata Form.Items (polling-interval-initial, h2-pool-size) on vmess, with mekya-config builder/reader fields
i18n: add 7 new keys + 6 hints to en.ts and zh.ts listeners section
Lint PASS (0 errors, 33 pre-existing fast-refresh warnings)
Build PASS (tsc -b + vite build OK)
fix(frontend): align listener config form with backend schema (hy2 fields + grpc-opts/mekya inputs)
HIGH-1: remove max-idle-time from hysteria2 form + set()
HIGH-2: remove handshake-timeout from hysteria2 form + set() (kept for sudoku)
MEDIUM-1: narrow UDP_PROTOCOLS to ['shadowsocks', 'snell'] — vmess/vless/trojan udp toggle was dead (backend compile_modules.go strips it)
MEDIUM-2: add 5 R-M4 grpc-opts client-metadata Form.Items (grpc-user-agent, ping-interval, max-connections, min-streams, max-streams) on vmess/vless/trojan, with formValuesToConfig set() and configToFormValues reads
MEDIUM-3: add 2 R-M3 mekya-config client-metadata Form.Items (polling-interval-initial, h2-pool-size) on vmess, with mekya-config builder/reader fields
i18n: add 7 new keys + 6 hints to en.ts and zh.ts listeners section
Lint PASS (0 errors, 33 pre-existing fast-refresh warnings)
Build PASS (tsc -b + vite build OK)
fix(frontend): align listener config form with backend schema (hy2 fields + grpc-opts/mekya inputs)
HIGH-1: remove max-idle-time from hysteria2 form + set()
HIGH-2: remove handshake-timeout from hysteria2 form + set() (kept for sudoku)
MEDIUM-1: narrow UDP_PROTOCOLS to ['shadowsocks', 'snell'] — vmess/vless/trojan udp toggle was dead (backend compile_modules.go strips it)
MEDIUM-2: add 5 R-M4 grpc-opts client-metadata Form.Items (grpc-user-agent, ping-interval, max-connections, min-streams, max-streams) on vmess/vless/trojan, with formValuesToConfig set() and configToFormValues reads
MEDIUM-3: add 2 R-M3 mekya-config client-metadata Form.Items (polling-interval-initial, h2-pool-size) on vmess, with mekya-config builder/reader fields
i18n: add 7 new keys + 6 hints to en.ts and zh.ts listeners section
Lint PASS (0 errors, 33 pre-existing fast-refresh warnings)
Build PASS (tsc -b + vite build OK)
fix(frontend): align listener config form with backend schema (hy2 fields + grpc-opts/mekya inputs)
HIGH-1: remove max-idle-time from hysteria2 form + set()
HIGH-2: remove handshake-timeout from hysteria2 form + set() (kept for sudoku)
MEDIUM-1: narrow UDP_PROTOCOLS to ['shadowsocks', 'snell'] — vmess/vless/trojan udp toggle was dead (backend compile_modules.go strips it)
MEDIUM-2: add 5 R-M4 grpc-opts client-metadata Form.Items (grpc-user-agent, ping-interval, max-connections, min-streams, max-streams) on vmess/vless/trojan, with formValuesToConfig set() and configToFormValues reads
MEDIUM-3: add 2 R-M3 mekya-config client-metadata Form.Items (polling-interval-initial, h2-pool-size) on vmess, with mekya-config builder/reader fields
i18n: add 7 new keys + 6 hints to en.ts and zh.ts listeners section
Lint PASS (0 errors, 33 pre-existing fast-refresh warnings)
Build PASS (tsc -b + vite build OK)
fix(frontend): align listener config form with backend schema (hy2 fields + grpc-opts/mekya inputs)
HIGH-1: remove max-idle-time from hysteria2 form + set()
HIGH-2: remove handshake-timeout from hysteria2 form + set() (kept for sudoku)
MEDIUM-1: narrow UDP_PROTOCOLS to ['shadowsocks', 'snell'] — vmess/vless/trojan udp toggle was dead (backend compile_modules.go strips it)
MEDIUM-2: add 5 R-M4 grpc-opts client-metadata Form.Items (grpc-user-agent, ping-interval, max-connections, min-streams, max-streams) on vmess/vless/trojan, with formValuesToConfig set() and configToFormValues reads
MEDIUM-3: add 2 R-M3 mekya-config client-metadata Form.Items (polling-interval-initial, h2-pool-size) on vmess, with mekya-config builder/reader fields
i18n: add 7 new keys + 6 hints to en.ts and zh.ts listeners section
Lint PASS (0 errors, 33 pre-existing fast-refresh warnings)
Build PASS (tsc -b + vite build OK)
This commit is contained in:
Z User committed 2026-09-03 16:05:49 +00:00
1 parent fbca88a534
commit 4dde61e8db
3 files changed
+71 -14

No files matched your search

@@ -30,7 +30,7 @@ const ALWAYS_TLS_PROTOCOLS = new Set(['hysteria2', 'tuic', 'tuic-v4', 'tuic-v5',
const OPTIONAL_SECURITY_PROTOCOLS = new Set(['vmess', 'vless', 'trojan']);
const REALITY_PROTOCOLS = new Set(['vmess', 'vless', 'trojan']);
const TRANSPORT_PROTOCOLS = new Set(['vmess', 'vless', 'trojan']);
const UDP_PROTOCOLS = new Set(['shadowsocks', 'snell', 'vmess', 'vless', 'trojan']);
const UDP_PROTOCOLS = new Set(['shadowsocks', 'snell']);
/** Protocols that support shadow-tls / res-tls / jls-config wrappers */
const WRAPPER_TLS_PROTOCOLS = new Set([
'shadowsocks', 'snell', 'vmess', 'vless', 'trojan', 'anytls',
@@ -213,6 +213,9 @@ export function configToFormValues(raw: string | undefined | null): Record<strin
values.mekya_max_write_duration_ms = m['max-write-duration-ms'];
values.mekya_max_simultaneous_write_connection = m['max-simultaneous-write-connection'];
values.mekya_packet_writing_buffer = m['packet-writing-buffer'];
// R-M3 client-metadata fields (vmess only)
if (m['polling-interval-initial'] != null) values['mekya-polling-interval-initial'] = m['polling-interval-initial'];
if (m['h2-pool-size'] != null) values['mekya-h2-pool-size'] = m['h2-pool-size'];
const kcp = m.kcp && typeof m.kcp === 'object' ? m.kcp : {};
values.mekya_kcp_mtu = kcp.mtu;
values.mekya_kcp_tti = kcp.tti;
@@ -290,6 +293,14 @@ export function configToFormValues(raw: string | undefined | null): Record<strin
if (cfg['bbr-profile']) values['bbr-profile'] = cfg['bbr-profile'];
if (cfg['quic-versions']) values['quic-versions'] = asStringList(cfg['quic-versions']);
if (cfg.cwnd != null) values.cwnd = cfg.cwnd;
// R-M4 grpc-opts client-metadata fields (vmess/vless/trojan). The top-level
// scalar loop above already copies them; these explicit reads are redundant
// but kept for clarity and to survive any future change to that loop.
if (cfg['grpc-user-agent'] != null) values['grpc-user-agent'] = cfg['grpc-user-agent'];
if (cfg['ping-interval'] != null) values['ping-interval'] = cfg['ping-interval'];
if (cfg['max-connections'] != null) values['max-connections'] = cfg['max-connections'];
if (cfg['min-streams'] != null) values['min-streams'] = cfg['min-streams'];
if (cfg['max-streams'] != null) values['max-streams'] = cfg['max-streams'];
// ALPN
if (cfg.alpn && !Array.isArray(cfg.alpn)) {
@@ -421,6 +432,13 @@ export function formValuesToConfig(
}
set('ws-path', values['ws-path']);
set('grpc-service-name', values['grpc-service-name']);
// R-M4 grpc-opts client-metadata fields (panel-side; converter emits them
// into the client-side grpc-opts block).
set('grpc-user-agent', values['grpc-user-agent']);
set('ping-interval', toInt(values['ping-interval']));
set('max-connections', toInt(values['max-connections']));
set('min-streams', toInt(values['min-streams']));
set('max-streams', toInt(values['max-streams']));
break;
case 'vless':
set('flow', values.flow);
@@ -428,10 +446,22 @@ export function formValuesToConfig(
set('grpc-service-name', values['grpc-service-name']);
set('decryption', values.decryption);
set('encryption', values.encryption);
// R-M4 grpc-opts client-metadata fields
set('grpc-user-agent', values['grpc-user-agent']);
set('ping-interval', toInt(values['ping-interval']));
set('max-connections', toInt(values['max-connections']));
set('min-streams', toInt(values['min-streams']));
set('max-streams', toInt(values['max-streams']));
break;
case 'trojan':
set('ws-path', values['ws-path']);
set('grpc-service-name', values['grpc-service-name']);
// R-M4 grpc-opts client-metadata fields
set('grpc-user-agent', values['grpc-user-agent']);
set('ping-interval', toInt(values['ping-interval']));
set('max-connections', toInt(values['max-connections']));
set('min-streams', toInt(values['min-streams']));
set('max-streams', toInt(values['max-streams']));
if (values.ss_option_enabled) {
cfg['ss-option'] = cleanObj({
enabled: true,
@@ -448,8 +478,10 @@ export function formValuesToConfig(
set('obfs-password', values['obfs-password']);
set('masquerade', values.masquerade);
set('alpn', values.alpn);
set('max-idle-time', values['max-idle-time']);
set('handshake-timeout', values['handshake-timeout']);
// HIGH-1 / HIGH-2: max-idle-time + handshake-timeout removed from hy2 —
// backend hy2 schema (listener_schema_registry.go:161-163) does NOT
// whitelist them and HARD-REJECTs every save. They are CLIENT-side or
// TUIC/Sudoku-only fields per wiki + fix-A HIGH-5.
set('bbr-profile', values['bbr-profile']);
break;
case 'tuic':
@@ -722,6 +754,10 @@ export function formValuesToConfig(
'max-write-duration-ms': values.mekya_max_write_duration_ms,
'max-simultaneous-write-connection': values.mekya_max_simultaneous_write_connection,
'packet-writing-buffer': values.mekya_packet_writing_buffer,
// R-M3 client-metadata fields (vmess only; converter reads them for
// client-side mekya-opts emission).
'polling-interval-initial': values['mekya-polling-interval-initial'],
'h2-pool-size': values['mekya-h2-pool-size'],
kcp,
}) || { enable: true };
}
@@ -934,9 +970,29 @@ const ListenerConfigFields: React.FC<Props> = ({ protocol }) => {
</Form.Item>
)}
{layer === 'grpc' && (
<Form.Item name="grpc-service-name" label={t('listeners.grpcServiceName')} tooltip={t('listeners.grpcHint')} rules={[{ required: true }]}>
<Input placeholder="GunService" />
</Form.Item>
<>
<Form.Item name="grpc-service-name" label={t('listeners.grpcServiceName')} tooltip={t('listeners.grpcHint')} rules={[{ required: true }]}>
<Input placeholder="GunService" />
</Form.Item>
{/* R-M4 grpc-opts client-metadata fields (vmess/vless/trojan).
These are panel-side metadata consumed by converter/client.go
to populate the client-side grpc-opts block. */}
<Form.Item name="grpc-user-agent" label={t('listeners.grpcUserAgent')} tooltip={t('listeners.grpcUserAgentHint')}>
<Input placeholder="Go-http-client/1.1" />
</Form.Item>
<Form.Item name="ping-interval" label={t('listeners.pingInterval')} tooltip={t('listeners.pingIntervalHint')}>
<InputNumber min={0} style={{ width: '100%' }} placeholder="0" />
</Form.Item>
<Form.Item name="max-connections" label={t('listeners.maxConnections')} tooltip={t('listeners.maxConnectionsHint')}>
<InputNumber min={0} style={{ width: '100%' }} placeholder="0" />
</Form.Item>
<Form.Item name="min-streams" label={t('listeners.minStreams')} tooltip={t('listeners.minStreamsHint')}>
<InputNumber min={0} style={{ width: '100%' }} placeholder="0" />
</Form.Item>
<Form.Item name="max-streams" label={t('listeners.maxStreams')} tooltip={t('listeners.maxStreamsHint')}>
<InputNumber min={0} style={{ width: '100%' }} placeholder="0" />
</Form.Item>
</>
)}
</>
);
@@ -982,12 +1038,6 @@ const ListenerConfigFields: React.FC<Props> = ({ protocol }) => {
<Form.Item name="alpn" label={t('listeners.alpn')}>
<Select mode="tags" placeholder="h3" tokenSeparators={[',']} />
</Form.Item>
<Form.Item name="max-idle-time" label={t('listeners.maxIdleTime')}>
<InputNumber min={0} style={{ width: '100%' }} placeholder="15000" />
</Form.Item>
<Form.Item name="handshake-timeout" label={t('listeners.handshakeTimeout')}>
<InputNumber min={0} style={{ width: '100%' }} />
</Form.Item>
<Form.Item name="bbr-profile" label={t('listeners.bbrProfile')}>
<Input />
</Form.Item>
@@ -1504,6 +1554,13 @@ const ListenerConfigFields: React.FC<Props> = ({ protocol }) => {
<Form.Item name="mekya_packet_writing_buffer" label={t('listeners.mekyaPacketBuffer')} tooltip={t('listeners.mekyaPacketBufferHint')}>
<InputNumber min={0} style={{ width: '100%' }} placeholder="65536" />
</Form.Item>
{/* R-M3 client-metadata fields (vmess only) */}
<Form.Item name="mekya-polling-interval-initial" label={t('listeners.mekyaPollingInterval')}>
<InputNumber min={0} style={{ width: '100%' }} />
</Form.Item>
<Form.Item name="mekya-h2-pool-size" label={t('listeners.mekyaH2PoolSize')}>
<InputNumber min={0} style={{ width: '100%' }} />
</Form.Item>
<Divider titlePlacement="start" plain style={{ marginTop: 8 }}>{t('listeners.mekyaKcpSection')}</Divider>
<Form.Item name="mekya_kcp_mtu" label="MTU">
<InputNumber min={0} style={{ width: '100%' }} placeholder="1350" />
+1 -1
View File
@@ -15,7 +15,7 @@ export default {
sectionSecurity: 'Security',
sectionTransport: 'Transport', sectionTLS: 'TLS certificate', sectionReality: 'Reality', sectionSSOption: 'Trojan SS option', cipher: 'Cipher', password: 'Password', passwordOptional: 'Password (optional)', uuid: 'UUID', privateKey: 'Private key', certificate: 'Certificate', alpn: 'ALPN', sni: 'SNI', clientFingerprint: 'Client fingerprint', allowInsecure: 'Allow insecure', muxOption: 'Mux', realityPrivateKey: 'Reality private key', realityShortID: 'Short ID', realityServerNames: 'Server names', realityDest: 'Dest', transport: 'Transport', path: 'Path', host: 'Host', serviceName: 'Service name', up: 'Up', down: 'Down', ignoreClientBandwidth: 'Ignore client bandwidth', masquerade: 'Masquerade', congestionControl: 'Congestion control', clone: 'Clone', saveTemplate: 'Save as template', versions: 'Versions', cloned: 'Cloned', templateCreated: 'Template created', instantiated: 'Listener created from template', batchDone: 'Batch operation completed', templates: 'Listener Templates', templateName: 'Template name', createdAt: 'Created at', instantiate: 'Instantiate', deleteTemplateConfirm: 'Delete this template?', templateDeleted: 'Template deleted', enableSelected: 'Enable selected', disableSelected: 'Disable selected', newPort: 'New port', version: 'Version', reason: 'Reason', diff: 'Diff', rollback: 'Rollback', rollbackConfirm: 'Rollback to this version?', rollbackDone: 'Rollback completed' , addUser: 'Add user', aeadMethod: 'AEAD method', allowInsecureHint: 'Allow insecure (debug only)', alterId: 'Alter ID', alterIdHint: 'VMess alterId, prefer 0', authenticationTimeout: 'Auth timeout', bandwidthHint: 'Bandwidth limit, e.g. 100 mbps', bbrProfile: 'BBR profile', clientAuthCert: 'Client cert', clientAuthType: 'Client auth type', congestionController: 'Congestion controller', createWizard: 'Create listener wizard', cwnd: 'CWND', decryption: 'Decryption',
encryption: 'Encryption',
encryptionHint: 'Client-side VLESS encryption pair from generate output; do not reuse the decryption value', decryptionHint: 'Server-side VLESS decryption from mihomo generate vless-x25519 / vless-mlkem768', echKey: 'ECH Key', enablePureDownlink: 'Pure downlink', flow: 'Flow', flowHint: 'e.g. xtls-rprx-vision', grpcHint: 'gRPC transport', grpcServiceName: 'gRPC service name', handshakeTimeout: 'Handshake timeout', jlsDest: 'JLS dest', jlsHint: 'JLS settings', jlsProxy: 'JLS proxy', jlsSni: 'JLS SNI', jlsSniHint: 'JLS SNI hostname', jlsUpstreamAddr: 'JLS upstream', jlsUsers: 'JLS users', kcpTunConn: 'KCP connections', kcpTunCrypt: 'KCP crypt', kcpTunKey: 'KCP key', kcpTunMode: 'KCP mode', kcpTunNocomp: 'KCP no compress', kcpTunRcvwnd: 'KCP recv window', kcpTunSndwnd: 'KCP send window', maxIdleTime: 'Max idle time', maxUdpRelayPacketSize: 'Max UDP relay packet', mekyaHint: 'Mekya settings', mekyaKcpSection: 'Mekya KCP', mekyaMaxSimultaneous: 'Max simultaneous', mekyaMaxSimultaneousHint: 'Max concurrent connections', mekyaMaxWriteDuration: 'Max write duration', mekyaMaxWriteDurationHint: 'Write timeout', mekyaMaxWriteSize: 'Max write size', mekyaMaxWriteSizeHint: 'Single write limit', mekyaPacketBuffer: 'Packet buffer', mekyaPacketBufferHint: 'Packet buffer size', mkcpCongestion: 'mKCP congestion', mkcpDownlink: 'mKCP downlink', mkcpHeader: 'mKCP header', mkcpHint: 'mKCP transport', mkcpReadBuffer: 'mKCP read buffer', mkcpSeed: 'mKCP seed', mkcpUplink: 'mKCP uplink', mkcpWriteBuffer: 'mKCP write buffer', muxBrutal: 'Mux brutal', muxBrutalDown: 'Brutal down', muxBrutalUp: 'Brutal up', muxMaxConnections: 'Mux max connections', muxMaxStreams: 'Mux max streams', muxMinStreams: 'Mux min streams', muxOnlyTcp: 'Mux TCP only', muxPadding: 'Mux padding', muxProtocol: 'Mux protocol', muxStatistic: 'Mux statistics', network: 'Network', obfs: 'Obfuscation', obfsMaxPacketSize: 'Obfs max packet', obfsMinPacketSize: 'Obfs min packet', obfsOptsHost: 'Obfs host', obfsOptsMode: 'Obfs mode', obfsPassword: 'Obfs password', paddingMax: 'Padding max', paddingMin: 'Padding min', paddingScheme: 'Padding scheme', psk: 'PSK', quicVersions: 'QUIC versions', rateLimit: 'Rate limit', rateLimitHint: 'e.g. 10m', realityExclusiveHint: 'Reality and TLS cert are mutually exclusive', realityShortId: 'Reality short ID', realmId: 'Realm ID', realmProxy: 'Realm proxy', realmServerUrl: 'Realm server URL', realmSkipCert: 'Skip cert verify', realmStun: 'STUN', realmToken: 'Realm token', resTlsDest: 'ResTLS dest', resTlsHint: 'ResTLS settings', resTlsMinRecordLen: 'Min record length', resTlsPassword: 'ResTLS password', resTlsProxy: 'ResTLS proxy', resTlsScript: 'ResTLS script', sectionJLS: 'JLS', sectionJlsUpstream: 'JLS upstream', sectionKcpTun: 'KCP Tun', sectionMekya: 'Mekya', sectionMkcp: 'mKCP', sectionMux: 'Mux', sectionRealm: 'Realm', sectionResTLS: 'ResTLS', sectionShadowTLS: 'ShadowTLS', sectionSimpleObfs: 'Simple Obfs', sectionXHTTP: 'XHTTP', shadowTlsHandshakeDest: 'Handshake dest', shadowTlsHandshakeProxy: 'Handshake proxy', shadowTlsHint: 'ShadowTLS settings', shadowTlsPassword: 'ShadowTLS password', shadowTlsPasswordHint: 'v2/v3 password', shadowTlsUsers: 'ShadowTLS users', shadowTlsVersion: 'ShadowTLS version', simpleObfsMode: 'Simple Obfs mode', snellVersion: 'Snell version', ssOptionMethod: 'SS method', ssOptionPassword: 'SS password', sudokuKey: 'Sudoku key', customTable: 'Custom table', customTables: 'Custom tables', sudokuFallback: 'Fallback', sectionHttpmask: 'HTTPMask', httpmaskDisable: 'Disable HTTP mask', httpmaskMode: 'HTTP mask mode', httpmaskPathRoot: 'HTTP path root', tableType: 'Table type', tlsPairHint: 'Certificate and private key must both be set', token: 'Token', tokenHint: 'Auth token', tokenPlaceholder: 'Enter token', trafficPattern: 'Traffic pattern', userHintMandatory: 'At least one user required', wizardBasic: 'Basics', wizardConfig: 'Protocol', wizardConfigHint: 'Fill protocol-specific fields (TLS / Reality / users, etc.)', wizardReview: 'Review', wsPath: 'WebSocket path', wsPathHint: 'e.g. /ws', xhttpHint: 'XHTTP transport', xhttpHost: 'XHTTP host', xhttpMode: 'XHTTP mode', xhttpPath: 'XHTTP path', zeroRtt: '0-RTT'},
encryptionHint: 'Client-side VLESS encryption pair from generate output; do not reuse the decryption value', decryptionHint: 'Server-side VLESS decryption from mihomo generate vless-x25519 / vless-mlkem768', echKey: 'ECH Key', enablePureDownlink: 'Pure downlink', flow: 'Flow', flowHint: 'e.g. xtls-rprx-vision', grpcHint: 'gRPC transport', grpcServiceName: 'gRPC service name', grpcUserAgent: 'gRPC User-Agent', grpcUserAgentHint: 'gRPC client User-Agent string (panel-side metadata; emitted into client-side grpc-opts).', pingInterval: 'Ping interval (ms)', pingIntervalHint: 'gRPC keepalive ping interval (panel-side metadata; emitted into client-side grpc-opts).', maxConnections: 'Max connections', maxConnectionsHint: 'gRPC max concurrent connections (panel-side metadata).', minStreams: 'Min streams', minStreamsHint: 'gRPC min concurrent streams (panel-side metadata).', maxStreams: 'Max streams', maxStreamsHint: 'gRPC max concurrent streams (panel-side metadata).', handshakeTimeout: 'Handshake timeout', jlsDest: 'JLS dest', jlsHint: 'JLS settings', jlsProxy: 'JLS proxy', jlsSni: 'JLS SNI', jlsSniHint: 'JLS SNI hostname', jlsUpstreamAddr: 'JLS upstream', jlsUsers: 'JLS users', kcpTunConn: 'KCP connections', kcpTunCrypt: 'KCP crypt', kcpTunKey: 'KCP key', kcpTunMode: 'KCP mode', kcpTunNocomp: 'KCP no compress', kcpTunRcvwnd: 'KCP recv window', kcpTunSndwnd: 'KCP send window', maxIdleTime: 'Max idle time', maxUdpRelayPacketSize: 'Max UDP relay packet', mekyaHint: 'Mekya settings', mekyaKcpSection: 'Mekya KCP', mekyaMaxSimultaneous: 'Max simultaneous', mekyaMaxSimultaneousHint: 'Max concurrent connections', mekyaMaxWriteDuration: 'Max write duration', mekyaMaxWriteDurationHint: 'Write timeout', mekyaMaxWriteSize: 'Max write size', mekyaMaxWriteSizeHint: 'Single write limit', mekyaPacketBuffer: 'Packet buffer', mekyaPacketBufferHint: 'Packet buffer size', mekyaPollingInterval: 'Polling interval (ms)', mekyaH2PoolSize: 'H2 pool size', mkcpCongestion: 'mKCP congestion', mkcpDownlink: 'mKCP downlink', mkcpHeader: 'mKCP header', mkcpHint: 'mKCP transport', mkcpReadBuffer: 'mKCP read buffer', mkcpSeed: 'mKCP seed', mkcpUplink: 'mKCP uplink', mkcpWriteBuffer: 'mKCP write buffer', muxBrutal: 'Mux brutal', muxBrutalDown: 'Brutal down', muxBrutalUp: 'Brutal up', muxMaxConnections: 'Mux max connections', muxMaxStreams: 'Mux max streams', muxMinStreams: 'Mux min streams', muxOnlyTcp: 'Mux TCP only', muxPadding: 'Mux padding', muxProtocol: 'Mux protocol', muxStatistic: 'Mux statistics', network: 'Network', obfs: 'Obfuscation', obfsMaxPacketSize: 'Obfs max packet', obfsMinPacketSize: 'Obfs min packet', obfsOptsHost: 'Obfs host', obfsOptsMode: 'Obfs mode', obfsPassword: 'Obfs password', paddingMax: 'Padding max', paddingMin: 'Padding min', paddingScheme: 'Padding scheme', psk: 'PSK', quicVersions: 'QUIC versions', rateLimit: 'Rate limit', rateLimitHint: 'e.g. 10m', realityExclusiveHint: 'Reality and TLS cert are mutually exclusive', realityShortId: 'Reality short ID', realmId: 'Realm ID', realmProxy: 'Realm proxy', realmServerUrl: 'Realm server URL', realmSkipCert: 'Skip cert verify', realmStun: 'STUN', realmToken: 'Realm token', resTlsDest: 'ResTLS dest', resTlsHint: 'ResTLS settings', resTlsMinRecordLen: 'Min record length', resTlsPassword: 'ResTLS password', resTlsProxy: 'ResTLS proxy', resTlsScript: 'ResTLS script', sectionJLS: 'JLS', sectionJlsUpstream: 'JLS upstream', sectionKcpTun: 'KCP Tun', sectionMekya: 'Mekya', sectionMkcp: 'mKCP', sectionMux: 'Mux', sectionRealm: 'Realm', sectionResTLS: 'ResTLS', sectionShadowTLS: 'ShadowTLS', sectionSimpleObfs: 'Simple Obfs', sectionXHTTP: 'XHTTP', shadowTlsHandshakeDest: 'Handshake dest', shadowTlsHandshakeProxy: 'Handshake proxy', shadowTlsHint: 'ShadowTLS settings', shadowTlsPassword: 'ShadowTLS password', shadowTlsPasswordHint: 'v2/v3 password', shadowTlsUsers: 'ShadowTLS users', shadowTlsVersion: 'ShadowTLS version', simpleObfsMode: 'Simple Obfs mode', snellVersion: 'Snell version', ssOptionMethod: 'SS method', ssOptionPassword: 'SS password', sudokuKey: 'Sudoku key', customTable: 'Custom table', customTables: 'Custom tables', sudokuFallback: 'Fallback', sectionHttpmask: 'HTTPMask', httpmaskDisable: 'Disable HTTP mask', httpmaskMode: 'HTTP mask mode', httpmaskPathRoot: 'HTTP path root', tableType: 'Table type', tlsPairHint: 'Certificate and private key must both be set', token: 'Token', tokenHint: 'Auth token', tokenPlaceholder: 'Enter token', trafficPattern: 'Traffic pattern', userHintMandatory: 'At least one user required', wizardBasic: 'Basics', wizardConfig: 'Protocol', wizardConfigHint: 'Fill protocol-specific fields (TLS / Reality / users, etc.)', wizardReview: 'Review', wsPath: 'WebSocket path', wsPathHint: 'e.g. /ws', xhttpHint: 'XHTTP transport', xhttpHost: 'XHTTP host', xhttpMode: 'XHTTP mode', xhttpPath: 'XHTTP path', zeroRtt: '0-RTT'},
core: { title: 'Core', status: 'Status', running: 'Running', stoppedStatus: 'Stopped', version: 'Version', pid: 'PID', uptime: 'Uptime', start: 'Start', stop: 'Stop', restart: 'Restart', started: 'Started', stopped: 'Stopped', restarted: 'Restarted' , operationFailed: 'Operation failed', unavailable: 'Core unavailable'},
logs: { title: 'Logs', empty: 'No logs', level: 'Level', timestamp: 'Time', payload: 'Payload', autoRefresh: 'Auto refresh', clear: 'Clear' },
config: { title: 'Config Engine', subtitle: 'Visual Mihomo configuration', visual: 'Visual Config', yaml: 'YAML Config', proxies: 'Proxy Configuration', yamlPreview: 'YAML Preview', addProxy: 'Add Proxy', editProxy: 'Edit Proxy', deleteProxy: 'Delete Proxy', deleteConfirm: 'Delete this proxy?', generateSuccess: 'Configuration generated successfully', validateSuccess: 'Configuration is valid', validateFailed: 'Configuration validation failed', proxyName: 'Proxy Name', proxyType: 'Proxy Type', proxyServer: 'Proxy Server', proxyPort: 'Proxy Port', proxyPassword: 'Proxy Password', proxyUUID: 'Proxy UUID' , generate: 'Generate config', validate: 'Validate config'},
+1 -1
View File
@@ -15,7 +15,7 @@ export default {
sectionSecurity: '安全层',
sectionTransport: '传输层', sectionTLS: 'TLS 证书', sectionReality: 'Reality', sectionSSOption: 'Trojan SS 混淆', cipher: '加密方法', password: '密码', passwordOptional: '密码(可选)', uuid: 'UUID', privateKey: '私钥', certificate: '证书', alpn: 'ALPN', sni: 'SNI', clientFingerprint: '客户端指纹', allowInsecure: '允许不安全', muxOption: '多路复用', realityPrivateKey: 'Reality 私钥', realityShortID: 'Short ID', realityServerNames: 'Server Names', realityDest: 'Dest', transport: '传输', path: '路径', host: 'Host', serviceName: 'Service Name', up: '上行', down: '下行', ignoreClientBandwidth: '忽略客户端带宽', masquerade: 'Masquerade', congestionControl: '拥塞控制', clone: '克隆', saveTemplate: '保存为模板', versions: '配置版本', cloned: '克隆成功', templateCreated: '模板创建成功', instantiated: '已从模板创建节点', batchDone: '批量操作完成', templates: '节点模板', templateName: '模板名称', createdAt: '创建时间', instantiate: '实例化', deleteTemplateConfirm: '确定删除此模板?', templateDeleted: '模板已删除', enableSelected: '启用选中', disableSelected: '禁用选中', newPort: '新端口', version: '版本', reason: '原因', diff: '配置差异', rollback: '回滚', rollbackConfirm: '确定回滚到此版本?', rollbackDone: '回滚完成' , addUser: '添加用户', aeadMethod: 'AEAD 加密方式', allowInsecureHint: '允许不安全连接(仅调试)', alterId: 'Alter ID', alterIdHint: 'VMess 额外 ID,建议 0', authenticationTimeout: '认证超时', bandwidthHint: '带宽限制,如 100 mbps', bbrProfile: 'BBR 配置', clientAuthCert: '客户端证书', clientAuthType: '客户端认证类型', congestionController: '拥塞控制', createWizard: '向导创建节点', cwnd: 'CWND', decryption: '解密',
encryption: 'Encryption',
encryptionHint: '客户端 VLESS Encryption:与 decryption 成对,取 generate 输出的 encryption 一侧,勿直接复制 decryption', decryptionHint: '服务端 VLESS Encryption:由 mihomo generate vless-x25519 / vless-mlkem768 生成,填 decryption 一侧', echKey: 'ECH Key', enablePureDownlink: '纯下行', flow: '流控', flowHint: '如 xtls-rprx-vision', grpcHint: 'gRPC 传输', grpcServiceName: 'gRPC Service Name', handshakeTimeout: '握手超时', jlsDest: 'JLS 目标', jlsHint: 'Joliz 相关配置', jlsProxy: 'JLS 代理', jlsSni: 'JLS SNI', jlsSniHint: 'JLS SNI 主机名', jlsUpstreamAddr: 'JLS 上游地址', jlsUsers: 'JLS 用户', kcpTunConn: 'KCP 连接数', kcpTunCrypt: 'KCP 加密', kcpTunKey: 'KCP 密钥', kcpTunMode: 'KCP 模式', kcpTunNocomp: 'KCP 禁用压缩', kcpTunRcvwnd: 'KCP 接收窗口', kcpTunSndwnd: 'KCP 发送窗口', maxIdleTime: '最大空闲时间', maxUdpRelayPacketSize: '最大 UDP 中继包', mekyaHint: 'Mekya 相关配置', mekyaKcpSection: 'Mekya KCP', mekyaMaxSimultaneous: '最大并发', mekyaMaxSimultaneousHint: '最大同时连接数', mekyaMaxWriteDuration: '最大写入时长', mekyaMaxWriteDurationHint: '写入超时', mekyaMaxWriteSize: '最大写入大小', mekyaMaxWriteSizeHint: '单次写入上限', mekyaPacketBuffer: '包缓冲', mekyaPacketBufferHint: '数据包缓冲大小', mkcpCongestion: 'mKCP 拥塞控制', mkcpDownlink: 'mKCP 下行', mkcpHeader: 'mKCP 头类型', mkcpHint: 'mKCP 传输', mkcpReadBuffer: 'mKCP 读缓冲', mkcpSeed: 'mKCP Seed', mkcpUplink: 'mKCP 上行', mkcpWriteBuffer: 'mKCP 写缓冲', muxBrutal: 'Mux Brutal', muxBrutalDown: 'Brutal 下行', muxBrutalUp: 'Brutal 上行', muxMaxConnections: 'Mux 最大连接', muxMaxStreams: 'Mux 最大流', muxMinStreams: 'Mux 最小流', muxOnlyTcp: '仅 TCP Mux', muxPadding: 'Mux 填充', muxProtocol: 'Mux 协议', muxStatistic: 'Mux 统计', network: '传输网络', obfs: '混淆', obfsMaxPacketSize: '混淆最大包', obfsMinPacketSize: '混淆最小包', obfsOptsHost: '混淆 Host', obfsOptsMode: '混淆模式', obfsPassword: '混淆密码', paddingMax: '填充最大', paddingMin: '填充最小', paddingScheme: '填充方案', psk: 'PSK', quicVersions: 'QUIC 版本', rateLimit: '速率限制', rateLimitHint: '如 10m', realityExclusiveHint: 'Reality 与 TLS 证书互斥', realityShortId: 'Reality Short ID', realmId: 'Realm ID', realmProxy: 'Realm 代理', realmServerUrl: 'Realm 服务地址', realmSkipCert: '跳过证书校验', realmStun: 'STUN', realmToken: 'Realm Token', resTlsDest: 'ResTLS 目标', resTlsHint: 'ResTLS 配置', resTlsMinRecordLen: '最小记录长度', resTlsPassword: 'ResTLS 密码', resTlsProxy: 'ResTLS 代理', resTlsScript: 'ResTLS 脚本', sectionJLS: 'JLS', sectionJlsUpstream: 'JLS 上游', sectionKcpTun: 'KCP Tun', sectionMekya: 'Mekya', sectionMkcp: 'mKCP', sectionMux: 'Mux', sectionRealm: 'Realm', sectionResTLS: 'ResTLS', sectionShadowTLS: 'ShadowTLS', sectionSimpleObfs: 'Simple Obfs', sectionXHTTP: 'XHTTP', shadowTlsHandshakeDest: '握手目标', shadowTlsHandshakeProxy: '握手代理', shadowTlsHint: 'ShadowTLS 配置', shadowTlsPassword: 'ShadowTLS 密码', shadowTlsPasswordHint: '版本 2/3 密码', shadowTlsUsers: 'ShadowTLS 用户', shadowTlsVersion: 'ShadowTLS 版本', simpleObfsMode: 'Simple Obfs 模式', snellVersion: 'Snell 版本', ssOptionMethod: 'SS 加密方式', ssOptionPassword: 'SS 密码', sudokuKey: 'Sudoku Key', customTable: '自定义表', customTables: '自定义表列表', sudokuFallback: '回落', sectionHttpmask: 'HTTPMask', httpmaskDisable: '禁用 HTTP 伪装', httpmaskMode: 'HTTP 伪装模式', httpmaskPathRoot: 'HTTP 路径前缀', tableType: '表类型', tlsPairHint: '证书与私钥需成对填写', token: 'Token', tokenHint: '认证 Token', tokenPlaceholder: '输入 Token', trafficPattern: '流量模式', userHintMandatory: '至少一个用户', wizardBasic: '基础信息', wizardConfig: '协议配置', wizardConfigHint: '填写协议相关字段(TLS / Reality / 用户等)', wizardReview: '确认创建', wsPath: 'WebSocket 路径', wsPathHint: '如 /ws', xhttpHint: 'XHTTP 传输', xhttpHost: 'XHTTP Host', xhttpMode: 'XHTTP 模式', xhttpPath: 'XHTTP 路径', zeroRtt: '0-RTT'},
encryptionHint: '客户端 VLESS Encryption:与 decryption 成对,取 generate 输出的 encryption 一侧,勿直接复制 decryption', decryptionHint: '服务端 VLESS Encryption:由 mihomo generate vless-x25519 / vless-mlkem768 生成,填 decryption 一侧', echKey: 'ECH Key', enablePureDownlink: '纯下行', flow: '流控', flowHint: '如 xtls-rprx-vision', grpcHint: 'gRPC 传输', grpcServiceName: 'gRPC Service Name', grpcUserAgent: 'gRPC User-Agent', grpcUserAgentHint: 'gRPC 客户端 User-Agent 字符串(面板侧元数据;写入客户端 grpc-opts)。', pingInterval: 'Ping 间隔 (ms)', pingIntervalHint: 'gRPC keepalive Ping 间隔(面板侧元数据;写入客户端 grpc-opts)。', maxConnections: '最大连接数', maxConnectionsHint: 'gRPC 最大并发连接数(面板侧元数据)。', minStreams: '最小流数', minStreamsHint: 'gRPC 最小并发流数(面板侧元数据)。', maxStreams: '最大流数', maxStreamsHint: 'gRPC 最大并发流数(面板侧元数据)。', handshakeTimeout: '握手超时', jlsDest: 'JLS 目标', jlsHint: 'Joliz 相关配置', jlsProxy: 'JLS 代理', jlsSni: 'JLS SNI', jlsSniHint: 'JLS SNI 主机名', jlsUpstreamAddr: 'JLS 上游地址', jlsUsers: 'JLS 用户', kcpTunConn: 'KCP 连接数', kcpTunCrypt: 'KCP 加密', kcpTunKey: 'KCP 密钥', kcpTunMode: 'KCP 模式', kcpTunNocomp: 'KCP 禁用压缩', kcpTunRcvwnd: 'KCP 接收窗口', kcpTunSndwnd: 'KCP 发送窗口', maxIdleTime: '最大空闲时间', maxUdpRelayPacketSize: '最大 UDP 中继包', mekyaHint: 'Mekya 相关配置', mekyaKcpSection: 'Mekya KCP', mekyaMaxSimultaneous: '最大并发', mekyaMaxSimultaneousHint: '最大同时连接数', mekyaMaxWriteDuration: '最大写入时长', mekyaMaxWriteDurationHint: '写入超时', mekyaMaxWriteSize: '最大写入大小', mekyaMaxWriteSizeHint: '单次写入上限', mekyaPacketBuffer: '包缓冲', mekyaPacketBufferHint: '数据包缓冲大小', mekyaPollingInterval: '轮询间隔 (ms)', mekyaH2PoolSize: 'H2 连接池大小', mkcpCongestion: 'mKCP 拥塞控制', mkcpDownlink: 'mKCP 下行', mkcpHeader: 'mKCP 头类型', mkcpHint: 'mKCP 传输', mkcpReadBuffer: 'mKCP 读缓冲', mkcpSeed: 'mKCP Seed', mkcpUplink: 'mKCP 上行', mkcpWriteBuffer: 'mKCP 写缓冲', muxBrutal: 'Mux Brutal', muxBrutalDown: 'Brutal 下行', muxBrutalUp: 'Brutal 上行', muxMaxConnections: 'Mux 最大连接', muxMaxStreams: 'Mux 最大流', muxMinStreams: 'Mux 最小流', muxOnlyTcp: '仅 TCP Mux', muxPadding: 'Mux 填充', muxProtocol: 'Mux 协议', muxStatistic: 'Mux 统计', network: '传输网络', obfs: '混淆', obfsMaxPacketSize: '混淆最大包', obfsMinPacketSize: '混淆最小包', obfsOptsHost: '混淆 Host', obfsOptsMode: '混淆模式', obfsPassword: '混淆密码', paddingMax: '填充最大', paddingMin: '填充最小', paddingScheme: '填充方案', psk: 'PSK', quicVersions: 'QUIC 版本', rateLimit: '速率限制', rateLimitHint: '如 10m', realityExclusiveHint: 'Reality 与 TLS 证书互斥', realityShortId: 'Reality Short ID', realmId: 'Realm ID', realmProxy: 'Realm 代理', realmServerUrl: 'Realm 服务地址', realmSkipCert: '跳过证书校验', realmStun: 'STUN', realmToken: 'Realm Token', resTlsDest: 'ResTLS 目标', resTlsHint: 'ResTLS 配置', resTlsMinRecordLen: '最小记录长度', resTlsPassword: 'ResTLS 密码', resTlsProxy: 'ResTLS 代理', resTlsScript: 'ResTLS 脚本', sectionJLS: 'JLS', sectionJlsUpstream: 'JLS 上游', sectionKcpTun: 'KCP Tun', sectionMekya: 'Mekya', sectionMkcp: 'mKCP', sectionMux: 'Mux', sectionRealm: 'Realm', sectionResTLS: 'ResTLS', sectionShadowTLS: 'ShadowTLS', sectionSimpleObfs: 'Simple Obfs', sectionXHTTP: 'XHTTP', shadowTlsHandshakeDest: '握手目标', shadowTlsHandshakeProxy: '握手代理', shadowTlsHint: 'ShadowTLS 配置', shadowTlsPassword: 'ShadowTLS 密码', shadowTlsPasswordHint: '版本 2/3 密码', shadowTlsUsers: 'ShadowTLS 用户', shadowTlsVersion: 'ShadowTLS 版本', simpleObfsMode: 'Simple Obfs 模式', snellVersion: 'Snell 版本', ssOptionMethod: 'SS 加密方式', ssOptionPassword: 'SS 密码', sudokuKey: 'Sudoku Key', customTable: '自定义表', customTables: '自定义表列表', sudokuFallback: '回落', sectionHttpmask: 'HTTPMask', httpmaskDisable: '禁用 HTTP 伪装', httpmaskMode: 'HTTP 伪装模式', httpmaskPathRoot: 'HTTP 路径前缀', tableType: '表类型', tlsPairHint: '证书与私钥需成对填写', token: 'Token', tokenHint: '认证 Token', tokenPlaceholder: '输入 Token', trafficPattern: '流量模式', userHintMandatory: '至少一个用户', wizardBasic: '基础信息', wizardConfig: '协议配置', wizardConfigHint: '填写协议相关字段(TLS / Reality / 用户等)', wizardReview: '确认创建', wsPath: 'WebSocket 路径', wsPathHint: '如 /ws', xhttpHint: 'XHTTP 传输', xhttpHost: 'XHTTP Host', xhttpMode: 'XHTTP 模式', xhttpPath: 'XHTTP 路径', zeroRtt: '0-RTT'},
core: { title: '核心管理', status: '核心状态', running: '运行中', stoppedStatus: '已停止', version: '版本', pid: '进程 ID', uptime: '运行时间', start: '启动', stop: '停止', restart: '重启', started: '已启动', stopped: '已停止', restarted: '已重启' , operationFailed: '操作失败', unavailable: '核心不可用'},
logs: { title: '运行日志', empty: '暂无日志', level: '级别', timestamp: '时间', payload: '内容', autoRefresh: '自动刷新', clear: '清空' },
config: { title: '配置引擎', subtitle: '可视化管理 Mihomo 配置', visual: '可视化配置', yaml: 'YAML 配置', proxies: '代理配置', yamlPreview: 'YAML 预览', addProxy: '添加代理', editProxy: '编辑代理', deleteProxy: '删除代理', deleteConfirm: '确定要删除此代理吗?', generateSuccess: '配置生成成功', validateSuccess: '配置验证通过', validateFailed: '配置验证失败', proxyName: '代理名称', proxyType: '代理类型', proxyServer: '代理服务器', proxyPort: '代理端口', proxyPassword: '代理密码', proxyUUID: '代理 UUID' , generate: '生成配置', validate: '校验配置'},