From 47cf21f4984663ea41421bbef1984b76342ea05b Mon Sep 17 00:00:00 2001 From: Gerhard Tan Date: Sun, 3 Mar 2024 17:04:38 +0800 Subject: [PATCH 1/6] Make TOML and INI formats switchable in a single configuration --- go.mod | 2 +- go.sum | 4 +- i18n/catalog.go | 821 ++++++++++++------------ i18n/locales/en-US/messages.gotext.json | 38 +- i18n/locales/es-ES/messages.gotext.json | 32 +- i18n/locales/ja-JP/messages.gotext.json | 32 +- i18n/locales/ko-KR/messages.gotext.json | 32 +- i18n/locales/zh-CN/messages.gotext.json | 32 +- i18n/locales/zh-TW/messages.gotext.json | 32 +- pkg/config/client.go | 59 +- pkg/config/conf.go | 2 +- pkg/config/conversion.go | 428 +++++++++++- ui/conf.go | 2 +- ui/editclient.go | 72 ++- ui/editproxy.go | 2 +- ui/model.go | 5 +- ui/proxyview.go | 3 +- 17 files changed, 1043 insertions(+), 555 deletions(-) diff --git a/go.mod b/go.mod index 86235b50..1d326483 100644 --- a/go.mod +++ b/go.mod @@ -64,4 +64,4 @@ require ( sigs.k8s.io/yaml v1.3.0 // indirect ) -replace github.com/lxn/walk => github.com/koho/frpmgr v0.0.0-20240226182702-de6a27e2c5f6 +replace github.com/lxn/walk => github.com/koho/frpmgr v0.0.0-20240228174759-ec59bb05f3d7 diff --git a/go.sum b/go.sum index 9d1166c2..ee5ba967 100644 --- a/go.sum +++ b/go.sum @@ -75,8 +75,8 @@ github.com/klauspost/cpuid/v2 v2.0.6 h1:dQ5ueTiftKxp0gyjKSx5+8BtPWkyQbd95m8Gys/R github.com/klauspost/cpuid/v2 v2.0.6/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= github.com/klauspost/reedsolomon v1.9.15 h1:g2erWKD2M6rgnPf89fCji6jNlhMKMdXcuNHMW1SYCIo= github.com/klauspost/reedsolomon v1.9.15/go.mod h1:eqPAcE7xar5CIzcdfwydOEdcmchAKAP/qs14y4GCBOk= -github.com/koho/frpmgr v0.0.0-20240226182702-de6a27e2c5f6 h1:KYUbVjfTDAQtLFQ3P/NC2kMiAkFS6wOSGymb8s2tqRQ= -github.com/koho/frpmgr v0.0.0-20240226182702-de6a27e2c5f6/go.mod h1:CdksCbC3x4Swi/ePNXCeg08K1i3XdIVdy3o7elo92k8= +github.com/koho/frpmgr v0.0.0-20240228174759-ec59bb05f3d7 h1:GbWLEZJc4BL9/cePQ2Z8hnYAEEbeeZ4GBfhhinNLy54= +github.com/koho/frpmgr v0.0.0-20240228174759-ec59bb05f3d7/go.mod h1:CdksCbC3x4Swi/ePNXCeg08K1i3XdIVdy3o7elo92k8= github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0= github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= diff --git a/i18n/catalog.go b/i18n/catalog.go index 004bf630..8c0dedbc 100644 --- a/i18n/catalog.go +++ b/i18n/catalog.go @@ -108,8 +108,8 @@ var messageKeyToIndex = map[string]int{ "Delete proxy \"%s\"": 235, "Dial Timeout": 101, "Direct Edit": 231, - "Disable": 239, - "Disable auto-start at boot": 120, + "Disable": 229, + "Disable auto-start at boot": 119, "Disable custom first byte": 114, "Disable proxy \"%s\"": 237, "Domains": 232, @@ -118,11 +118,11 @@ var messageKeyToIndex = map[string]int{ "Edit": 35, "Edit Client - %s": 56, "Edit Proxy - %s": 128, - "Enable": 229, + "Enable": 239, "Encryption": 155, "Enter Administration Password": 249, "Enter Password": 247, - "Exit after login failure": 119, + "Exit after login failure": 118, "Experimental Features": 122, "Export All Configs to ZIP": 47, "External Address": 188, @@ -177,7 +177,6 @@ var messageKeyToIndex = map[string]int{ "Max Streams": 104, "Metadata": 121, "Multiplexer": 147, - "Mux Keepalive": 117, "NAT Discovery": 45, "NAT Type": 186, "Name": 25, @@ -257,7 +256,7 @@ var messageKeyToIndex = map[string]int{ "Service": 201, "Set Defaults": 219, "Show in Folder": 37, - "Source Address": 118, + "Source Address": 116, "Start": 200, "Starting": 195, "Status": 197, @@ -267,7 +266,7 @@ var messageKeyToIndex = map[string]int{ "Stopping": 196, "Strip Prefix": 172, "Subdomain": 143, - "TCP Mux": 116, + "TCP Mux": 117, "The config \"%s\" already removed.": 34, "The config name \"%s\" already exists.": 126, "The current display language is": 214, @@ -277,23 +276,24 @@ var messageKeyToIndex = map[string]int{ "The text does not match the required pattern.": 254, "There are currently no updates available.": 22, "This feature only supports text in INI or TOML format.": 234, - "Timeout": 100, - "Times/Hour": 158, - "Token": 65, - "Token Endpoint": 69, - "Trusted CA": 112, - "Type": 130, - "UDP Packet Size": 96, - "Unix Path": 168, - "Unknown": 192, - "Use master password": 211, - "Use server SVCB records": 124, - "User": 60, - "Value": 26, - "Version: %s": 0, - "Visitor": 133, - "Work Conns": 73, - "Yes": 189, + "Timeout": 100, + "Times/Hour": 158, + "Token": 65, + "Token Endpoint": 69, + "Trusted CA": 112, + "Type": 130, + "UDP Packet Size": 96, + "Unix Path": 168, + "Unknown": 192, + "Use legacy format config file": 120, + "Use master password": 211, + "Use server SVCB records": 124, + "User": 60, + "Value": 26, + "Version: %s": 0, + "Visitor": 133, + "Work Conns": 73, + "Yes": 189, "You can set a password to restrict access to this program.\nYou will be asked to enter it the next time you use this program.": 210, "You must enter an administration password to operate the %s.": 248, "You must restart program to apply the modification.": 215, @@ -337,50 +337,50 @@ var en_USIndex = []uint32{ // 259 elements 0x000006e6, 0x000006f2, 0x000006f5, 0x000006f9, 0x00000703, 0x0000070f, 0x00000727, 0x00000737, 0x00000753, 0x0000075e, 0x00000775, 0x0000078f, - 0x00000798, 0x000007a0, 0x000007ae, 0x000007bd, - 0x000007d6, 0x000007f1, 0x000007fa, 0x00000810, - 0x00000852, 0x0000086a, 0x00000880, 0x000008a8, + 0x00000798, 0x000007a7, 0x000007af, 0x000007c8, + 0x000007e3, 0x00000801, 0x0000080a, 0x00000820, + 0x00000862, 0x0000087a, 0x00000890, 0x000008b8, // Entry 80 - 9F - 0x000008b2, 0x000008c5, 0x000008cc, 0x000008d1, - 0x000008d6, 0x000008dd, 0x000008e5, 0x000008f0, - 0x000008fe, 0x00000909, 0x00000915, 0x00000921, - 0x0000092e, 0x00000938, 0x00000944, 0x00000950, - 0x0000095a, 0x00000969, 0x00000973, 0x00000983, - 0x0000098f, 0x0000099a, 0x000009a1, 0x000009ab, - 0x000009ba, 0x000009bf, 0x000009c7, 0x000009d3, - 0x000009de, 0x000009ea, 0x000009f6, 0x00000a01, + 0x000008c2, 0x000008d5, 0x000008dc, 0x000008e1, + 0x000008e6, 0x000008ed, 0x000008f5, 0x00000900, + 0x0000090e, 0x00000919, 0x00000925, 0x00000931, + 0x0000093e, 0x00000948, 0x00000954, 0x00000960, + 0x0000096a, 0x00000979, 0x00000983, 0x00000993, + 0x0000099f, 0x000009aa, 0x000009b1, 0x000009bb, + 0x000009ca, 0x000009cf, 0x000009d7, 0x000009e3, + 0x000009ee, 0x000009fa, 0x00000a06, 0x00000a11, // Entry A0 - BF - 0x00000a10, 0x00000a19, 0x00000a2a, 0x00000a2d, - 0x00000a37, 0x00000a45, 0x00000a52, 0x00000a59, - 0x00000a65, 0x00000a6f, 0x00000a80, 0x00000a8b, - 0x00000ab2, 0x00000abf, 0x00000acc, 0x00000ad2, - 0x00000adc, 0x00000ae9, 0x00000af4, 0x00000b02, - 0x00000b10, 0x00000b1f, 0x00000b34, 0x00000b5b, - 0x00000b6b, 0x00000b72, 0x00000b77, 0x00000b80, - 0x00000b89, 0x00000b9a, 0x00000b9e, 0x00000ba1, + 0x00000a20, 0x00000a29, 0x00000a3a, 0x00000a3d, + 0x00000a47, 0x00000a55, 0x00000a62, 0x00000a69, + 0x00000a75, 0x00000a7f, 0x00000a90, 0x00000a9b, + 0x00000ac2, 0x00000acf, 0x00000adc, 0x00000ae2, + 0x00000aec, 0x00000af9, 0x00000b04, 0x00000b12, + 0x00000b20, 0x00000b2f, 0x00000b44, 0x00000b6b, + 0x00000b7b, 0x00000b82, 0x00000b87, 0x00000b90, + 0x00000b99, 0x00000baa, 0x00000bae, 0x00000bb1, // Entry C0 - DF - 0x00000bb0, 0x00000bb8, 0x00000bc0, 0x00000bc8, - 0x00000bd1, 0x00000bda, 0x00000be1, 0x00000bf0, - 0x00000bf5, 0x00000bfb, 0x00000c03, 0x00000c17, - 0x00000c4b, 0x00000c50, 0x00000c60, 0x00000c65, - 0x00000c6f, 0x00000c7b, 0x00000c8b, 0x00000d08, - 0x00000d1c, 0x00000d2c, 0x00000d36, 0x00000d56, - 0x00000d8a, 0x00000d9a, 0x00000da3, 0x00000e1a, - 0x00000e27, 0x00000e39, 0x00000e4d, 0x00000e5f, + 0x00000bc0, 0x00000bc8, 0x00000bd0, 0x00000bd8, + 0x00000be1, 0x00000bea, 0x00000bf1, 0x00000c00, + 0x00000c05, 0x00000c0b, 0x00000c13, 0x00000c27, + 0x00000c5b, 0x00000c60, 0x00000c70, 0x00000c75, + 0x00000c7f, 0x00000c8b, 0x00000c9b, 0x00000d18, + 0x00000d2c, 0x00000d3c, 0x00000d46, 0x00000d66, + 0x00000d9a, 0x00000daa, 0x00000db3, 0x00000e2a, + 0x00000e37, 0x00000e49, 0x00000e5d, 0x00000e6f, // Entry E0 - FF - 0x00000e70, 0x00000e7a, 0x00000e88, 0x00000e92, - 0x00000ea1, 0x00000eb2, 0x00000eb9, 0x00000ec5, - 0x00000ed1, 0x00000ed9, 0x00000eed, 0x00000f24, - 0x00000f39, 0x00000f6e, 0x00000f84, 0x00000fba, - 0x00000fc2, 0x00000fd5, 0x00000fe1, 0x0000100c, - 0x00001021, 0x00001027, 0x0000104a, 0x00001053, - 0x00001062, 0x000010a2, 0x000010c0, 0x000010ee, - 0x000010fc, 0x00001129, 0x00001154, 0x00001182, + 0x00000e80, 0x00000e8a, 0x00000e98, 0x00000ea2, + 0x00000eb1, 0x00000ec2, 0x00000eca, 0x00000ed6, + 0x00000ee2, 0x00000eea, 0x00000efe, 0x00000f35, + 0x00000f4a, 0x00000f7f, 0x00000f95, 0x00000fcb, + 0x00000fd2, 0x00000fe5, 0x00000ff1, 0x0000101c, + 0x00001031, 0x00001037, 0x0000105a, 0x00001063, + 0x00001072, 0x000010b2, 0x000010d0, 0x000010fe, + 0x0000110c, 0x00001139, 0x00001164, 0x00001192, // Entry 100 - 11F - 0x00001195, 0x000011c0, 0x000011d9, + 0x000011a5, 0x000011d0, 0x000011e9, } // Size: 1060 bytes -const en_USData string = "" + // Size: 4569 bytes +const en_USData string = "" + // Size: 4585 bytes "\x02Version: %[1]s\x02FRP version: %[1]s\x02Built on: %[1]s\x02All Files" + "\x02Configuration Files\x02Certificate Files\x02Key Files\x02Log Files" + "\x02Number out of allowed range\x02Please enter a number greater than %[" + @@ -413,50 +413,50 @@ const en_USData string = "" + // Size: 4569 bytes "\x02Keepalive\x02Idle Timeout\x02Max Streams\x02On\x02Off\x02Host Name" + "\x02Certificate\x02Select Certificate File\x02Certificate Key\x02Select " + "Certificate Key File\x02Trusted CA\x02Select Trusted CA File\x02Disable " + - "custom first byte\x02Advanced\x02TCP Mux\x02Mux Keepalive\x02Source Addr" + - "ess\x02Exit after login failure\x02Disable auto-start at boot\x02Metadat" + - "a\x02Experimental Features\x02* The following features may affect the st" + - "ability of the service.\x02Use server SVCB records\x02Config already exi" + - "sts\x02The config name \x22%[1]s\x22 already exists.\x02New Proxy\x02Edi" + - "t Proxy - %[1]s\x02Random\x02Type\x02Role\x02Server\x02Visitor\x02Secret" + - " Key\x02Local Address\x02Local Port\x02Remote Port\x02Allow Users\x02Bin" + - "d Address\x02Bind Port\x02Server Name\x02Server User\x02Subdomain\x02Cus" + - "tom Domains\x02Locations\x02Request headers\x02Multiplexer\x02Route User" + - "\x02Client\x02Bandwidth\x02Proxy Protocol\x02auto\x02default\x02Keep Tun" + - "nel\x02Encryption\x02Compression\x02Retry Count\x02Times/Hour\x02Retry I" + - "nterval\x02Fallback\x02Fallback Timeout\x02ms\x02HTTP User\x02HTTP Passw" + - "ord\x02Host Rewrite\x02Plugin\x02Plugin Name\x02Unix Path\x02Select Unix" + - " Path\x02Local Path\x02Select a folder for directory listing.\x02Strip P" + - "refix\x02Load Balance\x02Group\x02Group Key\x02Health Check\x02Check Typ" + - "e\x02Check Timeout\x02Failure Count\x02Check Interval\x02Proxy already e" + - "xists\x02The proxy name \x22%[1]s\x22 already exists.\x02Open Log Folder" + - "\x02Latest\x02Item\x02NAT Type\x02Behavior\x02External Address\x02Yes" + - "\x02No\x02Public Network\x02Unknown\x02Running\x02Stopped\x02Starting" + - "\x02Stopping\x02Status\x02Remote Address\x02Copy\x02Start\x02Service\x02" + - "Stop config \x22%[1]s\x22\x02Are you sure you would like to stop config " + - "\x22%[1]s\x22?\x02Stop\x02Local Directory\x02Port\x02Open Port\x02Prefer" + - "ences\x02Master password\x02You can set a password to restrict access to" + - " this program.\x0aYou will be asked to enter it the next time you use th" + - "is program.\x02Use master password\x02Change Password\x02Languages\x02Th" + - "e current display language is\x02You must restart program to apply the m" + - "odification.\x02Select language\x02Defaults\x02Define the default value " + - "when creating a new configuration.\x0aThe value here will not affect the" + - " existing configuration.\x02Set Defaults\x02Password removed.\x02New mas" + - "ter password\x02Re-enter password\x02Password is set.\x02Log Level\x02Lo" + - "g retention\x02Quick Add\x02Remote Desktop\x02HTTP File Server\x02Enable" + - "\x02Open Config\x02Direct Edit\x02Domains\x02Copy Access Address\x02This" + - " feature only supports text in INI or TOML format.\x02Delete proxy \x22%" + - "[1]s\x22\x02Are you sure you would like to delete proxy \x22%[1]s\x22?" + - "\x02Disable proxy \x22%[1]s\x22\x02Are you sure you would like to disabl" + - "e proxy \x22%[1]s\x22?\x02Disable\x02Passive Port Range\x02FRP Manager" + - "\x02* Support batch import, one link per line.\x02Rename automatically" + - "\x02Ready\x02Please enter the correct URL list.\x02Download\x02Enter Pas" + - "sword\x02You must enter an administration password to operate the %[1]s." + - "\x02Enter Administration Password\x02The password is incorrect. Re-enter" + - " password.\x02Invalid Input\x02Please enter a number from %.[1]f to %.[2" + - "]f.\x02Please enter a number from %[1]s to %[2]s.\x02The text does not m" + - "atch the required pattern.\x02Selection Required\x02Please select one of" + - " the provided options.\x02A selection is required." + "custom first byte\x02Advanced\x02Source Address\x02TCP Mux\x02Exit after" + + " login failure\x02Disable auto-start at boot\x02Use legacy format config" + + " file\x02Metadata\x02Experimental Features\x02* The following features m" + + "ay affect the stability of the service.\x02Use server SVCB records\x02Co" + + "nfig already exists\x02The config name \x22%[1]s\x22 already exists.\x02" + + "New Proxy\x02Edit Proxy - %[1]s\x02Random\x02Type\x02Role\x02Server\x02V" + + "isitor\x02Secret Key\x02Local Address\x02Local Port\x02Remote Port\x02Al" + + "low Users\x02Bind Address\x02Bind Port\x02Server Name\x02Server User\x02" + + "Subdomain\x02Custom Domains\x02Locations\x02Request headers\x02Multiplex" + + "er\x02Route User\x02Client\x02Bandwidth\x02Proxy Protocol\x02auto\x02def" + + "ault\x02Keep Tunnel\x02Encryption\x02Compression\x02Retry Count\x02Times" + + "/Hour\x02Retry Interval\x02Fallback\x02Fallback Timeout\x02ms\x02HTTP Us" + + "er\x02HTTP Password\x02Host Rewrite\x02Plugin\x02Plugin Name\x02Unix Pat" + + "h\x02Select Unix Path\x02Local Path\x02Select a folder for directory lis" + + "ting.\x02Strip Prefix\x02Load Balance\x02Group\x02Group Key\x02Health Ch" + + "eck\x02Check Type\x02Check Timeout\x02Failure Count\x02Check Interval" + + "\x02Proxy already exists\x02The proxy name \x22%[1]s\x22 already exists." + + "\x02Open Log Folder\x02Latest\x02Item\x02NAT Type\x02Behavior\x02Externa" + + "l Address\x02Yes\x02No\x02Public Network\x02Unknown\x02Running\x02Stoppe" + + "d\x02Starting\x02Stopping\x02Status\x02Remote Address\x02Copy\x02Start" + + "\x02Service\x02Stop config \x22%[1]s\x22\x02Are you sure you would like " + + "to stop config \x22%[1]s\x22?\x02Stop\x02Local Directory\x02Port\x02Open" + + " Port\x02Preferences\x02Master password\x02You can set a password to res" + + "trict access to this program.\x0aYou will be asked to enter it the next " + + "time you use this program.\x02Use master password\x02Change Password\x02" + + "Languages\x02The current display language is\x02You must restart program" + + " to apply the modification.\x02Select language\x02Defaults\x02Define the" + + " default value when creating a new configuration.\x0aThe value here will" + + " not affect the existing configuration.\x02Set Defaults\x02Password remo" + + "ved.\x02New master password\x02Re-enter password\x02Password is set.\x02" + + "Log Level\x02Log retention\x02Quick Add\x02Remote Desktop\x02HTTP File S" + + "erver\x02Disable\x02Open Config\x02Direct Edit\x02Domains\x02Copy Access" + + " Address\x02This feature only supports text in INI or TOML format.\x02De" + + "lete proxy \x22%[1]s\x22\x02Are you sure you would like to delete proxy " + + "\x22%[1]s\x22?\x02Disable proxy \x22%[1]s\x22\x02Are you sure you would " + + "like to disable proxy \x22%[1]s\x22?\x02Enable\x02Passive Port Range\x02" + + "FRP Manager\x02* Support batch import, one link per line.\x02Rename auto" + + "matically\x02Ready\x02Please enter the correct URL list.\x02Download\x02" + + "Enter Password\x02You must enter an administration password to operate t" + + "he %[1]s.\x02Enter Administration Password\x02The password is incorrect." + + " Re-enter password.\x02Invalid Input\x02Please enter a number from %.[1]" + + "f to %.[2]f.\x02Please enter a number from %[1]s to %[2]s.\x02The text d" + + "oes not match the required pattern.\x02Selection Required\x02Please sele" + + "ct one of the provided options.\x02A selection is required." var es_ESIndex = []uint32{ // 259 elements // Entry 0 - 1F @@ -492,50 +492,50 @@ var es_ESIndex = []uint32{ // 259 elements 0x000008ed, 0x00000901, 0x0000090a, 0x00000912, 0x00000927, 0x00000933, 0x00000956, 0x0000096b, 0x00000997, 0x000009a7, 0x000009cb, 0x000009f0, - 0x000009f9, 0x00000a01, 0x00000a0f, 0x00000a27, - 0x00000a55, 0x00000a82, 0x00000a8c, 0x00000aac, - 0x00000afa, 0x00000b1b, 0x00000b37, 0x00000b66, + 0x000009f9, 0x00000a11, 0x00000a19, 0x00000a47, + 0x00000a74, 0x00000aa7, 0x00000ab1, 0x00000ad1, + 0x00000b1f, 0x00000b40, 0x00000b5c, 0x00000b8b, // Entry 80 - 9F - 0x00000b72, 0x00000b87, 0x00000b91, 0x00000b96, - 0x00000b9b, 0x00000ba4, 0x00000bae, 0x00000bbc, - 0x00000bcd, 0x00000bda, 0x00000be8, 0x00000bfa, - 0x00000c0f, 0x00000c20, 0x00000c34, 0x00000c49, - 0x00000c54, 0x00000c6c, 0x00000c75, 0x00000c8b, - 0x00000c97, 0x00000ca7, 0x00000caf, 0x00000cbb, - 0x00000ccb, 0x00000cd0, 0x00000cdc, 0x00000cec, - 0x00000cf4, 0x00000d00, 0x00000d16, 0x00000d21, + 0x00000b97, 0x00000bac, 0x00000bb6, 0x00000bbb, + 0x00000bc0, 0x00000bc9, 0x00000bd3, 0x00000be1, + 0x00000bf2, 0x00000bff, 0x00000c0d, 0x00000c1f, + 0x00000c34, 0x00000c45, 0x00000c59, 0x00000c6e, + 0x00000c79, 0x00000c91, 0x00000c9a, 0x00000cb0, + 0x00000cbc, 0x00000ccc, 0x00000cd4, 0x00000ce0, + 0x00000cf0, 0x00000cf5, 0x00000d01, 0x00000d11, + 0x00000d19, 0x00000d25, 0x00000d3b, 0x00000d46, // Entry A0 - BF - 0x00000d38, 0x00000d41, 0x00000d59, 0x00000d65, - 0x00000d72, 0x00000d83, 0x00000d97, 0x00000da0, - 0x00000da7, 0x00000db1, 0x00000dcc, 0x00000dd7, - 0x00000e0c, 0x00000e1c, 0x00000e30, 0x00000e36, - 0x00000e45, 0x00000e56, 0x00000e5b, 0x00000e6f, - 0x00000e82, 0x00000e8c, 0x00000e9f, 0x00000ec5, - 0x00000ed4, 0x00000edc, 0x00000ee2, 0x00000eee, - 0x00000efd, 0x00000f10, 0x00000f14, 0x00000f17, + 0x00000d5d, 0x00000d66, 0x00000d7e, 0x00000d8a, + 0x00000d97, 0x00000da8, 0x00000dbc, 0x00000dc5, + 0x00000dcc, 0x00000dd6, 0x00000df1, 0x00000dfc, + 0x00000e31, 0x00000e41, 0x00000e55, 0x00000e5b, + 0x00000e6a, 0x00000e7b, 0x00000e80, 0x00000e94, + 0x00000ea7, 0x00000eb1, 0x00000ec4, 0x00000eea, + 0x00000ef9, 0x00000f01, 0x00000f07, 0x00000f13, + 0x00000f22, 0x00000f35, 0x00000f39, 0x00000f3c, // Entry C0 - DF - 0x00000f24, 0x00000f30, 0x00000f37, 0x00000f40, - 0x00000f4b, 0x00000f52, 0x00000f59, 0x00000f6b, - 0x00000f72, 0x00000f7b, 0x00000f84, 0x00000fa3, - 0x00000fe2, 0x00000fed, 0x00000ffe, 0x00001005, - 0x00001014, 0x00001021, 0x00001035, 0x000010c5, - 0x000010de, 0x000010f5, 0x000010fd, 0x00001123, - 0x0000115d, 0x00001172, 0x00001182, 0x000011fd, - 0x0000120c, 0x00001223, 0x0000123d, 0x0000125d, + 0x00000f49, 0x00000f55, 0x00000f5c, 0x00000f65, + 0x00000f70, 0x00000f77, 0x00000f7e, 0x00000f90, + 0x00000f97, 0x00000fa0, 0x00000fa9, 0x00000fc8, + 0x00001007, 0x00001012, 0x00001023, 0x0000102a, + 0x00001039, 0x00001046, 0x0000105a, 0x000010ea, + 0x00001103, 0x0000111a, 0x00001122, 0x00001148, + 0x00001182, 0x00001197, 0x000011a7, 0x00001222, + 0x00001231, 0x00001248, 0x00001262, 0x00001282, // Entry E0 - FF - 0x0000127f, 0x00001291, 0x000012a9, 0x000012b9, - 0x000012cb, 0x000012e5, 0x000012ef, 0x00001304, - 0x00001315, 0x0000131e, 0x0000133a, 0x00001371, - 0x00001388, 0x000013bf, 0x000013da, 0x00001413, - 0x00001420, 0x00001438, 0x0000144d, 0x00001484, - 0x0000149f, 0x000014a5, 0x000014ca, 0x000014d4, - 0x000014ee, 0x00001532, 0x0000155c, 0x0000159b, - 0x000015ac, 0x000015d3, 0x000015f8, 0x00001627, + 0x000012a4, 0x000012b6, 0x000012ce, 0x000012de, + 0x000012f0, 0x0000130a, 0x00001317, 0x0000132c, + 0x0000133d, 0x00001346, 0x00001362, 0x00001399, + 0x000013b0, 0x000013e7, 0x00001402, 0x0000143b, + 0x00001445, 0x0000145d, 0x00001472, 0x000014a9, + 0x000014c4, 0x000014ca, 0x000014ef, 0x000014f9, + 0x00001513, 0x00001557, 0x00001581, 0x000015c0, + 0x000015d1, 0x000015f8, 0x0000161d, 0x0000164c, // Entry 100 - 11F - 0x0000163c, 0x0000166b, 0x00001687, + 0x00001661, 0x00001690, 0x000016ac, } // Size: 1060 bytes -const es_ESData string = "" + // Size: 5767 bytes +const es_ESData string = "" + // Size: 5804 bytes "\x02Versión: %[1]s\x02Versión FRP: %[1]s\x02Fecha de compilación: %[1]s" + "\x02Todos los archivos\x02Archivos de configuración\x02Archivos de certi" + "ficado\x02Archivos clave\x02Archivos de registro\x02Número fuera del ran" + @@ -576,57 +576,58 @@ const es_ESData string = "" + // Size: 5767 bytes "do\x02Seleccionar archivo de certificado\x02Clave de certificado\x02Sele" + "ccionar archivo de clave de certificado\x02CA de confianza\x02Selecciona" + "r archivo CA de confianza\x02Desactivar primer byte personalizado\x02Ava" + - "nzado\x02Mux TCP\x02Mux Keepalive\x02Dirección de la fuente\x02Salir des" + - "pués de fallar el inicio de sesión\x02Desactivar el inicio automático al" + - " arrancar\x02Metadatos\x02Características experimentales\x02* Las siguie" + - "ntes características pueden afectar la estabilidad del servicio.\x02Usar" + - " registros SVCB del servidor\x02La configuración ya existe\x02El nombre " + - "de configuración \x22%[1]s\x22 ya existe.\x02Nuevo Proxy\x02Editar Proxy" + - " - %[1]s\x02Aleatorio\x02Tipo\x02Role\x02Servidor\x02Visitante\x02Llave " + - "secreta\x02Dirección local\x02Puerto local\x02Puerto remoto\x02Permitir " + - "usuarios\x02Dirección de enlace\x02Puerto de enlace\x02Nombre del servid" + - "or\x02Usuario del servidor\x02Subdominio\x02Dominios personalizados\x02R" + - "uta URL\x02Solicitar encabezados\x02Multiplexor\x02Usuario de ruta\x02Cl" + - "iente\x02Banda ancha\x02Protocolo proxy\x02auto\x02por defecto\x02Manten" + - "er túnel\x02Cifrado\x02Compresión\x02Número de reintentos\x02Veces/Hora" + - "\x02Intervalo de reintento\x02Repuesto\x02Interruptor de respaldo\x02mil" + - "isegundo\x02Usuario HTTP\x02Contraseña HTTP\x02Reescritura de host\x02En" + - "chufar\x02Nombre\x02Ruta Unix\x02Seleccione la ruta de Unix\x02Ruta loca" + - "l\x02Seleccione una carpeta para la lista de directorios.\x02Prefijo de " + - "tira\x02Equilibrio de carga\x02Grupo\x02Clave de grupo\x02Chequeo de sal" + - "ud\x02Tipo\x02Se acabó el tiempo\x02Recuento de fallas\x02Intervalo\x02E" + - "l proxy ya existe\x02El nombre de proxy \x22%[1]s\x22 ya existe.\x02Abri" + - "r registro\x02Último\x02Ítem\x02Tipo de NAT\x02Comportamiento\x02Direcci" + - "ón externa\x02Sí\x02No\x02Red pública\x02Desconocido\x02Correr\x02Deten" + - "ido\x02Comenzando\x02Parada\x02Estado\x02Dirección remota\x02Copiar\x02C" + - "omienzo\x02Servicio\x02Detener configuración \x22%[1]s\x22\x02¿Está segu" + - "ro de que desea detener la configuración \x22%[1]s\x22?\x02Deténgase\x02" + - "Directorio local\x02Puerto\x02Puerto abierto\x02Preferencias\x02Contrase" + - "ña maestra\x02Puede establecer una contraseña para restringir el acceso" + - " a este programa.\x0aSe le pedirá que lo ingrese la próxima vez que use " + - "este programa.\x02Usar contraseña maestra\x02Cambiar la contraseña\x02Id" + - "iomas\x02El idioma de visualización actual es\x02Debe reiniciar el progr" + - "ama para aplicar la modificación.\x02Seleccione el idioma\x02Predetermin" + - "ados\x02Defina el valor predeterminado al crear una nueva configuración." + - "\x0aEl valor aquí no afectará la configuración existente.\x02Valor ajust" + - "ado\x02Contraseña eliminada.\x02Nueva contraseña maestra\x02Escriba la c" + - "ontraseña otra vez\x02La contraseña está configurada.\x02Nivel de regist" + - "ro\x02Retención de registros\x02Añadir rápido\x02Escritorio remoto\x02Se" + - "rvidor de archivos HTTP\x02Habilitar\x02Abrir configuración\x02Edición d" + - "irecta\x02Dominios\x02Copiar dirección de acceso\x02Esta función solo ad" + - "mite texto en formato INI o TOML.\x02Eliminar proxy \x22%[1]s\x22\x02¿Es" + - "tá seguro de que desea eliminar el proxy \x22%[1]s\x22?\x02Deshabilitar " + - "proxy \x22%[1]s\x22\x02¿Está seguro de que desea desactivar el proxy " + - "\x22%[1]s\x22?\x02Deshabilitar\x02Gama de puertos pasivos\x02Administrad" + - "or de FRP\x02* Admite importación por lotes, un enlace por línea.\x02Ren" + - "ombrar automáticamente\x02Listo\x02Introduzca la lista de URL correcta." + - "\x02Descargar\x02Introducir la contraseña\x02Debe ingresar una contraseñ" + - "a de administración para operar %[1]s.\x02Ingrese la contraseña de admin" + - "istración\x02La contraseña es incorrecta. Escriba la contraseña otra vez" + - ".\x02Entrada invalida\x02Ingrese un número de %.[1]f a %.[2]f.\x02Ingres" + - "e un número de %[1]s a %[2]s.\x02El texto no coincide con el patrón requ" + - "erido.\x02Selección requerida\x02Seleccione una de las opciones proporci" + - "onadas.\x02Se requiere una selección." + "nzado\x02Dirección de la fuente\x02Mux TCP\x02Salir después de fallar el" + + " inicio de sesión\x02Desactivar el inicio automático al arrancar\x02Usar" + + " archivo de configuración de formato heredado\x02Metadatos\x02Caracterís" + + "ticas experimentales\x02* Las siguientes características pueden afectar " + + "la estabilidad del servicio.\x02Usar registros SVCB del servidor\x02La c" + + "onfiguración ya existe\x02El nombre de configuración \x22%[1]s\x22 ya ex" + + "iste.\x02Nuevo Proxy\x02Editar Proxy - %[1]s\x02Aleatorio\x02Tipo\x02Rol" + + "e\x02Servidor\x02Visitante\x02Llave secreta\x02Dirección local\x02Puerto" + + " local\x02Puerto remoto\x02Permitir usuarios\x02Dirección de enlace\x02P" + + "uerto de enlace\x02Nombre del servidor\x02Usuario del servidor\x02Subdom" + + "inio\x02Dominios personalizados\x02Ruta URL\x02Solicitar encabezados\x02" + + "Multiplexor\x02Usuario de ruta\x02Cliente\x02Banda ancha\x02Protocolo pr" + + "oxy\x02auto\x02por defecto\x02Mantener túnel\x02Cifrado\x02Compresión" + + "\x02Número de reintentos\x02Veces/Hora\x02Intervalo de reintento\x02Repu" + + "esto\x02Interruptor de respaldo\x02milisegundo\x02Usuario HTTP\x02Contra" + + "seña HTTP\x02Reescritura de host\x02Enchufar\x02Nombre\x02Ruta Unix\x02S" + + "eleccione la ruta de Unix\x02Ruta local\x02Seleccione una carpeta para l" + + "a lista de directorios.\x02Prefijo de tira\x02Equilibrio de carga\x02Gru" + + "po\x02Clave de grupo\x02Chequeo de salud\x02Tipo\x02Se acabó el tiempo" + + "\x02Recuento de fallas\x02Intervalo\x02El proxy ya existe\x02El nombre d" + + "e proxy \x22%[1]s\x22 ya existe.\x02Abrir registro\x02Último\x02Ítem\x02" + + "Tipo de NAT\x02Comportamiento\x02Dirección externa\x02Sí\x02No\x02Red pú" + + "blica\x02Desconocido\x02Correr\x02Detenido\x02Comenzando\x02Parada\x02Es" + + "tado\x02Dirección remota\x02Copiar\x02Comienzo\x02Servicio\x02Detener co" + + "nfiguración \x22%[1]s\x22\x02¿Está seguro de que desea detener la config" + + "uración \x22%[1]s\x22?\x02Deténgase\x02Directorio local\x02Puerto\x02Pue" + + "rto abierto\x02Preferencias\x02Contraseña maestra\x02Puede establecer un" + + "a contraseña para restringir el acceso a este programa.\x0aSe le pedirá " + + "que lo ingrese la próxima vez que use este programa.\x02Usar contraseña " + + "maestra\x02Cambiar la contraseña\x02Idiomas\x02El idioma de visualizació" + + "n actual es\x02Debe reiniciar el programa para aplicar la modificación." + + "\x02Seleccione el idioma\x02Predeterminados\x02Defina el valor predeterm" + + "inado al crear una nueva configuración.\x0aEl valor aquí no afectará la " + + "configuración existente.\x02Valor ajustado\x02Contraseña eliminada.\x02N" + + "ueva contraseña maestra\x02Escriba la contraseña otra vez\x02La contrase" + + "ña está configurada.\x02Nivel de registro\x02Retención de registros\x02" + + "Añadir rápido\x02Escritorio remoto\x02Servidor de archivos HTTP\x02Desha" + + "bilitar\x02Abrir configuración\x02Edición directa\x02Dominios\x02Copiar " + + "dirección de acceso\x02Esta función solo admite texto en formato INI o T" + + "OML.\x02Eliminar proxy \x22%[1]s\x22\x02¿Está seguro de que desea elimin" + + "ar el proxy \x22%[1]s\x22?\x02Deshabilitar proxy \x22%[1]s\x22\x02¿Está " + + "seguro de que desea desactivar el proxy \x22%[1]s\x22?\x02Habilitar\x02G" + + "ama de puertos pasivos\x02Administrador de FRP\x02* Admite importación p" + + "or lotes, un enlace por línea.\x02Renombrar automáticamente\x02Listo\x02" + + "Introduzca la lista de URL correcta.\x02Descargar\x02Introducir la contr" + + "aseña\x02Debe ingresar una contraseña de administración para operar %[1]" + + "s.\x02Ingrese la contraseña de administración\x02La contraseña es incorr" + + "ecta. Escriba la contraseña otra vez.\x02Entrada invalida\x02Ingrese un " + + "número de %.[1]f a %.[2]f.\x02Ingrese un número de %[1]s a %[2]s.\x02El " + + "texto no coincide con el patrón requerido.\x02Selección requerida\x02Sel" + + "eccione una de las opciones proporcionadas.\x02Se requiere una selección" + + "." var ja_JPIndex = []uint32{ // 259 elements // Entry 0 - 1F @@ -662,50 +663,50 @@ var ja_JPIndex = []uint32{ // 259 elements 0x00000a74, 0x00000a8a, 0x00000a91, 0x00000a98, 0x00000aa5, 0x00000aaf, 0x00000ace, 0x00000ade, 0x00000b0c, 0x00000b1f, 0x00000b51, 0x00000b82, - 0x00000b89, 0x00000b93, 0x00000bac, 0x00000bc2, - 0x00000be1, 0x00000c0c, 0x00000c1c, 0x00000c2f, - 0x00000c8c, 0x00000cb8, 0x00000cda, 0x00000d0d, + 0x00000b89, 0x00000b9f, 0x00000ba9, 0x00000bc8, + 0x00000bf3, 0x00000c27, 0x00000c37, 0x00000c4a, + 0x00000ca7, 0x00000cd3, 0x00000cf5, 0x00000d28, // Entry 80 - 9F - 0x00000d23, 0x00000d41, 0x00000d4e, 0x00000d58, - 0x00000d5f, 0x00000d69, 0x00000d76, 0x00000d80, - 0x00000d99, 0x00000daf, 0x00000dc5, 0x00000de1, - 0x00000dfa, 0x00000e10, 0x00000e20, 0x00000e39, - 0x00000e4c, 0x00000e65, 0x00000e7c, 0x00000e98, - 0x00000eae, 0x00000ec4, 0x00000ed7, 0x00000ee1, - 0x00000efd, 0x00000f04, 0x00000f0e, 0x00000f2a, - 0x00000f34, 0x00000f3b, 0x00000f4e, 0x00000f59, + 0x00000d3e, 0x00000d5c, 0x00000d69, 0x00000d73, + 0x00000d7a, 0x00000d84, 0x00000d91, 0x00000d9b, + 0x00000db4, 0x00000dca, 0x00000de0, 0x00000dfc, + 0x00000e15, 0x00000e2b, 0x00000e3b, 0x00000e54, + 0x00000e67, 0x00000e80, 0x00000e97, 0x00000eb3, + 0x00000ec9, 0x00000edf, 0x00000ef2, 0x00000efc, + 0x00000f18, 0x00000f1f, 0x00000f29, 0x00000f45, + 0x00000f4f, 0x00000f56, 0x00000f69, 0x00000f74, // Entry A0 - BF - 0x00000f69, 0x00000f70, 0x00000f98, 0x00000fa2, - 0x00000fb4, 0x00000fc9, 0x00000fe2, 0x00000ff2, - 0x00001005, 0x00001011, 0x00001026, 0x00001039, - 0x00001079, 0x00001098, 0x000010a5, 0x000010b2, - 0x000010c8, 0x000010d5, 0x000010df, 0x000010f2, - 0x000010fc, 0x0000110f, 0x00001137, 0x00001170, - 0x0000118c, 0x00001193, 0x0000119a, 0x000011a8, - 0x000011af, 0x000011c2, 0x000011c9, 0x000011d3, + 0x00000f84, 0x00000f8b, 0x00000fb3, 0x00000fbd, + 0x00000fcf, 0x00000fe4, 0x00000ffd, 0x0000100d, + 0x00001020, 0x0000102c, 0x00001041, 0x00001054, + 0x00001094, 0x000010b3, 0x000010c0, 0x000010cd, + 0x000010e3, 0x000010f0, 0x000010fa, 0x0000110d, + 0x00001117, 0x0000112a, 0x00001152, 0x0000118b, + 0x000011a7, 0x000011ae, 0x000011b5, 0x000011c3, + 0x000011ca, 0x000011dd, 0x000011e4, 0x000011ee, // Entry C0 - DF - 0x000011ef, 0x000011ff, 0x0000120f, 0x00001216, - 0x0000121d, 0x00001224, 0x0000122b, 0x00001244, - 0x0000124e, 0x00001258, 0x00001265, 0x00001289, - 0x000012c3, 0x000012cd, 0x000012da, 0x000012e4, - 0x000012f4, 0x00001301, 0x0000131d, 0x000013d9, - 0x00001404, 0x00001423, 0x0000142a, 0x00001443, - 0x0000149b, 0x000014b1, 0x000014c1, 0x00001550, - 0x00001569, 0x00001594, 0x000015b9, 0x000015c3, + 0x0000120a, 0x0000121a, 0x0000122a, 0x00001231, + 0x00001238, 0x0000123f, 0x00001246, 0x0000125f, + 0x00001269, 0x00001273, 0x00001280, 0x000012a4, + 0x000012de, 0x000012e8, 0x000012f5, 0x000012ff, + 0x0000130f, 0x0000131c, 0x00001338, 0x000013f4, + 0x0000141f, 0x0000143e, 0x00001445, 0x0000145e, + 0x000014b6, 0x000014cc, 0x000014dc, 0x0000156b, + 0x00001584, 0x000015af, 0x000015d4, 0x000015de, // Entry E0 - FF - 0x000015f1, 0x00001601, 0x0000160e, 0x00001621, - 0x00001640, 0x0000165e, 0x00001665, 0x00001675, - 0x00001682, 0x00001692, 0x000016b7, 0x00001713, - 0x0000173d, 0x0000177d, 0x000017a7, 0x000017ea, - 0x000017f1, 0x0000180d, 0x00001821, 0x00001880, - 0x0000189c, 0x000018a3, 0x000018d7, 0x000018ea, - 0x00001909, 0x00001964, 0x00001986, 0x000019d0, - 0x000019dd, 0x00001a20, 0x00001a61, 0x00001a9e, + 0x0000160c, 0x0000161c, 0x00001629, 0x0000163c, + 0x0000165b, 0x00001679, 0x00001680, 0x00001690, + 0x0000169d, 0x000016ad, 0x000016d2, 0x0000172e, + 0x00001758, 0x00001798, 0x000017c2, 0x00001805, + 0x0000180c, 0x00001828, 0x0000183c, 0x0000189b, + 0x000018b7, 0x000018be, 0x000018f2, 0x00001905, + 0x00001924, 0x0000197f, 0x000019a1, 0x000019eb, + 0x000019f8, 0x00001a3b, 0x00001a7c, 0x00001ab9, // Entry 100 - 11F - 0x00001aab, 0x00001af7, 0x00001b10, + 0x00001ac6, 0x00001b12, 0x00001b2b, } // Size: 1060 bytes -const ja_JPData string = "" + // Size: 6928 bytes +const ja_JPData string = "" + // Size: 6955 bytes "\x02バージョン:%[1]s\x02FRP バージョン:%[1]s\x02コンパイル日:%[1]s\x02すべてのファイル\x02設定ファイル" + "\x02証明書ファイル\x02秘密鍵ファイル\x02ログファイル\x02許容範囲外の数値\x02%[1]d より大きい数値を入力してください。" + "\x02パスワードの不一致\x02もう一度確認してください。\x02数字ではありません\x02有効な数値を入力してください。\x02新しいバージ" + @@ -727,35 +728,35 @@ const ja_JPData string = "" + // Size: 6928 bytes "\x02HTTP プロキシ\x02接続プールの数\x02UDPパケットサイズ\x02ハートビート\x02間隔\x02s\x02タイムアウト" + "\x02接続タイムアウト\x02接続を維持\x02アイドルタイムアウト\x02最大ストリーム\x02有効\x02無効\x02ホスト名\x02証明" + "書\x02証明書ファイルを選択\x02証明書キー\x02証明書キーファイルを選択します\x02信頼できる CA\x02信頼できる CA ファ" + - "イルを選択します\x02カスタムの先頭バイトを無効にする\x02高度\x02多重化\x02多重化接続を維持\x02送信元アドレス\x02ログ" + - "イン失敗後に終了\x02起動時に自動起動を無効にする\x02メタデータ\x02実験的な機能\x02* 以下の機能はサービスの安定性に影響を与" + - "える可能性があります。\x02サーバーSVCBレコードを使用する\x02設定はすでに存在します\x02設定名「%[1]s」はすでに存在します" + - "。\x02新しいプロキシ\x02プロキシの編集 - %[1]s\x02ランダム\x02タイプ\x02役割\x02サーバ\x02ビジター" + - "\x02秘密鍵\x02ローカルアドレス\x02ローカルポート\x02リモートポート\x02ユーザーを許可する\x02バインドアドレス\x02バイ" + - "ンドポート\x02サーバー名\x02サーバーユーザー\x02サブドメイン\x02カスタムドメイン\x02URL ルーティング\x02リクエス" + - "トヘッダー\x02マルチプレクサ\x02ルートユーザー\x02クライアント\x02帯域幅\x02プロキシプロトコル\x02自動\x02既定値" + - "\x02トンネルを維持する\x02暗号化\x02圧縮\x02リトライ回数\x02回/時間\x02再試行間隔\x02代替\x02フォールバックタイ" + - "ムアウト\x02ミリ秒\x02HTTP ユーザー\x02HTTP パスワード\x02ホストの書き換え\x02プラグイン\x02プラグイン名" + - "\x02Unix パス\x02Unix パスを選択\x02ローカルパス\x02ディレクトリリストのフォルダを選択します。\x02プレフィックスを" + - "削除\x02負荷平衡\x02グループ\x02グループ秘密鍵\x02健康診断\x02タイプ\x02タイムアウト\x02失敗数\x02チェック間" + - "隔\x02プロキシはすでに存在します\x02プロキシ名「%[1]s」はすでに存在します。\x02ログフォルダを開く\x02最新\x02項目" + - "\x02NAT タイプ\x02挙動\x02外部アドレス\x02はい\x02いいえ\x02公共のネットワーク\x02わからない\x02ランニング" + - "\x02停止\x02起動\x02停止\x02状態\x02リモートアドレス\x02コピー\x02始める\x02サービス\x02設定「%[1]s」を" + - "停止します\x02設定「%[1]s」を停止してもよろしいですか?\x02止まる\x02フォルダ\x02ポート\x02ポート開放\x02環境設" + - "定\x02マスターパスワード\x02パスワードを設定して、このプログラムへのアクセスを制限できます。\x0a次回このプログラムを使用するとき" + - "に入力するよう求められます。\x02マスターパスワードを使用する\x02パスワードを変更する\x02言語\x02現在の表示言語は\x02変更" + - "を適用するには、プログラムを再起動する必要があります。\x02言語を選択する\x02デフォルト\x02新しい設定を作成するときのデフォルト値" + - "を定義します。\x0aここでの値は、既存の設定には影響しません。\x02デフォルトの設定\x02パスワードが解除されました。\x02新しいマ" + - "スターパスワード\x02再入力\x02パスワードが設定されています。\x02ログレベル\x02ログ保持\x02クイック追加\x02リモートデ" + - "スクトップ\x02HTTP ファイルサーバー\x02有効\x02設定を開く\x02直接編集\x02ドメイン名\x02アクセスアドレスのコピー" + - "\x02この機能は、INI または TOML 形式のテキストのみをサポートします。\x02プロキシ「%[1]s」を削除します\x02プロキシ「%" + - "[1]s」を削除してもよろしいですか?\x02プロキシ「%[1]s」を無効にする\x02プロキシ「%[1]s」を無効にしてもよろしいですか?" + - "\x02無効\x02パッシブポート範囲\x02FRP マネージャ\x02* バッチインポートをサポートします、1行に1つのリンクがあります。" + - "\x02自動的に名前を変更\x02準備\x02正しいURLリストを入力してください。\x02ダウンロード\x02パスワードを入力する\x02%[" + - "1]s を操作するには、管理パスワードを入力する必要があります。\x02管理者パスワードを入力\x02パスワードが正しくありません。 パスワード" + - "再入力。\x02無効入力\x02%.[1]f から %.[2]f までの数字を入力してください。\x02%[1]s から %[2]s までの" + - "数値を入力してください。\x02テキストが必要なパターンと一致しません。\x02選択必須\x02提供されたオプションのいずれかを選択してくだ" + - "さい。\x02選択が必要です。" + "イルを選択します\x02カスタムの先頭バイトを無効にする\x02高度\x02送信元アドレス\x02多重化\x02ログイン失敗後に終了\x02" + + "起動時に自動起動を無効にする\x02従来の形式の設定ファイルを使用する\x02メタデータ\x02実験的な機能\x02* 以下の機能はサービス" + + "の安定性に影響を与える可能性があります。\x02サーバーSVCBレコードを使用する\x02設定はすでに存在します\x02設定名「%[1]s」" + + "はすでに存在します。\x02新しいプロキシ\x02プロキシの編集 - %[1]s\x02ランダム\x02タイプ\x02役割\x02サーバ" + + "\x02ビジター\x02秘密鍵\x02ローカルアドレス\x02ローカルポート\x02リモートポート\x02ユーザーを許可する\x02バインドアド" + + "レス\x02バインドポート\x02サーバー名\x02サーバーユーザー\x02サブドメイン\x02カスタムドメイン\x02URL ルーティング" + + "\x02リクエストヘッダー\x02マルチプレクサ\x02ルートユーザー\x02クライアント\x02帯域幅\x02プロキシプロトコル\x02自動" + + "\x02既定値\x02トンネルを維持する\x02暗号化\x02圧縮\x02リトライ回数\x02回/時間\x02再試行間隔\x02代替\x02フォ" + + "ールバックタイムアウト\x02ミリ秒\x02HTTP ユーザー\x02HTTP パスワード\x02ホストの書き換え\x02プラグイン\x02" + + "プラグイン名\x02Unix パス\x02Unix パスを選択\x02ローカルパス\x02ディレクトリリストのフォルダを選択します。\x02" + + "プレフィックスを削除\x02負荷平衡\x02グループ\x02グループ秘密鍵\x02健康診断\x02タイプ\x02タイムアウト\x02失敗数" + + "\x02チェック間隔\x02プロキシはすでに存在します\x02プロキシ名「%[1]s」はすでに存在します。\x02ログフォルダを開く\x02最新" + + "\x02項目\x02NAT タイプ\x02挙動\x02外部アドレス\x02はい\x02いいえ\x02公共のネットワーク\x02わからない\x02" + + "ランニング\x02停止\x02起動\x02停止\x02状態\x02リモートアドレス\x02コピー\x02始める\x02サービス\x02設定「" + + "%[1]s」を停止します\x02設定「%[1]s」を停止してもよろしいですか?\x02止まる\x02フォルダ\x02ポート\x02ポート開放" + + "\x02環境設定\x02マスターパスワード\x02パスワードを設定して、このプログラムへのアクセスを制限できます。\x0a次回このプログラムを使" + + "用するときに入力するよう求められます。\x02マスターパスワードを使用する\x02パスワードを変更する\x02言語\x02現在の表示言語は" + + "\x02変更を適用するには、プログラムを再起動する必要があります。\x02言語を選択する\x02デフォルト\x02新しい設定を作成するときのデフ" + + "ォルト値を定義します。\x0aここでの値は、既存の設定には影響しません。\x02デフォルトの設定\x02パスワードが解除されました。\x02" + + "新しいマスターパスワード\x02再入力\x02パスワードが設定されています。\x02ログレベル\x02ログ保持\x02クイック追加\x02リ" + + "モートデスクトップ\x02HTTP ファイルサーバー\x02無効\x02設定を開く\x02直接編集\x02ドメイン名\x02アクセスアドレス" + + "のコピー\x02この機能は、INI または TOML 形式のテキストのみをサポートします。\x02プロキシ「%[1]s」を削除します\x02" + + "プロキシ「%[1]s」を削除してもよろしいですか?\x02プロキシ「%[1]s」を無効にする\x02プロキシ「%[1]s」を無効にしてもよろ" + + "しいですか?\x02有効\x02パッシブポート範囲\x02FRP マネージャ\x02* バッチインポートをサポートします、1行に1つのリンク" + + "があります。\x02自動的に名前を変更\x02準備\x02正しいURLリストを入力してください。\x02ダウンロード\x02パスワードを入力" + + "する\x02%[1]s を操作するには、管理パスワードを入力する必要があります。\x02管理者パスワードを入力\x02パスワードが正しくあり" + + "ません。 パスワード再入力。\x02無効入力\x02%.[1]f から %.[2]f までの数字を入力してください。\x02%[1]s から" + + " %[2]s までの数値を入力してください。\x02テキストが必要なパターンと一致しません。\x02選択必須\x02提供されたオプションのいずれ" + + "かを選択してください。\x02選択が必要です。" var ko_KRIndex = []uint32{ // 259 elements // Entry 0 - 1F @@ -791,50 +792,50 @@ var ko_KRIndex = []uint32{ // 259 elements 0x0000087e, 0x0000088f, 0x00000896, 0x0000089d, 0x000008ae, 0x000008b8, 0x000008d0, 0x000008de, 0x000008fa, 0x00000912, 0x00000938, 0x00000961, - 0x0000096b, 0x00000975, 0x0000098a, 0x00000998, - 0x000009b4, 0x000009da, 0x000009ea, 0x000009fb, - 0x00000a4b, 0x00000a65, 0x00000a84, 0x00000abb, + 0x0000096b, 0x00000979, 0x00000983, 0x0000099f, + 0x000009c5, 0x000009eb, 0x000009fb, 0x00000a0c, + 0x00000a5c, 0x00000a76, 0x00000a95, 0x00000acc, // Entry 80 - 9F - 0x00000ac9, 0x00000ae2, 0x00000aef, 0x00000af6, - 0x00000afd, 0x00000b04, 0x00000b0e, 0x00000b19, - 0x00000b27, 0x00000b35, 0x00000b43, 0x00000b54, - 0x00000b65, 0x00000b76, 0x00000b84, 0x00000b95, - 0x00000ba6, 0x00000bc1, 0x00000bcf, 0x00000bdd, - 0x00000bed, 0x00000bfe, 0x00000c0e, 0x00000c18, - 0x00000c2f, 0x00000c36, 0x00000c40, 0x00000c4e, - 0x00000c58, 0x00000c5f, 0x00000c70, 0x00000c7b, + 0x00000ada, 0x00000af3, 0x00000b00, 0x00000b07, + 0x00000b0e, 0x00000b15, 0x00000b1f, 0x00000b2a, + 0x00000b38, 0x00000b46, 0x00000b54, 0x00000b65, + 0x00000b76, 0x00000b87, 0x00000b95, 0x00000ba6, + 0x00000bb7, 0x00000bd2, 0x00000be0, 0x00000bee, + 0x00000bfe, 0x00000c0f, 0x00000c1f, 0x00000c29, + 0x00000c40, 0x00000c47, 0x00000c51, 0x00000c5f, + 0x00000c69, 0x00000c70, 0x00000c81, 0x00000c8c, // Entry A0 - BF - 0x00000c8c, 0x00000c93, 0x00000ca8, 0x00000cb2, - 0x00000cc1, 0x00000cd3, 0x00000ce7, 0x00000cf4, - 0x00000d08, 0x00000d14, 0x00000d27, 0x00000d35, - 0x00000d71, 0x00000d85, 0x00000d93, 0x00000d9a, - 0x00000dac, 0x00000dba, 0x00000dc1, 0x00000dcf, - 0x00000ddd, 0x00000de4, 0x00000e06, 0x00000e40, - 0x00000e55, 0x00000e5c, 0x00000e63, 0x00000e6e, - 0x00000e75, 0x00000e83, 0x00000e87, 0x00000e91, + 0x00000c9d, 0x00000ca4, 0x00000cb9, 0x00000cc3, + 0x00000cd2, 0x00000ce4, 0x00000cf8, 0x00000d05, + 0x00000d19, 0x00000d25, 0x00000d38, 0x00000d46, + 0x00000d82, 0x00000d96, 0x00000da4, 0x00000dab, + 0x00000dbd, 0x00000dcb, 0x00000dd2, 0x00000de0, + 0x00000dee, 0x00000df5, 0x00000e17, 0x00000e51, + 0x00000e66, 0x00000e6d, 0x00000e74, 0x00000e7f, + 0x00000e86, 0x00000e94, 0x00000e98, 0x00000ea2, // Entry C0 - DF - 0x00000ea5, 0x00000eb9, 0x00000ec3, 0x00000ecd, - 0x00000ed4, 0x00000edb, 0x00000ee2, 0x00000ef0, - 0x00000ef7, 0x00000efe, 0x00000f08, 0x00000f1e, - 0x00000f4a, 0x00000f51, 0x00000f65, 0x00000f6c, - 0x00000f7a, 0x00000f81, 0x00000f98, 0x00001054, - 0x00001072, 0x00001086, 0x0000108d, 0x000010a5, - 0x000010f1, 0x000010ff, 0x00001109, 0x00001181, - 0x00001198, 0x000011b9, 0x000011d4, 0x000011eb, + 0x00000eb6, 0x00000eca, 0x00000ed4, 0x00000ede, + 0x00000ee5, 0x00000eec, 0x00000ef3, 0x00000f01, + 0x00000f08, 0x00000f0f, 0x00000f19, 0x00000f2f, + 0x00000f5b, 0x00000f62, 0x00000f76, 0x00000f7d, + 0x00000f8b, 0x00000f92, 0x00000fa9, 0x00001065, + 0x00001083, 0x00001097, 0x0000109e, 0x000010b6, + 0x00001102, 0x00001110, 0x0000111a, 0x00001192, + 0x000011a9, 0x000011ca, 0x000011e5, 0x000011fc, // Entry E0 - FF - 0x00001216, 0x00001224, 0x00001232, 0x00001240, - 0x00001254, 0x00001267, 0x0000126e, 0x0000127c, - 0x0000128a, 0x00001294, 0x000012ac, 0x000012f2, - 0x0000130b, 0x0000133a, 0x00001359, 0x0000138e, - 0x00001395, 0x000013ad, 0x000013bb, 0x00001404, - 0x00001422, 0x00001430, 0x00001459, 0x00001466, - 0x00001477, 0x000014be, 0x000014d9, 0x0000152c, - 0x0000153d, 0x00001575, 0x000015af, 0x000015e8, + 0x00001227, 0x00001235, 0x00001243, 0x00001251, + 0x00001265, 0x00001278, 0x0000127f, 0x0000128d, + 0x0000129b, 0x000012a5, 0x000012bd, 0x00001303, + 0x0000131c, 0x0000134b, 0x0000136a, 0x0000139f, + 0x000013a6, 0x000013be, 0x000013cc, 0x00001415, + 0x00001433, 0x00001441, 0x0000146a, 0x00001477, + 0x00001488, 0x000014cf, 0x000014ea, 0x0000153d, + 0x0000154e, 0x00001586, 0x000015c0, 0x000015f9, // Entry 100 - 11F - 0x000015f6, 0x00001629, 0x00001644, + 0x00001607, 0x0000163a, 0x00001655, } // Size: 1060 bytes -const ko_KRData string = "" + // Size: 5700 bytes +const ko_KRData string = "" + // Size: 5717 bytes "\x02버전: %[1]s\x02FRP 버전: %[1]s\x02빌드 날짜: %[1]s\x02모든 파일\x02구성 파일\x02인증서 " + "파일\x02열쇠 파일\x02로그 파일\x02허용 범위를 벗어난 숫자\x02%[1]d보다 큰 숫자를 입력하세요.\x02암호 불일" + "치\x02확인하고 다시 시도해 주세요.\x02숫자가 아님\x02유효한 숫자를 입력하세요.\x02새로운 버전!\x02에 대한" + @@ -855,30 +856,30 @@ const ko_KRData string = "" + // Size: 5700 bytes "제\x02삭제 일\x02날\x02연결\x02규약\x02HTTP 프록시\x02연결 수\x02UDP 패킷 크기\x02심장박동" + "\x02간격\x02s\x02타임아웃\x02연결 시간 초과\x02유지\x02유휴 시간 초과\x02최대 스트림\x02켜다\x02폐쇄" + "\x02호스트 이름\x02자격증\x02인증서 파일 선택\x02인증서 키\x02인증서 키 파일 선택\x02신뢰할 수 있는 CA" + - "\x02신뢰할 수 있는 CA 파일 선택\x02맞춤 첫 번째 바이트 비활성화\x02고급의\x02다중화\x02다중화 대기 중\x02소" + - "스 주소\x02로그인 실패 후 종료\x02부팅 시 자동 시작 비활성화\x02메타데이터\x02실험적 기능\x02* 다음 기능은 " + - "서비스의 안정성에 영향을 미칠 수 있습니다.\x02서버 SVCB 기록 사용\x02구성이 이미 있습니다.\x02구성 이름 " + - "\x22%[1]s\x22 이(가) 이미 존재합니다.\x02새 프록시\x02프록시 편집 - %[1]s\x02무작위의\x02유형" + - "\x02역할\x02서버\x02방문객\x02비밀 키\x02지역 주소\x02로컬 포트\x02원격 포트\x02사용자 허용\x02바인드 " + - "주소\x02바인드 포트\x02서버 이름\x02서버 사용자\x02하위 도메인\x02사용자 정의 도메인\x02URL 라우팅\x02" + - "요청 헤더\x02멀티플렉서\x02경로 사용자\x02클라이언트\x02대역폭\x02프록시 프로토콜\x02자동\x02기본값\x02터" + - "널 유지\x02암호화\x02압축\x02재시도 횟수\x02회/시간\x02재시도 간격\x02폴백\x02대체 시간 초과\x02밀리초" + - "\x02HTTP 사용자\x02HTTP 비밀번호\x02호스트 재작성\x02플러그인\x02플러그인 이름\x02Unix 경로\x02선택" + - " Unix 경로\x02로컬 경로\x02디렉토리 목록에 대한 폴더를 선택하십시오.\x02스트립 접두사\x02부하 분산\x02그룹" + - "\x02그룹 비밀 키\x02건강 체크\x02유형\x02시간 초과\x02실패 횟수\x02간격\x02프록시가 이미 있습니다.\x02프" + - "록시 이름 \x22%[1]s\x22 이(가) 이미 존재합니다.\x02로그 폴더 열기\x02최신\x02안건\x02NAT 유형" + - "\x02행실\x02외부 주소\x02예\x02아니요\x02공용 네트워크\x02알려지지 않은\x02달리기\x02중지됨\x02시작" + - "\x02멎는\x02상태\x02원격 주소\x02복사\x02시작\x02서비스\x02\x22%[1]s\x22 구성 중지\x02\x22%" + - "[1]s\x22 구성을 중지하시겠습니까?\x02중지\x02로컬 디렉토리\x02포트\x02오픈 포트\x02옵션\x02마스터 비밀번호" + - "\x02이 프로그램에 대한 액세스를 제한하기 위해 암호를 설정할 수 있습니다.\x0a다음에 이 프로그램을 사용할 때 입력하라는 메" + - "시지가 표시됩니다.\x02마스터 비밀번호 사용\x02비밀번호 변경\x02언어\x02현재 표시 언어는\x02수정 사항을 적용하려" + - "면 프로그램을 재시작해야 합니다.\x02언어 선택\x02기본값\x02새 구성을 만들 때 기본값을 정의합니다.\x0a여기의 값은" + - " 기존 구성에 영향을 주지 않습니다.\x02기본값으로 설정\x02암호가 제거되었습니다.\x02새 마스터 비밀번호\x02비밀번호 재" + - "입력\x02비밀번호가 설정되어 있습니다.\x02로그 수준\x02로그 보존\x02빠른 추가\x02원격 데스크탑\x02HTTP 파" + - "일 서버\x02켜다\x02구성 열기\x02직접 편집\x02도메인\x02액세스 주소 복사\x02이 기능은 INI 또는 TOML " + - "형식의 텍스트만 지원합니다.\x02프록시 \x22%[1]s\x22 삭제\x02\x22%[1]s\x22 프록시를 삭제하시겠습니까" + - "?\x02프록시 \x22%[1]s\x22 비활성화\x02\x22%[1]s\x22 프록시를 비활성화하시겠습니까?\x02폐쇄\x02패" + - "시브 포트 범위\x02FRP 관리자\x02* 한 줄에 하나의 링크로 일괄 가져오기를 지원합니다.\x02자동으로 이름 바꾸기" + + "\x02신뢰할 수 있는 CA 파일 선택\x02맞춤 첫 번째 바이트 비활성화\x02고급의\x02소스 주소\x02다중화\x02로그인 " + + "실패 후 종료\x02부팅 시 자동 시작 비활성화\x02레거시 형식 구성 파일 사용\x02메타데이터\x02실험적 기능\x02* " + + "다음 기능은 서비스의 안정성에 영향을 미칠 수 있습니다.\x02서버 SVCB 기록 사용\x02구성이 이미 있습니다.\x02구성" + + " 이름 \x22%[1]s\x22 이(가) 이미 존재합니다.\x02새 프록시\x02프록시 편집 - %[1]s\x02무작위의\x02유" + + "형\x02역할\x02서버\x02방문객\x02비밀 키\x02지역 주소\x02로컬 포트\x02원격 포트\x02사용자 허용\x02바" + + "인드 주소\x02바인드 포트\x02서버 이름\x02서버 사용자\x02하위 도메인\x02사용자 정의 도메인\x02URL 라우팅" + + "\x02요청 헤더\x02멀티플렉서\x02경로 사용자\x02클라이언트\x02대역폭\x02프록시 프로토콜\x02자동\x02기본값" + + "\x02터널 유지\x02암호화\x02압축\x02재시도 횟수\x02회/시간\x02재시도 간격\x02폴백\x02대체 시간 초과\x02" + + "밀리초\x02HTTP 사용자\x02HTTP 비밀번호\x02호스트 재작성\x02플러그인\x02플러그인 이름\x02Unix 경로" + + "\x02선택 Unix 경로\x02로컬 경로\x02디렉토리 목록에 대한 폴더를 선택하십시오.\x02스트립 접두사\x02부하 분산" + + "\x02그룹\x02그룹 비밀 키\x02건강 체크\x02유형\x02시간 초과\x02실패 횟수\x02간격\x02프록시가 이미 있습니다" + + ".\x02프록시 이름 \x22%[1]s\x22 이(가) 이미 존재합니다.\x02로그 폴더 열기\x02최신\x02안건\x02NAT " + + "유형\x02행실\x02외부 주소\x02예\x02아니요\x02공용 네트워크\x02알려지지 않은\x02달리기\x02중지됨\x02시" + + "작\x02멎는\x02상태\x02원격 주소\x02복사\x02시작\x02서비스\x02\x22%[1]s\x22 구성 중지\x02" + + "\x22%[1]s\x22 구성을 중지하시겠습니까?\x02중지\x02로컬 디렉토리\x02포트\x02오픈 포트\x02옵션\x02마스터" + + " 비밀번호\x02이 프로그램에 대한 액세스를 제한하기 위해 암호를 설정할 수 있습니다.\x0a다음에 이 프로그램을 사용할 때 입력" + + "하라는 메시지가 표시됩니다.\x02마스터 비밀번호 사용\x02비밀번호 변경\x02언어\x02현재 표시 언어는\x02수정 사항을" + + " 적용하려면 프로그램을 재시작해야 합니다.\x02언어 선택\x02기본값\x02새 구성을 만들 때 기본값을 정의합니다.\x0a여기의" + + " 값은 기존 구성에 영향을 주지 않습니다.\x02기본값으로 설정\x02암호가 제거되었습니다.\x02새 마스터 비밀번호\x02비밀번" + + "호 재입력\x02비밀번호가 설정되어 있습니다.\x02로그 수준\x02로그 보존\x02빠른 추가\x02원격 데스크탑\x02HTT" + + "P 파일 서버\x02폐쇄\x02구성 열기\x02직접 편집\x02도메인\x02액세스 주소 복사\x02이 기능은 INI 또는 TOML" + + " 형식의 텍스트만 지원합니다.\x02프록시 \x22%[1]s\x22 삭제\x02\x22%[1]s\x22 프록시를 삭제하시겠습니까?" + + "\x02프록시 \x22%[1]s\x22 비활성화\x02\x22%[1]s\x22 프록시를 비활성화하시겠습니까?\x02켜다\x02패시" + + "브 포트 범위\x02FRP 관리자\x02* 한 줄에 하나의 링크로 일괄 가져오기를 지원합니다.\x02자동으로 이름 바꾸기" + "\x02준비가 된\x02올바른 URL 목록을 입력하세요.\x02다운로드\x02암호를 입력\x02%[1]s을(를) 작동하려면 관리 " + "암호를 입력해야 합니다.\x02관리 비밀번호 입력\x02비밀번호가 올바르지 않습니다. 비밀번호를 다시 입력하세요.\x02잘못된" + " 입력\x02%.[1]f에서 %.[2]f까지의 숫자를 입력하세요.\x02%[1]s에서 %[2]s 사이의 숫자를 입력하십시오." + @@ -919,50 +920,50 @@ var zh_CNIndex = []uint32{ // 259 elements 0x000006d3, 0x000006e3, 0x000006ea, 0x000006f1, 0x000006fe, 0x0000070b, 0x0000071e, 0x0000072b, 0x00000744, 0x00000754, 0x0000076d, 0x00000786, - 0x0000078d, 0x0000079a, 0x000007aa, 0x000007ba, - 0x000007d6, 0x000007ec, 0x000007f6, 0x00000806, - 0x00000839, 0x00000855, 0x00000865, 0x00000886, + 0x0000078d, 0x0000079d, 0x000007aa, 0x000007c6, + 0x000007dc, 0x000007f8, 0x00000802, 0x00000812, + 0x00000845, 0x00000861, 0x00000871, 0x00000892, // Entry 80 - 9F - 0x00000893, 0x000008a8, 0x000008b5, 0x000008bc, - 0x000008c3, 0x000008cd, 0x000008d7, 0x000008de, - 0x000008eb, 0x000008f8, 0x00000905, 0x00000912, - 0x0000091f, 0x0000092c, 0x00000939, 0x00000946, - 0x00000950, 0x00000960, 0x0000096b, 0x00000975, - 0x0000097f, 0x0000098c, 0x00000996, 0x000009a3, - 0x000009b0, 0x000009b7, 0x000009be, 0x000009cb, - 0x000009d8, 0x000009e5, 0x000009f2, 0x000009fd, + 0x0000089f, 0x000008b4, 0x000008c1, 0x000008c8, + 0x000008cf, 0x000008d9, 0x000008e3, 0x000008ea, + 0x000008f7, 0x00000904, 0x00000911, 0x0000091e, + 0x0000092b, 0x00000938, 0x00000945, 0x00000952, + 0x0000095c, 0x0000096c, 0x00000977, 0x00000981, + 0x0000098b, 0x00000998, 0x000009a2, 0x000009af, + 0x000009bc, 0x000009c3, 0x000009ca, 0x000009d7, + 0x000009e4, 0x000009f1, 0x000009fe, 0x00000a09, // Entry A0 - BF - 0x00000a0a, 0x00000a11, 0x00000a1e, 0x00000a25, - 0x00000a31, 0x00000a3d, 0x00000a49, 0x00000a50, - 0x00000a5d, 0x00000a69, 0x00000a7c, 0x00000a89, - 0x00000ab7, 0x00000ac4, 0x00000ad1, 0x00000ade, - 0x00000aeb, 0x00000af8, 0x00000b05, 0x00000b12, - 0x00000b1f, 0x00000b2c, 0x00000b3c, 0x00000b5d, - 0x00000b73, 0x00000b7a, 0x00000b81, 0x00000b8c, - 0x00000b93, 0x00000ba0, 0x00000ba4, 0x00000ba8, + 0x00000a16, 0x00000a1d, 0x00000a2a, 0x00000a31, + 0x00000a3d, 0x00000a49, 0x00000a55, 0x00000a5c, + 0x00000a69, 0x00000a75, 0x00000a88, 0x00000a95, + 0x00000ac3, 0x00000ad0, 0x00000add, 0x00000aea, + 0x00000af7, 0x00000b04, 0x00000b11, 0x00000b1e, + 0x00000b2b, 0x00000b38, 0x00000b48, 0x00000b69, + 0x00000b7f, 0x00000b86, 0x00000b8d, 0x00000b98, + 0x00000b9f, 0x00000bac, 0x00000bb0, 0x00000bb4, // Entry C0 - DF - 0x00000baf, 0x00000bb6, 0x00000bc3, 0x00000bcd, - 0x00000bda, 0x00000be7, 0x00000bee, 0x00000bfb, - 0x00000c02, 0x00000c09, 0x00000c10, 0x00000c28, - 0x00000c4f, 0x00000c56, 0x00000c63, 0x00000c6a, - 0x00000c77, 0x00000c7e, 0x00000c88, 0x00000cf6, - 0x00000d06, 0x00000d13, 0x00000d1a, 0x00000d30, - 0x00000d61, 0x00000d6e, 0x00000d78, 0x00000dc8, - 0x00000dd8, 0x00000deb, 0x00000df8, 0x00000e05, + 0x00000bbb, 0x00000bc2, 0x00000bcf, 0x00000bd9, + 0x00000be6, 0x00000bf3, 0x00000bfa, 0x00000c07, + 0x00000c0e, 0x00000c15, 0x00000c1c, 0x00000c34, + 0x00000c5b, 0x00000c62, 0x00000c6f, 0x00000c76, + 0x00000c83, 0x00000c8a, 0x00000c94, 0x00000d02, + 0x00000d12, 0x00000d1f, 0x00000d26, 0x00000d3c, + 0x00000d6d, 0x00000d7a, 0x00000d84, 0x00000dd4, + 0x00000de4, 0x00000df7, 0x00000e04, 0x00000e11, // Entry E0 - FF - 0x00000e18, 0x00000e25, 0x00000e32, 0x00000e3f, - 0x00000e4c, 0x00000e5e, 0x00000e65, 0x00000e78, - 0x00000e85, 0x00000e8c, 0x00000e9f, 0x00000ed2, - 0x00000eea, 0x00000f11, 0x00000f29, 0x00000f50, - 0x00000f57, 0x00000f6a, 0x00000f78, 0x00000fa5, - 0x00000fb5, 0x00000fc2, 0x00000fe3, 0x00000fea, - 0x00000ff7, 0x00001025, 0x00001038, 0x0000105a, - 0x00001067, 0x00001099, 0x000010c9, 0x000010ee, + 0x00000e24, 0x00000e31, 0x00000e3e, 0x00000e4b, + 0x00000e58, 0x00000e6a, 0x00000e71, 0x00000e84, + 0x00000e91, 0x00000e98, 0x00000eab, 0x00000ede, + 0x00000ef6, 0x00000f1d, 0x00000f35, 0x00000f5c, + 0x00000f63, 0x00000f76, 0x00000f84, 0x00000fb1, + 0x00000fc1, 0x00000fce, 0x00000fef, 0x00000ff6, + 0x00001003, 0x00001031, 0x00001044, 0x00001066, + 0x00001073, 0x000010a5, 0x000010d5, 0x000010fa, // Entry 100 - 11F - 0x000010f8, 0x00001117, 0x00001127, + 0x00001104, 0x00001123, 0x00001133, } // Size: 1060 bytes -const zh_CNData string = "" + // Size: 4391 bytes +const zh_CNData string = "" + // Size: 4403 bytes "\x02版本:%[1]s\x02FRP 版本:%[1]s\x02构建日期:%[1]s\x02所有文件\x02配置文件\x02证书文件\x02密钥" + "文件\x02日志文件\x02数值超出允许范围\x02请输入一个大于 %[1]d 的数字。\x02密码不匹配\x02请检查并重试。\x02不是" + "数字\x02请输入一个有效的数字。\x02发现更新!\x02关于\x02下载更新\x02正在检查更新\x02检查更新\x02如有任何意见或报" + @@ -979,14 +980,14 @@ const zh_CNData string = "" + // Size: 4391 bytes "\x02自动删除\x02绝对\x02相对\x02删除日期\x02删除天数\x02天\x02连接\x02协议\x02HTTP 代理\x02连接池数" + "量\x02UDP 包大小\x02心跳\x02间隔\x02秒\x02超时\x02连接超时\x02保活周期\x02闲置超时\x02最大流数量" + "\x02开启\x02关闭\x02主机名称\x02证书文件\x02选择证书文件\x02密钥文件\x02选择证书密钥文件\x02受信任证书\x02选" + - "择受信任的证书\x02禁用自定义首字节\x02高级\x02多路复用\x02复用器心跳\x02使用源地址\x02初次登录失败后退出\x02禁用" + - "开机自启动\x02元数据\x02实验性功能\x02* 以下功能可能会影响服务的稳定性。\x02使用服务器 SVCB 记录\x02配置已存在" + - "\x02配置名「%[1]s」已存在。\x02新建代理\x02编辑代理 - %[1]s\x02随机名称\x02类型\x02角色\x02服务端" + - "\x02访问者\x02私钥\x02本地地址\x02本地端口\x02远程端口\x02允许用户\x02绑定地址\x02绑定端口\x02服务名称" + - "\x02服务用户\x02子域名\x02自定义域名\x02URL 路由\x02请求头\x02复用器\x02路由用户\x02客户端\x02带宽限流" + - "\x02代理协议\x02自动\x02默认\x02隧道保活\x02加密传输\x02压缩传输\x02重试次数\x02次/小时\x02重试间隔\x02" + - "备用\x02备用超时\x02毫秒\x02HTTP 用户\x02HTTP 密码\x02Host 替换\x02插件\x02插件名称\x02Uni" + - "x 路径\x02选择 Unix 路径\x02本地路径\x02选择需要显示目录列表的文件夹。\x02移除前缀\x02负载均衡\x02分组名称" + + "择受信任的证书\x02禁用自定义首字节\x02高级\x02使用源地址\x02多路复用\x02初次登录失败后退出\x02禁用开机自启动\x02" + + "使用旧格式配置文件\x02元数据\x02实验性功能\x02* 以下功能可能会影响服务的稳定性。\x02使用服务器 SVCB 记录\x02配置" + + "已存在\x02配置名「%[1]s」已存在。\x02新建代理\x02编辑代理 - %[1]s\x02随机名称\x02类型\x02角色\x02服" + + "务端\x02访问者\x02私钥\x02本地地址\x02本地端口\x02远程端口\x02允许用户\x02绑定地址\x02绑定端口\x02服务名" + + "称\x02服务用户\x02子域名\x02自定义域名\x02URL 路由\x02请求头\x02复用器\x02路由用户\x02客户端\x02带宽" + + "限流\x02代理协议\x02自动\x02默认\x02隧道保活\x02加密传输\x02压缩传输\x02重试次数\x02次/小时\x02重试间隔" + + "\x02备用\x02备用超时\x02毫秒\x02HTTP 用户\x02HTTP 密码\x02Host 替换\x02插件\x02插件名称\x02U" + + "nix 路径\x02选择 Unix 路径\x02本地路径\x02选择需要显示目录列表的文件夹。\x02移除前缀\x02负载均衡\x02分组名称" + "\x02分组密钥\x02健康检查\x02检查类型\x02检查超时\x02错误次数\x02检查周期\x02代理已存在\x02代理名「%[1]s」已" + "存在。\x02打开日志文件夹\x02最新\x02项目\x02NAT 类型\x02行为\x02外部地址\x02是\x02否\x02公网\x02" + "未知\x02正在运行\x02已停止\x02正在启动\x02正在停止\x02状态\x02远程地址\x02复制\x02启动\x02服务\x02停" + @@ -994,9 +995,9 @@ const zh_CNData string = "" + // Size: 4391 bytes "码\x02您可以设置密码来限制访问此程序。\x0a在下次使用此程序时,您将被要求输入密码。\x02使用主密码\x02修改密码\x02语言" + "\x02目前的显示语言\x02您必须重新启动程序才能应用修改。\x02选择语言\x02默认值\x02定义新建配置时的默认值。\x0a此处的值不会" + "影响现有的配置。\x02设置默认值\x02密码已删除。\x02新主密码\x02确认密码\x02密码已设定。\x02日志级别\x02日志保留" + - "\x02快速添加\x02远程桌面\x02HTTP 文件服务\x02启用\x02打开配置文件\x02直接编辑\x02域名\x02复制访问地址" + + "\x02快速添加\x02远程桌面\x02HTTP 文件服务\x02禁用\x02打开配置文件\x02直接编辑\x02域名\x02复制访问地址" + "\x02此功能仅支持 INI 或 TOML 格式的文本。\x02删除代理「%[1]s」\x02确定要删除代理「%[1]s」吗?\x02禁用代理「" + - "%[1]s」\x02确定要禁用代理「%[1]s」吗?\x02禁用\x02被动端口范围\x02FRP 管理器\x02* 支持批量导入,每行一个链接" + + "%[1]s」\x02确定要禁用代理「%[1]s」吗?\x02启用\x02被动端口范围\x02FRP 管理器\x02* 支持批量导入,每行一个链接" + "。\x02自动重命名\x02准备就绪\x02请输入正确的 URL 列表。\x02下载\x02输入密码\x02您必须输入管理密码来使用 %[1" + "]s。\x02输入管理密码\x02密码错误。请重新输入。\x02输入无效\x02请输入一个从 %.[1]f 到 %.[2]f 的数字。\x02请" + "输入一个从 %[1]s 到 %[2]s 的数字。\x02文本与要求的模式不匹配。\x02必填项\x02请选择其中一个选项。\x02需要选择。" @@ -1035,50 +1036,50 @@ var zh_TWIndex = []uint32{ // 259 elements 0x000006d3, 0x000006e3, 0x000006ea, 0x000006f1, 0x000006fe, 0x0000070b, 0x0000071e, 0x0000072b, 0x00000744, 0x00000754, 0x0000076d, 0x00000783, - 0x0000078a, 0x00000797, 0x000007a7, 0x000007b7, - 0x000007d3, 0x000007e9, 0x000007f3, 0x00000803, - 0x00000836, 0x00000852, 0x00000862, 0x00000883, + 0x0000078a, 0x0000079a, 0x000007a7, 0x000007c3, + 0x000007d9, 0x000007f2, 0x000007fc, 0x0000080c, + 0x0000083f, 0x0000085b, 0x0000086b, 0x0000088c, // Entry 80 - 9F - 0x00000890, 0x000008a5, 0x000008b2, 0x000008b9, - 0x000008c0, 0x000008ca, 0x000008d4, 0x000008db, - 0x000008e8, 0x000008f5, 0x00000902, 0x0000090f, - 0x0000091c, 0x00000929, 0x00000936, 0x00000943, - 0x0000094d, 0x0000095d, 0x00000968, 0x00000972, - 0x0000097c, 0x00000989, 0x00000993, 0x000009a0, - 0x000009ad, 0x000009b4, 0x000009bb, 0x000009c8, - 0x000009d5, 0x000009e2, 0x000009ef, 0x000009fa, + 0x00000899, 0x000008ae, 0x000008bb, 0x000008c2, + 0x000008c9, 0x000008d3, 0x000008dd, 0x000008e4, + 0x000008f1, 0x000008fe, 0x0000090b, 0x00000918, + 0x00000925, 0x00000932, 0x0000093f, 0x0000094c, + 0x00000956, 0x00000966, 0x00000971, 0x0000097b, + 0x00000985, 0x00000992, 0x0000099c, 0x000009a9, + 0x000009b6, 0x000009bd, 0x000009c4, 0x000009d1, + 0x000009de, 0x000009eb, 0x000009f8, 0x00000a03, // Entry A0 - BF - 0x00000a07, 0x00000a0e, 0x00000a1b, 0x00000a22, - 0x00000a2e, 0x00000a3a, 0x00000a46, 0x00000a4d, - 0x00000a5a, 0x00000a66, 0x00000a79, 0x00000a86, - 0x00000ab4, 0x00000ac1, 0x00000ace, 0x00000adb, - 0x00000ae8, 0x00000af5, 0x00000b02, 0x00000b0f, - 0x00000b1c, 0x00000b29, 0x00000b39, 0x00000b5a, - 0x00000b70, 0x00000b77, 0x00000b7e, 0x00000b89, - 0x00000b90, 0x00000b9d, 0x00000ba1, 0x00000ba5, + 0x00000a10, 0x00000a17, 0x00000a24, 0x00000a2b, + 0x00000a37, 0x00000a43, 0x00000a4f, 0x00000a56, + 0x00000a63, 0x00000a6f, 0x00000a82, 0x00000a8f, + 0x00000abd, 0x00000aca, 0x00000ad7, 0x00000ae4, + 0x00000af1, 0x00000afe, 0x00000b0b, 0x00000b18, + 0x00000b25, 0x00000b32, 0x00000b42, 0x00000b63, + 0x00000b79, 0x00000b80, 0x00000b87, 0x00000b92, + 0x00000b99, 0x00000ba6, 0x00000baa, 0x00000bae, // Entry C0 - DF - 0x00000bac, 0x00000bb3, 0x00000bc0, 0x00000bca, - 0x00000bd7, 0x00000be4, 0x00000beb, 0x00000bf8, - 0x00000bff, 0x00000c06, 0x00000c0d, 0x00000c25, - 0x00000c4c, 0x00000c53, 0x00000c60, 0x00000c67, - 0x00000c74, 0x00000c7b, 0x00000c85, 0x00000cf3, - 0x00000d03, 0x00000d10, 0x00000d17, 0x00000d2d, - 0x00000d5e, 0x00000d6b, 0x00000d75, 0x00000dc5, - 0x00000dd5, 0x00000de8, 0x00000df5, 0x00000e02, + 0x00000bb5, 0x00000bbc, 0x00000bc9, 0x00000bd3, + 0x00000be0, 0x00000bed, 0x00000bf4, 0x00000c01, + 0x00000c08, 0x00000c0f, 0x00000c16, 0x00000c2e, + 0x00000c55, 0x00000c5c, 0x00000c69, 0x00000c70, + 0x00000c7d, 0x00000c84, 0x00000c8e, 0x00000cfc, + 0x00000d0c, 0x00000d19, 0x00000d20, 0x00000d36, + 0x00000d67, 0x00000d74, 0x00000d7e, 0x00000dce, + 0x00000dde, 0x00000df1, 0x00000dfe, 0x00000e0b, // Entry E0 - FF - 0x00000e15, 0x00000e22, 0x00000e2f, 0x00000e3c, - 0x00000e49, 0x00000e5b, 0x00000e62, 0x00000e75, - 0x00000e82, 0x00000e89, 0x00000e9c, 0x00000ecf, - 0x00000ee7, 0x00000f0e, 0x00000f26, 0x00000f4d, - 0x00000f54, 0x00000f67, 0x00000f75, 0x00000fa2, - 0x00000fb2, 0x00000fbf, 0x00000fe0, 0x00000fe7, - 0x00000ff4, 0x00001022, 0x00001035, 0x00001057, - 0x00001064, 0x00001096, 0x000010c6, 0x000010eb, + 0x00000e1e, 0x00000e2b, 0x00000e38, 0x00000e45, + 0x00000e52, 0x00000e64, 0x00000e6b, 0x00000e7e, + 0x00000e8b, 0x00000e92, 0x00000ea5, 0x00000ed8, + 0x00000ef0, 0x00000f17, 0x00000f2f, 0x00000f56, + 0x00000f5d, 0x00000f70, 0x00000f7e, 0x00000fab, + 0x00000fbb, 0x00000fc8, 0x00000fe9, 0x00000ff0, + 0x00000ffd, 0x0000102b, 0x0000103e, 0x00001060, + 0x0000106d, 0x0000109f, 0x000010cf, 0x000010f4, // Entry 100 - 11F - 0x000010f5, 0x00001114, 0x00001124, + 0x000010fe, 0x0000111d, 0x0000112d, } // Size: 1060 bytes -const zh_TWData string = "" + // Size: 4388 bytes +const zh_TWData string = "" + // Size: 4397 bytes "\x02版本:%[1]s\x02FRP 版本:%[1]s\x02構建日期:%[1]s\x02所有文件\x02配置文件\x02證書文件\x02密鑰" + "文件\x02日誌文件\x02數值超出允許範圍\x02請輸入一個大於 %[1]d 的數字。\x02密碼不匹配\x02請檢查並重試。\x02不是" + "數字\x02請輸入一個有效的數字。\x02發現更新!\x02關於\x02下載更新\x02正在檢查更新\x02檢查更新\x02如有任何意見或報" + @@ -1095,9 +1096,9 @@ const zh_TWData string = "" + // Size: 4388 bytes "\x02自動刪除\x02絕對\x02相對\x02刪除日期\x02刪除天數\x02天\x02連接\x02協議\x02HTTP 代理\x02連接池數" + "量\x02UDP 包大小\x02心跳\x02間隔\x02秒\x02超時\x02連接超時\x02保活週期\x02閒置超時\x02最大流數量" + "\x02開啟\x02關閉\x02主機名稱\x02證書文件\x02選擇證書文件\x02密鑰文件\x02選擇證書密鑰文件\x02受信任證書\x02選" + - "擇受信任的證書\x02停用自訂首字節\x02高級\x02多路復用\x02復用器心跳\x02使用源地址\x02初次登錄失敗後退出\x02禁用開" + - "機自啟動\x02元數據\x02實驗性功能\x02* 以下功能可能會影響服務的穩定性。\x02使用服務器 SVCB 記錄\x02配置已存在" + - "\x02配置名「%[1]s」已存在。\x02新建代理\x02編輯代理 - %[1]s\x02隨機名稱\x02類型\x02角色\x02服務端" + + "擇受信任的證書\x02停用自訂首字節\x02高級\x02使用源地址\x02多路復用\x02初次登錄失敗後退出\x02禁用開機自啟動\x02使" + + "用舊格式設定檔\x02元數據\x02實驗性功能\x02* 以下功能可能會影響服務的穩定性。\x02使用服務器 SVCB 記錄\x02配置已存" + + "在\x02配置名「%[1]s」已存在。\x02新建代理\x02編輯代理 - %[1]s\x02隨機名稱\x02類型\x02角色\x02服務端" + "\x02訪問者\x02私鑰\x02本地地址\x02本地端口\x02遠程端口\x02允許用戶\x02綁定地址\x02綁定端口\x02服務名稱" + "\x02服務用戶\x02子域名\x02自定義域名\x02URL 路由\x02請求頭\x02復用器\x02路由用戶\x02客戶端\x02帶寬限流" + "\x02代理協議\x02自動\x02默認\x02隧道保活\x02加密傳輸\x02壓縮傳輸\x02重試次數\x02次/小時\x02重試間隔\x02" + @@ -1110,11 +1111,11 @@ const zh_TWData string = "" + // Size: 4388 bytes "碼\x02您可以設置密碼來限制訪問此程式。\x0a在下次使用此程式時,您將被要求輸入密碼。\x02使用主密碼\x02修改密碼\x02語言" + "\x02目前的顯示語言\x02您必須重新啟動程式才能應用修改。\x02選擇語言\x02默認值\x02定義新建配置時的默認值。\x0a此處的值不會" + "影響現有的配置。\x02設置默認值\x02密碼已刪除。\x02新主密碼\x02確認密碼\x02密碼已設定。\x02日誌級別\x02日誌保留" + - "\x02快速添加\x02遠程桌面\x02HTTP 文件服務\x02啟用\x02打開配置文件\x02直接編輯\x02域名\x02複製訪問地址" + + "\x02快速添加\x02遠程桌面\x02HTTP 文件服務\x02禁用\x02打開配置文件\x02直接編輯\x02域名\x02複製訪問地址" + "\x02此功能僅支援 INI 或 TOML 格式的文字。\x02刪除代理「%[1]s」\x02確定要刪除代理「%[1]s」嗎?\x02禁用代理「" + - "%[1]s」\x02確定要禁用代理「%[1]s」嗎?\x02禁用\x02被動端口範圍\x02FRP 管理器\x02* 支持批量導入,每行一個鏈接" + + "%[1]s」\x02確定要禁用代理「%[1]s」嗎?\x02啟用\x02被動端口範圍\x02FRP 管理器\x02* 支持批量導入,每行一個鏈接" + "。\x02自動重命名\x02準備就緒\x02請輸入正確的 URL 列表。\x02下載\x02輸入密碼\x02您必須輸入管理密碼來使用 %[1" + "]s。\x02輸入管理密碼\x02密碼錯誤。請重新輸入。\x02輸入無效\x02請輸入一個從 %.[1]f 到 %.[2]f 的數字。\x02請" + "輸入一個從 %[1]s 到 %[2]s 的數字。\x02文本與要求的模式不匹配。\x02必填項\x02請選擇其中一個選項。\x02需要選擇。" - // Total table size 38103 bytes (37KiB); checksum: 78CF4E2B + // Total table size 38221 bytes (37KiB); checksum: 49783779 diff --git a/i18n/locales/en-US/messages.gotext.json b/i18n/locales/en-US/messages.gotext.json index d9831863..4913e89b 100644 --- a/i18n/locales/en-US/messages.gotext.json +++ b/i18n/locales/en-US/messages.gotext.json @@ -932,23 +932,16 @@ "fuzzy": true }, { - "id": "TCP Mux", - "message": "TCP Mux", - "translation": "TCP Mux", - "translatorComment": "Copied from source.", - "fuzzy": true - }, - { - "id": "Mux Keepalive", - "message": "Mux Keepalive", - "translation": "Mux Keepalive", + "id": "Source Address", + "message": "Source Address", + "translation": "Source Address", "translatorComment": "Copied from source.", "fuzzy": true }, { - "id": "Source Address", - "message": "Source Address", - "translation": "Source Address", + "id": "TCP Mux", + "message": "TCP Mux", + "translation": "TCP Mux", "translatorComment": "Copied from source.", "fuzzy": true }, @@ -966,6 +959,13 @@ "translatorComment": "Copied from source.", "fuzzy": true }, + { + "id": "Use legacy format config file", + "message": "Use legacy format config file", + "translation": "Use legacy format config file", + "translatorComment": "Copied from source.", + "fuzzy": true + }, { "id": "Metadata", "message": "Metadata", @@ -1773,9 +1773,9 @@ "fuzzy": true }, { - "id": "Enable", - "message": "Enable", - "translation": "Enable", + "id": "Disable", + "message": "Disable", + "translation": "Disable", "translatorComment": "Copied from source.", "fuzzy": true }, @@ -1883,9 +1883,9 @@ "fuzzy": true }, { - "id": "Disable", - "message": "Disable", - "translation": "Disable", + "id": "Enable", + "message": "Enable", + "translation": "Enable", "translatorComment": "Copied from source.", "fuzzy": true }, diff --git a/i18n/locales/es-ES/messages.gotext.json b/i18n/locales/es-ES/messages.gotext.json index d78a655b..a4cf791c 100644 --- a/i18n/locales/es-ES/messages.gotext.json +++ b/i18n/locales/es-ES/messages.gotext.json @@ -699,21 +699,16 @@ "message": "Advanced", "translation": "Avanzado" }, - { - "id": "TCP Mux", - "message": "TCP Mux", - "translation": "Mux TCP" - }, - { - "id": "Mux Keepalive", - "message": "Mux Keepalive", - "translation": "Mux Keepalive" - }, { "id": "Source Address", "message": "Source Address", "translation": "Dirección de la fuente" }, + { + "id": "TCP Mux", + "message": "TCP Mux", + "translation": "Mux TCP" + }, { "id": "Exit after login failure", "message": "Exit after login failure", @@ -724,6 +719,11 @@ "message": "Disable auto-start at boot", "translation": "Desactivar el inicio automático al arrancar" }, + { + "id": "Use legacy format config file", + "message": "Use legacy format config file", + "translation": "Usar archivo de configuración de formato heredado" + }, { "id": "Metadata", "message": "Metadata", @@ -1315,9 +1315,9 @@ "translation": "Servidor de archivos HTTP" }, { - "id": "Enable", - "message": "Enable", - "translation": "Habilitar" + "id": "Disable", + "message": "Disable", + "translation": "Deshabilitar" }, { "id": "Open Config", @@ -1405,9 +1405,9 @@ ] }, { - "id": "Disable", - "message": "Disable", - "translation": "Deshabilitar" + "id": "Enable", + "message": "Enable", + "translation": "Habilitar" }, { "id": "Passive Port Range", diff --git a/i18n/locales/ja-JP/messages.gotext.json b/i18n/locales/ja-JP/messages.gotext.json index a94a91a2..cddbbc8b 100644 --- a/i18n/locales/ja-JP/messages.gotext.json +++ b/i18n/locales/ja-JP/messages.gotext.json @@ -709,21 +709,16 @@ "message": "Advanced", "translation": "高度" }, - { - "id": "TCP Mux", - "message": "TCP Mux", - "translation": "多重化" - }, - { - "id": "Mux Keepalive", - "message": "Mux Keepalive", - "translation": "多重化接続を維持" - }, { "id": "Source Address", "message": "Source Address", "translation": "送信元アドレス" }, + { + "id": "TCP Mux", + "message": "TCP Mux", + "translation": "多重化" + }, { "id": "Exit after login failure", "message": "Exit after login failure", @@ -734,6 +729,11 @@ "message": "Disable auto-start at boot", "translation": "起動時に自動起動を無効にする" }, + { + "id": "Use legacy format config file", + "message": "Use legacy format config file", + "translation": "従来の形式の設定ファイルを使用する" + }, { "id": "Metadata", "message": "Metadata", @@ -1325,9 +1325,9 @@ "translation": "HTTP ファイルサーバー" }, { - "id": "Enable", - "message": "Enable", - "translation": "有効" + "id": "Disable", + "message": "Disable", + "translation": "無効" }, { "id": "Open Config", @@ -1415,9 +1415,9 @@ ] }, { - "id": "Disable", - "message": "Disable", - "translation": "無効" + "id": "Enable", + "message": "Enable", + "translation": "有効" }, { "id": "Passive Port Range", diff --git a/i18n/locales/ko-KR/messages.gotext.json b/i18n/locales/ko-KR/messages.gotext.json index c04f30bd..13f091e2 100644 --- a/i18n/locales/ko-KR/messages.gotext.json +++ b/i18n/locales/ko-KR/messages.gotext.json @@ -699,21 +699,16 @@ "message": "Advanced", "translation": "고급의" }, - { - "id": "TCP Mux", - "message": "TCP Mux", - "translation": "다중화" - }, - { - "id": "Mux Keepalive", - "message": "Mux Keepalive", - "translation": "다중화 대기 중" - }, { "id": "Source Address", "message": "Source Address", "translation": "소스 주소" }, + { + "id": "TCP Mux", + "message": "TCP Mux", + "translation": "다중화" + }, { "id": "Exit after login failure", "message": "Exit after login failure", @@ -724,6 +719,11 @@ "message": "Disable auto-start at boot", "translation": "부팅 시 자동 시작 비활성화" }, + { + "id": "Use legacy format config file", + "message": "Use legacy format config file", + "translation": "레거시 형식 구성 파일 사용" + }, { "id": "Metadata", "message": "Metadata", @@ -1315,9 +1315,9 @@ "translation": "HTTP 파일 서버" }, { - "id": "Enable", - "message": "Enable", - "translation": "켜다" + "id": "Disable", + "message": "Disable", + "translation": "폐쇄" }, { "id": "Open Config", @@ -1405,9 +1405,9 @@ ] }, { - "id": "Disable", - "message": "Disable", - "translation": "폐쇄" + "id": "Enable", + "message": "Enable", + "translation": "켜다" }, { "id": "Passive Port Range", diff --git a/i18n/locales/zh-CN/messages.gotext.json b/i18n/locales/zh-CN/messages.gotext.json index 5276ba8c..321e7fa1 100644 --- a/i18n/locales/zh-CN/messages.gotext.json +++ b/i18n/locales/zh-CN/messages.gotext.json @@ -699,21 +699,16 @@ "message": "Advanced", "translation": "高级" }, - { - "id": "TCP Mux", - "message": "TCP Mux", - "translation": "多路复用" - }, - { - "id": "Mux Keepalive", - "message": "Mux Keepalive", - "translation": "复用器心跳" - }, { "id": "Source Address", "message": "Source Address", "translation": "使用源地址" }, + { + "id": "TCP Mux", + "message": "TCP Mux", + "translation": "多路复用" + }, { "id": "Exit after login failure", "message": "Exit after login failure", @@ -724,6 +719,11 @@ "message": "Disable auto-start at boot", "translation": "禁用开机自启动" }, + { + "id": "Use legacy format config file", + "message": "Use legacy format config file", + "translation": "使用旧格式配置文件" + }, { "id": "Metadata", "message": "Metadata", @@ -1315,9 +1315,9 @@ "translation": "HTTP 文件服务" }, { - "id": "Enable", - "message": "Enable", - "translation": "启用" + "id": "Disable", + "message": "Disable", + "translation": "禁用" }, { "id": "Open Config", @@ -1405,9 +1405,9 @@ ] }, { - "id": "Disable", - "message": "Disable", - "translation": "禁用" + "id": "Enable", + "message": "Enable", + "translation": "启用" }, { "id": "Passive Port Range", diff --git a/i18n/locales/zh-TW/messages.gotext.json b/i18n/locales/zh-TW/messages.gotext.json index 5fcd7dd8..8f8d76a9 100644 --- a/i18n/locales/zh-TW/messages.gotext.json +++ b/i18n/locales/zh-TW/messages.gotext.json @@ -699,21 +699,16 @@ "message": "Advanced", "translation": "高級" }, - { - "id": "TCP Mux", - "message": "TCP Mux", - "translation": "多路復用" - }, - { - "id": "Mux Keepalive", - "message": "Mux Keepalive", - "translation": "復用器心跳" - }, { "id": "Source Address", "message": "Source Address", "translation": "使用源地址" }, + { + "id": "TCP Mux", + "message": "TCP Mux", + "translation": "多路復用" + }, { "id": "Exit after login failure", "message": "Exit after login failure", @@ -724,6 +719,11 @@ "message": "Disable auto-start at boot", "translation": "禁用開機自啟動" }, + { + "id": "Use legacy format config file", + "message": "Use legacy format config file", + "translation": "使用舊格式設定檔" + }, { "id": "Metadata", "message": "Metadata", @@ -1315,9 +1315,9 @@ "translation": "HTTP 文件服務" }, { - "id": "Enable", - "message": "Enable", - "translation": "啟用" + "id": "Disable", + "message": "Disable", + "translation": "禁用" }, { "id": "Open Config", @@ -1405,9 +1405,9 @@ ] }, { - "id": "Disable", - "message": "Disable", - "translation": "禁用" + "id": "Enable", + "message": "Enable", + "translation": "啟用" }, { "id": "Passive Port Range", diff --git a/pkg/config/client.go b/pkg/config/client.go index 6b2c132d..f01926d3 100644 --- a/pkg/config/client.go +++ b/pkg/config/client.go @@ -10,6 +10,7 @@ import ( "github.com/fatedier/frp/pkg/config" "github.com/fatedier/frp/pkg/config/v1" frputil "github.com/fatedier/frp/pkg/util/util" + "github.com/pelletier/go-toml/v2" "github.com/samber/lo" "gopkg.in/ini.v1" @@ -66,7 +67,7 @@ type ClientCommon struct { v1.APIMetadata `ini:"-"` ClientAuth `ini:",extends"` ServerAddress string `ini:"server_addr,omitempty"` - ServerPort string `ini:"server_port,omitempty"` + ServerPort int `ini:"server_port,omitempty"` NatHoleSTUNServer string `ini:"nat_hole_stun_server,omitempty"` DialServerTimeout int64 `ini:"dial_server_timeout,omitempty"` DialServerKeepAlive int64 `ini:"dial_server_keepalive,omitempty"` @@ -74,14 +75,14 @@ type ClientCommon struct { HTTPProxy string `ini:"http_proxy,omitempty"` LogFile string `ini:"log_file,omitempty"` LogLevel string `ini:"log_level,omitempty"` - LogMaxDays uint `ini:"log_max_days,omitempty"` + LogMaxDays int64 `ini:"log_max_days,omitempty"` AdminAddr string `ini:"admin_addr,omitempty"` - AdminPort string `ini:"admin_port,omitempty"` + AdminPort int `ini:"admin_port,omitempty"` AdminUser string `ini:"admin_user,omitempty"` AdminPwd string `ini:"admin_pwd,omitempty"` AdminTLS v1.TLSConfig `ini:"-"` AssetsDir string `ini:"assets_dir,omitempty"` - PoolCount uint `ini:"pool_count,omitempty"` + PoolCount int `ini:"pool_count,omitempty"` DNSServer string `ini:"dns_server,omitempty"` Protocol string `ini:"protocol,omitempty"` QUICKeepalivePeriod int `ini:"quic_keepalive_period,omitempty"` @@ -117,6 +118,8 @@ type ClientCommon struct { AutoDelete `ini:",extends"` // Client meta info Metas map[string]string `ini:"-"` + // Config file format + LegacyFormat bool `ini:"-"` } // BaseProxyConf provides configuration info that is common to all types. @@ -216,7 +219,7 @@ type Proxy struct { ServerUser string `ini:"server_user,omitempty" visitor:"*"` ServerName string `ini:"server_name,omitempty" visitor:"*"` BindAddr string `ini:"bind_addr,omitempty" visitor:"*"` - BindPort string `ini:"bind_port,omitempty" visitor:"*"` + BindPort int `ini:"bind_port,omitempty" visitor:"*"` CustomDomains string `ini:"custom_domains,omitempty" http:"true" https:"true" tcpmux:"true"` SubDomain string `ini:"subdomain,omitempty" http:"true" https:"true" tcpmux:"true"` Locations string `ini:"locations,omitempty" http:"true"` @@ -376,6 +379,14 @@ func (conf *ClientConfig) AddItem(item interface{}) bool { } func (conf *ClientConfig) Save(path string) error { + if conf.LegacyFormat { + return conf.saveINI(path) + } else { + return conf.saveTOML(path) + } +} + +func (conf *ClientConfig) saveINI(path string) error { cfg := ini.Empty() common, err := cfg.NewSection("common") if err != nil { @@ -411,10 +422,41 @@ func (conf *ClientConfig) Save(path string) error { return cfg.SaveTo(path) } +func (conf *ClientConfig) saveTOML(path string) error { + c := ClientConfigV1{ + ClientCommonConfig: ClientCommonToV1(&conf.ClientCommon), + Internal: Internal{ + ManualStart: conf.ManualStart, + SVCBEnable: conf.SVCBEnable, + AutoDelete: conf.AutoDelete, + }, + } + for _, v := range conf.Proxies { + if v.IsVisitor() { + c.Visitors = append(c.Visitors, ClientVisitorToV1(v)) + } else { + p, err := ClientProxyToV1(v) + if err != nil { + return err + } + c.Proxies = append(c.Proxies, p) + } + } + obj, err := toMap(&c, "json") + if err != nil { + return err + } + b, err := toml.Marshal(obj) + if err != nil { + return err + } + return os.WriteFile(path, b, 0666) +} + func (conf *ClientConfig) Complete(read bool) { // Common config conf.ClientAuth = conf.ClientAuth.Complete() - if conf.AdminPort == "" { + if conf.AdminPort == 0 { conf.AdminUser = "" conf.AdminPwd = "" conf.AssetsDir = "" @@ -565,6 +607,7 @@ func UnmarshalClientConfFromIni(source interface{}) (*ClientConfig, error) { conf.Proxies = append(conf.Proxies, proxy) } conf.Complete(true) + conf.LegacyFormat = true return conf, nil } @@ -587,7 +630,7 @@ func UnmarshalClientConf(source interface{}) (*ClientConfig, error) { return nil, err } var r ClientConfig - r.ClientCommon = ClientCommonFromV1(cfg.ClientCommonConfig) + r.ClientCommon = ClientCommonFromV1(&cfg.ClientCommonConfig) r.ManualStart = cfg.Internal.ManualStart r.SVCBEnable = cfg.Internal.SVCBEnable r.AutoDelete = cfg.Internal.AutoDelete @@ -604,7 +647,7 @@ func NewDefaultClientConfig() *ClientConfig { return &ClientConfig{ ClientCommon: ClientCommon{ ClientAuth: ClientAuth{AuthMethod: consts.AuthToken}, - ServerPort: "7000", + ServerPort: 7000, LogLevel: "info", TCPMux: true, TLSEnable: true, diff --git a/pkg/config/conf.go b/pkg/config/conf.go index 3658fe6e..2b8a5de2 100644 --- a/pkg/config/conf.go +++ b/pkg/config/conf.go @@ -49,7 +49,7 @@ type AutoDelete struct { // is calculated by adding the days to the file modification time. If it's empty, the config has no expiry date. DeleteMethod string `ini:"frpmgr_delete_method,omitempty" json:"method,omitempty"` // DeleteAfterDays is the number of days a config will be kept, after which it may be stopped and deleted. - DeleteAfterDays uint `ini:"frpmgr_delete_after_days,omitempty" relative:"true" json:"afterDays,omitempty"` + DeleteAfterDays int64 `ini:"frpmgr_delete_after_days,omitempty" relative:"true" json:"afterDays,omitempty"` // DeleteAfterDate is the last date the config will be valid, after which it may be stopped and deleted. DeleteAfterDate time.Time `ini:"frpmgr_delete_after_date,omitempty" absolute:"true" json:"afterDate,omitempty"` } diff --git a/pkg/config/conversion.go b/pkg/config/conversion.go index 1c7be6bb..3d8fac18 100644 --- a/pkg/config/conversion.go +++ b/pkg/config/conversion.go @@ -1,14 +1,20 @@ package config import ( + "fmt" + "reflect" "strconv" "strings" + "time" + "github.com/fatedier/frp/pkg/config/types" "github.com/fatedier/frp/pkg/config/v1" "github.com/samber/lo" + + "github.com/koho/frpmgr/pkg/consts" ) -func ClientCommonFromV1(c v1.ClientCommonConfig) (r ClientCommon) { +func ClientCommonFromV1(c *v1.ClientCommonConfig) (r ClientCommon) { r.APIMetadata = c.APIMetadata // Auth client config @@ -29,9 +35,7 @@ func ClientCommonFromV1(c v1.ClientCommonConfig) (r ClientCommon) { r.User = c.User r.ServerAddress = c.ServerAddr - if c.ServerPort != 0 { - r.ServerPort = strconv.Itoa(c.ServerPort) - } + r.ServerPort = c.ServerPort r.NatHoleSTUNServer = c.NatHoleSTUNServer r.DNSServer = c.DNSServer if c.LoginFailExit == nil || *c.LoginFailExit { @@ -42,13 +46,11 @@ func ClientCommonFromV1(c v1.ClientCommonConfig) (r ClientCommon) { // Log r.LogFile = c.Log.To r.LogLevel = c.Log.Level - r.LogMaxDays = uint(c.Log.MaxDays) + r.LogMaxDays = c.Log.MaxDays // Admin r.AdminAddr = c.WebServer.Addr - if c.WebServer.Port != 0 { - r.AdminPort = strconv.Itoa(c.WebServer.Port) - } + r.AdminPort = c.WebServer.Port r.AdminUser = c.WebServer.User r.AdminPwd = c.WebServer.Password r.AssetsDir = c.WebServer.AssetsDir @@ -63,7 +65,7 @@ func ClientCommonFromV1(c v1.ClientCommonConfig) (r ClientCommon) { r.DialServerKeepAlive = c.Transport.DialServerKeepAlive r.ConnectServerLocalIP = c.Transport.ConnectServerLocalIP r.HTTPProxy = c.Transport.ProxyURL - r.PoolCount = uint(c.Transport.PoolCount) + r.PoolCount = c.Transport.PoolCount if c.Transport.TCPMux == nil || *c.Transport.TCPMux { r.TCPMux = true } @@ -177,7 +179,7 @@ func clientProxyBaseFromV1(c *v1.ProxyBaseConfig, out *Proxy) { out.PluginHttpPasswd = v.HTTPPassword case *v1.HTTPS2HTTPPluginOptions: out.PluginLocalAddr = v.LocalAddr - out.HostHeaderRewrite = v.HostHeaderRewrite + out.PluginHostHeaderRewrite = v.HostHeaderRewrite out.PluginCrtPath = v.CrtPath out.PluginKeyPath = v.KeyPath out.PluginHeaders = v.RequestHeaders.Set @@ -210,7 +212,409 @@ func clientVisitorBaseFromV1(c *v1.VisitorBaseConfig, out *Proxy) { out.ServerUser = c.ServerUser out.ServerName = c.ServerName out.BindAddr = c.BindAddr - if c.BindPort != 0 { - out.BindPort = strconv.Itoa(c.BindPort) + out.BindPort = c.BindPort +} + +func ClientCommonToV1(c *ClientCommon) (r v1.ClientCommonConfig) { + r.APIMetadata = c.APIMetadata + + // Auth client config + r.Auth = v1.AuthClientConfig{ + Method: v1.AuthMethod(c.AuthMethod), + Token: c.Token, + OIDC: v1.AuthOIDCClientConfig{ + ClientID: c.OIDCClientId, + ClientSecret: c.OIDCClientSecret, + Audience: c.OIDCAudience, + Scope: c.OIDCScope, + TokenEndpointURL: c.OIDCTokenEndpoint, + AdditionalEndpointParams: c.OIDCAdditionalEndpointParams, + }, + } + if c.AuthenticateHeartBeats { + r.Auth.AdditionalScopes = append(r.Auth.AdditionalScopes, v1.AuthScopeHeartBeats) + } + if c.AuthenticateNewWorkConns { + r.Auth.AdditionalScopes = append(r.Auth.AdditionalScopes, v1.AuthScopeNewWorkConns) + } + + r.User = c.User + r.ServerAddr = c.ServerAddress + r.ServerPort = c.ServerPort + r.NatHoleSTUNServer = c.NatHoleSTUNServer + r.DNSServer = c.DNSServer + r.LoginFailExit = &c.LoginFailExit + r.Start = c.Start + + // Log + r.Log = v1.LogConfig{ + To: c.LogFile, + Level: c.LogLevel, + MaxDays: c.LogMaxDays, + } + + // Admin + r.WebServer = v1.WebServerConfig{ + Addr: c.AdminAddr, + Port: c.AdminPort, + User: c.AdminUser, + Password: c.AdminPwd, + AssetsDir: c.AssetsDir, + PprofEnable: c.PprofEnable, + } + if lo.IsNotEmpty(c.AdminTLS) { + r.WebServer.TLS = &c.AdminTLS + } + + // Transport + r.Transport = v1.ClientTransportConfig{ + Protocol: c.Protocol, + DialServerTimeout: c.DialServerTimeout, + DialServerKeepAlive: c.DialServerKeepAlive, + ConnectServerLocalIP: c.ConnectServerLocalIP, + ProxyURL: c.HTTPProxy, + PoolCount: c.PoolCount, + TCPMux: &c.TCPMux, + TCPMuxKeepaliveInterval: c.TCPMuxKeepaliveInterval, + QUIC: v1.QUICOptions{ + KeepalivePeriod: c.QUICKeepalivePeriod, + MaxIdleTimeout: c.QUICMaxIdleTimeout, + MaxIncomingStreams: c.QUICMaxIncomingStreams, + }, + HeartbeatInterval: c.HeartbeatInterval, + HeartbeatTimeout: c.HeartbeatTimeout, + TLS: v1.TLSClientConfig{ + Enable: &c.TLSEnable, + DisableCustomTLSFirstByte: &c.DisableCustomTLSFirstByte, + TLSConfig: v1.TLSConfig{ + CertFile: c.TLSCertFile, + KeyFile: c.TLSKeyFile, + TrustedCaFile: c.TLSTrustedCaFile, + ServerName: c.TLSServerName, + }, + }, + } + r.UDPPacketSize = c.UDPPacketSize + r.Metadatas = c.Metas + return +} + +func ClientProxyToV1(p *Proxy) (v1.TypedProxyConfig, error) { + r := v1.TypedProxyConfig{Type: p.Type} + base, err := clientProxyBaseToV1(&p.BaseProxyConf) + if err != nil { + return r, err + } + switch r.Type { + case consts.ProxyTypeTCP: + c := &v1.TCPProxyConfig{ProxyBaseConfig: base} + if p.RemotePort != "" { + if c.RemotePort, err = strconv.Atoi(p.RemotePort); err != nil { + return r, err + } + } + r.ProxyConfigurer = c + case consts.ProxyTypeUDP: + c := &v1.UDPProxyConfig{ProxyBaseConfig: base} + if p.RemotePort != "" { + if c.RemotePort, err = strconv.Atoi(p.RemotePort); err != nil { + return r, err + } + } + r.ProxyConfigurer = c + case consts.ProxyTypeHTTP: + c := &v1.HTTPProxyConfig{ + ProxyBaseConfig: base, + DomainConfig: v1.DomainConfig{ + SubDomain: p.SubDomain, + }, + HTTPUser: p.HTTPUser, + HTTPPassword: p.HTTPPwd, + HostHeaderRewrite: p.HostHeaderRewrite, + RequestHeaders: v1.HeaderOperations{ + Set: p.Headers, + }, + RouteByHTTPUser: p.RouteByHTTPUser, + } + if p.CustomDomains != "" { + c.CustomDomains = strings.Split(p.CustomDomains, ",") + } + if p.Locations != "" { + c.Locations = strings.Split(p.Locations, ",") + } + r.ProxyConfigurer = c + case consts.ProxyTypeHTTPS: + c := &v1.HTTPSProxyConfig{ + ProxyBaseConfig: base, + DomainConfig: v1.DomainConfig{ + SubDomain: p.SubDomain, + }, + } + if p.CustomDomains != "" { + c.CustomDomains = strings.Split(p.CustomDomains, ",") + } + r.ProxyConfigurer = c + case consts.ProxyTypeTCPMUX: + c := &v1.TCPMuxProxyConfig{ + ProxyBaseConfig: base, + DomainConfig: v1.DomainConfig{ + SubDomain: p.SubDomain, + }, + HTTPUser: p.HTTPUser, + HTTPPassword: p.HTTPPwd, + RouteByHTTPUser: p.RouteByHTTPUser, + Multiplexer: p.Multiplexer, + } + if p.CustomDomains != "" { + c.CustomDomains = strings.Split(p.CustomDomains, ",") + } + r.ProxyConfigurer = c + case consts.ProxyTypeSTCP: + c := &v1.STCPProxyConfig{ + ProxyBaseConfig: base, + Secretkey: p.SK, + } + if p.AllowUsers != "" { + c.AllowUsers = strings.Split(p.AllowUsers, ",") + } + r.ProxyConfigurer = c + case consts.ProxyTypeSUDP: + c := &v1.SUDPProxyConfig{ + ProxyBaseConfig: base, + Secretkey: p.SK, + } + if p.AllowUsers != "" { + c.AllowUsers = strings.Split(p.AllowUsers, ",") + } + r.ProxyConfigurer = c + case consts.ProxyTypeXTCP: + c := &v1.XTCPProxyConfig{ + ProxyBaseConfig: base, + Secretkey: p.SK, + } + if p.AllowUsers != "" { + c.AllowUsers = strings.Split(p.AllowUsers, ",") + } + r.ProxyConfigurer = c + } + return r, nil +} + +func clientProxyBaseToV1(c *BaseProxyConf) (v1.ProxyBaseConfig, error) { + r := v1.ProxyBaseConfig{ + Name: c.Name, + Type: c.Type, + Transport: v1.ProxyTransport{ + UseEncryption: c.UseEncryption, + UseCompression: c.UseCompression, + BandwidthLimitMode: c.BandwidthLimitMode, + ProxyProtocolVersion: c.ProxyProtocolVersion, + }, + Metadatas: c.Metas, + LoadBalancer: v1.LoadBalancerConfig{ + Group: c.Group, + GroupKey: c.GroupKey, + }, + HealthCheck: v1.HealthCheckConfig{ + Type: c.HealthCheckType, + TimeoutSeconds: c.HealthCheckTimeoutS, + MaxFailed: c.HealthCheckMaxFailed, + IntervalSeconds: c.HealthCheckIntervalS, + Path: c.HealthCheckURL, + }, + ProxyBackend: v1.ProxyBackend{ + LocalIP: c.LocalIP, + Plugin: v1.TypedClientPluginOptions{ + Type: c.Plugin, + }, + }, + } + if c.LocalPort != "" { + localPort, err := strconv.Atoi(c.LocalPort) + if err != nil { + return r, err + } + r.ProxyBackend.LocalPort = localPort + } + bl, err := types.NewBandwidthQuantity(c.BandwidthLimit) + if err != nil { + return r, err + } + r.Transport.BandwidthLimit = bl + switch c.Plugin { + case consts.PluginHttp2Https: + r.ProxyBackend.Plugin.ClientPluginOptions = &v1.HTTP2HTTPSPluginOptions{ + Type: c.Plugin, + LocalAddr: c.PluginLocalAddr, + HostHeaderRewrite: c.PluginHostHeaderRewrite, + RequestHeaders: v1.HeaderOperations{ + Set: c.PluginHeaders, + }, + } + case consts.PluginHttpProxy: + r.ProxyBackend.Plugin.ClientPluginOptions = &v1.HTTPProxyPluginOptions{ + Type: c.Plugin, + HTTPUser: c.PluginHttpUser, + HTTPPassword: c.PluginHttpPasswd, + } + case consts.PluginHttps2Http: + r.ProxyBackend.Plugin.ClientPluginOptions = &v1.HTTPS2HTTPPluginOptions{ + Type: c.Plugin, + LocalAddr: c.PluginLocalAddr, + HostHeaderRewrite: c.PluginHostHeaderRewrite, + RequestHeaders: v1.HeaderOperations{ + Set: c.PluginHeaders, + }, + CrtPath: c.PluginCrtPath, + KeyPath: c.PluginKeyPath, + } + case consts.PluginHttps2Https: + r.ProxyBackend.Plugin.ClientPluginOptions = &v1.HTTPS2HTTPSPluginOptions{ + Type: c.Plugin, + LocalAddr: c.PluginLocalAddr, + HostHeaderRewrite: c.PluginHostHeaderRewrite, + RequestHeaders: v1.HeaderOperations{ + Set: c.PluginHeaders, + }, + CrtPath: c.PluginCrtPath, + KeyPath: c.PluginKeyPath, + } + case consts.PluginSocks5: + r.ProxyBackend.Plugin.ClientPluginOptions = &v1.Socks5PluginOptions{ + Type: c.Plugin, + Username: c.PluginUser, + Password: c.PluginPasswd, + } + case consts.PluginStaticFile: + r.ProxyBackend.Plugin.ClientPluginOptions = &v1.StaticFilePluginOptions{ + Type: c.Plugin, + LocalPath: c.PluginLocalPath, + StripPrefix: c.PluginStripPrefix, + HTTPUser: c.PluginHttpUser, + HTTPPassword: c.PluginHttpPasswd, + } + case consts.PluginUnixDomain: + r.ProxyBackend.Plugin.ClientPluginOptions = &v1.UnixDomainSocketPluginOptions{ + Type: c.Plugin, + UnixPath: c.PluginUnixPath, + } + } + return r, nil +} + +func ClientVisitorToV1(p *Proxy) v1.TypedVisitorConfig { + r := v1.TypedVisitorConfig{Type: p.Type} + base := clientVisitorBaseToV1(p) + switch p.Type { + case consts.ProxyTypeSTCP: + r.VisitorConfigurer = &v1.STCPVisitorConfig{VisitorBaseConfig: base} + case consts.ProxyTypeSUDP: + r.VisitorConfigurer = &v1.SUDPVisitorConfig{VisitorBaseConfig: base} + case consts.ProxyTypeXTCP: + r.VisitorConfigurer = &v1.XTCPVisitorConfig{ + VisitorBaseConfig: base, + Protocol: p.Protocol, + KeepTunnelOpen: p.KeepTunnelOpen, + MaxRetriesAnHour: p.MaxRetriesAnHour, + MinRetryInterval: p.MinRetryInterval, + FallbackTo: p.FallbackTo, + FallbackTimeoutMs: p.FallbackTimeoutMs, + } + } + return r +} + +func clientVisitorBaseToV1(p *Proxy) v1.VisitorBaseConfig { + return v1.VisitorBaseConfig{ + Name: p.Name, + Type: p.Type, + Transport: v1.VisitorTransport{ + UseEncryption: p.UseEncryption, + UseCompression: p.UseCompression, + }, + SecretKey: p.SK, + ServerUser: p.ServerUser, + ServerName: p.ServerName, + BindAddr: p.BindAddr, + BindPort: p.BindPort, + } +} + +// toMap converts a struct to a map using the struct tags. +func toMap(in any, tag string) (map[string]any, error) { + out := make(map[string]any) + + v := reflect.ValueOf(in) + if v.Kind() == reflect.Ptr { + v = v.Elem() + } + + // we only accept structs + if v.Kind() != reflect.Struct { + return nil, fmt.Errorf("toMap only accepts structs; got %T", v) + } + + t := v.Type() + for i := 0; i < v.NumField(); i++ { + ft := t.Field(i) + fv := v.Field(i) + key := ft.Tag.Get(tag) + if key != "" { + key = strings.Split(key, ",")[0] + } + switch fv.Kind() { + case reflect.Struct, reflect.Interface: + value := fv.Interface() + if value == nil { + continue + } + if o, ok := value.(time.Time); ok && !o.IsZero() && key != "" { + if b, err := o.MarshalText(); err != nil { + return nil, err + } else { + out[key] = string(b) + } + } + if o, ok := value.(types.BandwidthQuantity); ok && o.String() != "" && key != "" { + out[key] = o.String() + continue + } + m, err := toMap(value, tag) + if err != nil { + return nil, err + } + if len(m) == 0 { + continue + } + if key == "" { + for k, v := range m { + out[k] = v + } + } else { + out[key] = m + } + case reflect.Slice: + if key == "" || fv.Len() == 0 { + continue + } + if fv.Index(0).Kind() == reflect.Struct { + s := make([]any, fv.Len()) + for k := 0; k < fv.Len(); k++ { + m, err := toMap(fv.Index(k).Interface(), tag) + if err != nil { + return nil, err + } + s[k] = m + } + out[key] = s + } else { + out[key] = fv.Interface() + } + default: + if key != "" && !fv.IsZero() { + out[key] = fv.Interface() + } + } } + return out, nil } diff --git a/ui/conf.go b/ui/conf.go index 804f42ca..0ded1d5b 100644 --- a/ui/conf.go +++ b/ui/conf.go @@ -79,7 +79,7 @@ func (conf *Conf) Save() error { var ( appConf = config.App{Defaults: config.ClientCommon{ - ServerPort: "7000", + ServerPort: 7000, LogLevel: "info", LogMaxDays: 3, TCPMux: true, diff --git a/ui/editclient.go b/ui/editclient.go index 44c72480..38e9c23f 100644 --- a/ui/editclient.go +++ b/ui/editclient.go @@ -9,6 +9,7 @@ import ( "github.com/lxn/walk" . "github.com/lxn/walk/declarative" + "github.com/lxn/win" "github.com/samber/lo" "github.com/koho/frpmgr/i18n" @@ -119,7 +120,19 @@ func (cd *EditClientDialog) basicConfPage() TabPage { Label{Text: i18n.SprintfColon("Server Address")}, LineEdit{Text: Bind("ServerAddress", consts.ValidateNonEmpty)}, Label{Text: i18n.SprintfColon("Server Port")}, - LineEdit{Text: Bind("ServerPort", consts.ValidateRequireInteger)}, + Composite{ + Layout: HBox{MarginsZero: true}, + Children: []Widget{ + NumberEdit{ + Value: Bind("ServerPort"), + MinValue: 0, + MaxValue: 65535, + SpinButtonsVisible: true, + MinSize: Size{Width: 90}, + }, + HSpacer{}, + }, + }, Label{Text: i18n.SprintfColon("User")}, LineEdit{Text: Bind("User")}, Label{Text: i18n.SprintfColon("STUN Server")}, @@ -197,6 +210,7 @@ func (cd *EditClientDialog) logConfPage() TabPage { } func (cd *EditClientDialog) adminConfPage() TabPage { + adminEnabled := Bind("adminPort.Value > 0") return AlignGrid(TabPage{ Title: i18n.Sprintf("Admin"), Layout: Grid{Columns: 2}, @@ -207,9 +221,15 @@ func (cd *EditClientDialog) adminConfPage() TabPage { Children: []Widget{ LineEdit{Text: Bind("AdminAddr"), StretchFactor: 2}, Label{Text: ":"}, - LineEdit{Name: "adminPort", Text: Bind("AdminPort", consts.ValidateInteger)}, + NumberEdit{ + Name: "adminPort", + Value: Bind("AdminPort"), + MinValue: 0, + MaxValue: 65535, + MinSize: Size{Width: 70}, + }, ToolButton{ - Enabled: Bind("adminPort.Text != ''"), + Enabled: Bind("adminPort.Value > 0 && !legacyFormat.Checked"), Image: loadIcon(consts.IconLock, 16), ToolTipText: "TLS", OnClicked: func() { cd.adminTLSDialog().Run(cd.Form()) @@ -217,15 +237,15 @@ func (cd *EditClientDialog) adminConfPage() TabPage { }, }, }, - Label{Enabled: Bind("adminPort.Text != ''"), Text: i18n.SprintfColon("User")}, - LineEdit{Enabled: Bind("adminPort.Text != ''"), Text: Bind("AdminUser")}, - Label{Enabled: Bind("adminPort.Text != ''"), Text: i18n.SprintfColon("Password")}, - LineEdit{Enabled: Bind("adminPort.Text != ''"), Text: Bind("AdminPwd"), PasswordMode: true}, - Label{Enabled: Bind("adminPort.Text != ''"), Text: i18n.SprintfColon("Assets")}, - NewBrowseLineEdit(nil, true, Bind("adminPort.Text != ''"), Bind("AssetsDir"), + Label{Enabled: adminEnabled, Text: i18n.SprintfColon("User")}, + LineEdit{Enabled: adminEnabled, Text: Bind("AdminUser")}, + Label{Enabled: adminEnabled, Text: i18n.SprintfColon("Password")}, + LineEdit{Enabled: adminEnabled, Text: Bind("AdminPwd"), PasswordMode: true}, + Label{Enabled: adminEnabled, Text: i18n.SprintfColon("Assets")}, + NewBrowseLineEdit(nil, true, adminEnabled, Bind("AssetsDir"), i18n.Sprintf("Select a local directory that the admin server will load resources from."), "", false), - Label{Enabled: Bind("adminPort.Text != ''"), Text: i18n.SprintfColon("Other Options")}, - CheckBox{Enabled: Bind("adminPort.Text != ''"), Text: "Pprof", Checked: Bind("PprofEnable")}, + Label{Enabled: adminEnabled, Text: i18n.SprintfColon("Other Options")}, + CheckBox{Enabled: adminEnabled, Text: "Pprof", Checked: Bind("PprofEnable")}, Label{Text: i18n.SprintfColon("Auto Delete")}, NewRadioButtonGroup("DeleteMethod", nil, nil, []RadioButton{ {Name: "absCheck", Text: i18n.Sprintf("Absolute"), Value: consts.DeleteAbsolute}, @@ -325,17 +345,11 @@ func (cd *EditClientDialog) tlsConfPage() TabPage { } func (cd *EditClientDialog) advancedConfPage() TabPage { + muxChecked := Bind("muxCheck.Checked") return TabPage{ Title: i18n.Sprintf("Advanced"), Layout: Grid{Columns: 2}, Children: []Widget{ - Label{Text: i18n.SprintfColon("TCP Mux")}, - NewRadioButtonGroup("TCPMux", nil, nil, []RadioButton{ - {Name: "muxCheck", Text: i18n.Sprintf("On"), Value: true}, - {Text: i18n.Sprintf("Off"), Value: false}, - }), - Label{Enabled: Bind("muxCheck.Checked"), Text: i18n.SprintfColon("Mux Keepalive")}, - NumberEdit{Enabled: Bind("muxCheck.Checked"), Value: Bind("TCPMuxKeepaliveInterval"), Suffix: i18n.SprintfLSpace("s")}, Label{Text: "DNS:"}, LineEdit{Text: Bind("DNSServer")}, Label{Text: i18n.SprintfColon("Source Address")}, @@ -350,8 +364,30 @@ func (cd *EditClientDialog) advancedConfPage() TabPage { Composite{ Layout: VBox{MarginsZero: true, SpacingZero: true, Alignment: AlignHNearVNear}, Children: []Widget{ + Composite{ + Layout: HBox{MarginsZero: true}, + Children: []Widget{ + CheckBox{Name: "muxCheck", Text: i18n.Sprintf("TCP Mux"), Checked: Bind("TCPMux")}, + HSpacer{}, + Label{Enabled: muxChecked, Text: i18n.SprintfColon("Heartbeat")}, + NumberEdit{ + Enabled: muxChecked, + Value: Bind("TCPMuxKeepaliveInterval"), + MinValue: 0, + SpinButtonsVisible: true, + MinSize: Size{Width: 85}, + Style: win.ES_RIGHT, + }, + Label{Enabled: muxChecked, Text: i18n.Sprintf("s")}, + }, + }, CheckBox{Text: i18n.Sprintf("Exit after login failure"), Checked: Bind("LoginFailExit")}, CheckBox{Text: i18n.Sprintf("Disable auto-start at boot"), Checked: Bind("ManualStart")}, + CheckBox{ + Name: "legacyFormat", + Text: i18n.Sprintf("Use legacy format config file"), + Checked: Bind("LegacyFormat"), + }, VSpacer{Size: 4}, Composite{ Layout: HBox{MarginsZero: true, Spacing: 18}, diff --git a/ui/editproxy.go b/ui/editproxy.go index dada52be..8a23257b 100644 --- a/ui/editproxy.go +++ b/ui/editproxy.go @@ -200,7 +200,7 @@ func (pd *EditProxyDialog) basicProxyPage() TabPage { Label{Visible: Bind("vm.BindAddrVisible"), Text: i18n.SprintfColon("Bind Address")}, LineEdit{Visible: Bind("vm.BindAddrVisible"), Text: Bind("BindAddr")}, Label{Visible: Bind("vm.BindPortVisible"), Text: i18n.SprintfColon("Bind Port")}, - LineEdit{Visible: Bind("vm.BindPortVisible"), Text: Bind("BindPort")}, + NumberEdit{Visible: Bind("vm.BindPortVisible"), Value: Bind("BindPort"), MinValue: 0, MaxValue: 65535}, Label{Visible: Bind("vm.ServerNameVisible"), Text: i18n.SprintfColon("Server Name")}, LineEdit{Visible: Bind("vm.ServerNameVisible"), Text: Bind("ServerName")}, Label{Visible: Bind("vm.ServerNameVisible"), Text: i18n.SprintfColon("Server User")}, diff --git a/ui/model.go b/ui/model.go index e444913a..2437b744 100644 --- a/ui/model.go +++ b/ui/model.go @@ -2,6 +2,7 @@ package ui import ( "os" + "strconv" "strings" "github.com/lxn/walk" @@ -86,7 +87,9 @@ func NewProxyModel(conf *Conf) *ProxyModel { if p.IsVisitor() { pi.Domains = p.ServerName pi.DisplayLocalIP = p.BindAddr - pi.DisplayLocalPort = p.BindPort + if p.BindPort > 0 { + pi.DisplayLocalPort = strconv.Itoa(p.BindPort) + } } return pi }) diff --git a/ui/proxyview.go b/ui/proxyview.go index 0b594168..45a6ff63 100644 --- a/ui/proxyview.go +++ b/ui/proxyview.go @@ -4,6 +4,7 @@ import ( "fmt" "net" "path/filepath" + "strconv" "strings" frpconfig "github.com/fatedier/frp/pkg/config" @@ -352,7 +353,7 @@ func (pv *ProxyView) onCopyAccessAddr() { } case consts.ProxyTypeXTCP, consts.ProxyTypeSTCP, consts.ProxyTypeSUDP: if proxy.Role == "visitor" { - access = util.GetOrElse(proxy.BindAddr, "127.0.0.1") + ":" + proxy.BindPort + access = util.GetOrElse(proxy.BindAddr, "127.0.0.1") + ":" + strconv.Itoa(proxy.BindPort) } else { access = util.GetOrElse(proxy.LocalIP, "127.0.0.1") + ":" + proxy.LocalPort } From 5bbcef17e1cf84d7e0feeacab5aee0ba20f18255 Mon Sep 17 00:00:00 2001 From: Gerhard Tan Date: Sun, 3 Mar 2024 17:33:40 +0800 Subject: [PATCH 2/6] Fix type assertion --- pkg/config/conversion.go | 51 +++++++++++++++++++++++----------------- 1 file changed, 30 insertions(+), 21 deletions(-) diff --git a/pkg/config/conversion.go b/pkg/config/conversion.go index 3d8fac18..9e95e68b 100644 --- a/pkg/config/conversion.go +++ b/pkg/config/conversion.go @@ -562,36 +562,45 @@ func toMap(in any, tag string) (map[string]any, error) { if key != "" { key = strings.Split(key, ",")[0] } + if key == "-" { + continue + } switch fv.Kind() { case reflect.Struct, reflect.Interface: value := fv.Interface() if value == nil { continue } - if o, ok := value.(time.Time); ok && !o.IsZero() && key != "" { - if b, err := o.MarshalText(); err != nil { + switch o := value.(type) { + case time.Time: + if !o.IsZero() && key != "" { + if b, err := o.MarshalText(); err != nil { + return nil, err + } else { + out[key] = string(b) + } + } + case types.BandwidthQuantity: + if o.String() != "" && key != "" { + out[key] = o.String() + } + default: + m, err := toMap(value, tag) + if err != nil { return nil, err - } else { - out[key] = string(b) } - } - if o, ok := value.(types.BandwidthQuantity); ok && o.String() != "" && key != "" { - out[key] = o.String() - continue - } - m, err := toMap(value, tag) - if err != nil { - return nil, err - } - if len(m) == 0 { - continue - } - if key == "" { - for k, v := range m { - out[k] = v + if len(m) == 0 { + continue + } + if key == "" { + if ft.Anonymous { + for k, v := range m { + out[k] = v + } + } + } else { + out[key] = m } - } else { - out[key] = m } case reflect.Slice: if key == "" || fv.Len() == 0 { From 9fe0f86f02c4ee1576c8eaa92ba034088ab92876 Mon Sep 17 00:00:00 2001 From: Gerhard Tan Date: Sun, 3 Mar 2024 17:56:13 +0800 Subject: [PATCH 3/6] Fix unit tests --- pkg/config/app_test.go | 2 +- pkg/config/client_test.go | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/pkg/config/app_test.go b/pkg/config/app_test.go index 6b52ff88..be2077af 100644 --- a/pkg/config/app_test.go +++ b/pkg/config/app_test.go @@ -23,7 +23,7 @@ func TestUnmarshalAppConfFromIni(t *testing.T) { expected := App{ Password: "abcde", Defaults: ClientCommon{ - ServerPort: "7000", + ServerPort: 7000, LogLevel: "info", LogMaxDays: 5, Protocol: "kcp", diff --git a/pkg/config/client_test.go b/pkg/config/client_test.go index ca2bd456..fc5451eb 100644 --- a/pkg/config/client_test.go +++ b/pkg/config/client_test.go @@ -25,8 +25,9 @@ func TestUnmarshalClientConfFromIni(t *testing.T) { meta_2 = value ` expected := NewDefaultClientConfig() + expected.LegacyFormat = true expected.ServerAddress = "example.com" - expected.ServerPort = "7001" + expected.ServerPort = 7001 expected.Token = "123456" expected.ManualStart = true expected.Metas = map[string]string{"1": "value"} From f3e8a16e71e36c50b4d8edaee4dcf39d7662d05d Mon Sep 17 00:00:00 2001 From: Gerhard Tan Date: Sun, 10 Mar 2024 00:40:03 +0800 Subject: [PATCH 4/6] Validate proxy and support for ranged ports in TOML format --- i18n/catalog.go | 1112 ++++++++++++----------- i18n/locales/en-US/messages.gotext.json | 73 ++ i18n/locales/es-ES/messages.gotext.json | 55 ++ i18n/locales/ja-JP/messages.gotext.json | 55 ++ i18n/locales/ko-KR/messages.gotext.json | 55 ++ i18n/locales/zh-CN/messages.gotext.json | 55 ++ i18n/locales/zh-TW/messages.gotext.json | 55 ++ pkg/config/client.go | 84 +- pkg/config/conversion.go | 55 +- pkg/config/v1.go | 50 + services/frp.go | 25 - ui/editclient.go | 28 +- ui/editproxy.go | 158 ++-- ui/proxyview.go | 6 +- ui/simpleproxy.go | 1 - 15 files changed, 1191 insertions(+), 676 deletions(-) create mode 100644 pkg/config/v1.go diff --git a/i18n/catalog.go b/i18n/catalog.go index 8c0dedbc..560dbaa0 100644 --- a/i18n/catalog.go +++ b/i18n/catalog.go @@ -44,9 +44,9 @@ func init() { var messageKeyToIndex = map[string]int{ "* Leave blank to record no log and delete the original log file.": 75, - "* Support batch import, one link per line.": 242, + "* Support batch import, one link per line.": 251, "* The following features may affect the stability of the service.": 123, - "A selection is required.": 257, + "A selection is required.": 266, "About": 15, "Absolute": 87, "Add": 27, @@ -55,95 +55,98 @@ var messageKeyToIndex = map[string]int{ "Advanced": 115, "All": 39, "All Files": 3, - "Allow Users": 138, + "Allow Users": 139, "An error occurred while checking for a software update.": 21, "Another config already exists with the name \"%s\".": 51, "Are you sure you would like to delete config \"%s\"?": 54, - "Are you sure you would like to delete proxy \"%s\"?": 236, - "Are you sure you would like to disable proxy \"%s\"?": 238, - "Are you sure you would like to stop config \"%s\"?": 203, + "Are you sure you would like to delete proxy \"%s\"?": 245, + "Are you sure you would like to disable proxy \"%s\"?": 247, + "Are you sure you would like to stop config \"%s\"?": 212, "Assets": 83, "Audience": 67, "Auth": 62, "Auth Method": 63, "Authentication": 71, "Auto Delete": 86, - "Bandwidth": 150, + "Bandwidth": 151, "Basic": 57, - "Behavior": 187, - "Bind Address": 139, - "Bind Port": 140, + "Behavior": 196, + "Bind Address": 140, + "Bind Port": 141, + "Bind port is required.": 184, "Built on: %s": 2, "Cancel": 24, "Certificate": 108, "Certificate Files": 5, "Certificate Key": 110, - "Change Password": 212, - "Check Interval": 180, - "Check Timeout": 178, - "Check Type": 177, + "Change Password": 221, + "Check Interval": 181, + "Check Timeout": 179, + "Check Type": 178, "Check for updates": 18, "Checking for updates": 17, "Clear All": 29, - "Client": 149, + "Client": 150, "Common Only": 40, - "Compression": 156, + "Compression": 157, "Config already exists": 125, "Config already removed": 33, "Configuration": 30, "Configuration Files": 4, "Connection": 92, - "Copy": 199, - "Copy Access Address": 233, + "Copy": 208, + "Copy Access Address": 242, "Copy Share Link": 46, "Create a Copy": 38, - "Custom Domains": 144, - "Days": 91, - "Defaults": 217, - "Define the default value when creating a new configuration.\nThe value here will not affect the existing configuration.": 218, + "Custom Domains": 145, + "Custom domains and subdomain should have at least one of these set.": 191, + "Days": 91, + "Defaults": 226, + "Define the default value when creating a new configuration.\nThe value here will not affect the existing configuration.": 227, "Delete": 28, "Delete Date": 89, "Delete Days": 90, "Delete config \"%s\"": 53, - "Delete proxy \"%s\"": 235, + "Delete proxy \"%s\"": 244, "Dial Timeout": 101, - "Direct Edit": 231, - "Disable": 229, + "Direct Edit": 240, + "Disable": 238, "Disable auto-start at boot": 119, "Disable custom first byte": 114, - "Disable proxy \"%s\"": 237, - "Domains": 232, - "Download": 246, + "Disable proxy \"%s\"": 246, + "Domains": 241, + "Download": 255, "Download updates": 16, "Edit": 35, "Edit Client - %s": 56, - "Edit Proxy - %s": 128, - "Enable": 239, - "Encryption": 155, - "Enter Administration Password": 249, - "Enter Password": 247, + "Edit Proxy - %s": 129, + "Enable": 248, + "Encryption": 156, + "Enter Administration Password": 258, + "Enter Password": 256, "Exit after login failure": 118, "Experimental Features": 122, "Export All Configs to ZIP": 47, - "External Address": 188, - "FRP Manager": 241, + "External Address": 197, + "FRP Manager": 250, "FRP version: %s": 1, - "Failure Count": 179, - "Fallback": 160, - "Fallback Timeout": 161, + "Failure Count": 180, + "Fallback": 161, + "Fallback Timeout": 162, "For FRP configuration documentation, please visit the FRP project page:": 20, "For comments or to report bugs, please visit the project page:": 19, - "Group": 174, - "Group Key": 175, - "HTTP File Server": 228, - "HTTP Password": 164, + "Group": 175, + "Group Key": 176, + "HTTP File Server": 237, + "HTTP Password": 165, "HTTP Proxy": 94, - "HTTP User": 163, - "Health Check": 176, + "HTTP User": 164, + "Health Check": 177, + "Health check url is required.": 187, "Heart Beats": 72, "Heartbeat": 97, "Host Name": 107, - "Host Rewrite": 165, + "Host Rewrite": 166, "Idle Timeout": 103, "Import Config": 41, "Import Config from File": 32, @@ -152,158 +155,164 @@ var messageKeyToIndex = map[string]int{ "Import from URL": 43, "Imported %d of %d configs.": 50, "Interval": 98, - "Invalid Input": 251, - "Item": 185, - "Keep Tunnel": 154, + "Invalid Input": 260, + "Invalid local port.": 186, + "Invalid remote port.": 189, + "Item": 194, + "Keep Tunnel": 155, "Keepalive": 102, "Key Files": 6, - "Languages": 213, - "Latest": 184, + "Languages": 222, + "Latest": 193, "Level": 78, - "Load Balance": 173, - "Local Address": 135, - "Local Directory": 205, - "Local Path": 170, - "Local Port": 136, - "Locations": 145, + "Load Balance": 174, + "Local Address": 136, + "Local Directory": 214, + "Local Path": 171, + "Local Port": 137, + "Locations": 146, "Log": 74, "Log File": 76, "Log Files": 7, - "Log Level": 224, - "Log retention": 225, + "Log Level": 233, + "Log retention": 234, "Manual Settings": 49, - "Master password": 209, + "Master password": 218, "Max Days": 79, "Max Streams": 104, "Metadata": 121, - "Multiplexer": 147, + "Multiplexer": 148, "NAT Discovery": 45, - "NAT Type": 186, + "NAT Type": 195, "Name": 25, "New Client": 55, "New Config": 48, "New Configuration": 31, - "New Proxy": 127, + "New Proxy": 128, "New Version!": 14, - "New master password": 221, - "No": 190, + "New master password": 230, + "No": 199, "None": 64, "Not a number": 12, "Number out of allowed range": 8, "OK": 23, "Off": 106, "On": 105, - "Open Config": 230, + "Open Config": 239, "Open File": 36, - "Open Log Folder": 183, - "Open Port": 207, + "Open Log Folder": 192, + "Open Port": 216, "Other Options": 85, "Parameters": 70, - "Passive Port Range": 240, + "Passive Port Range": 249, "Password": 82, - "Password is set.": 223, + "Password is set.": 232, "Password mismatch": 10, - "Password removed.": 220, + "Password removed.": 229, "Please check and try again.": 11, - "Please enter a number from %.f to %.f.": 252, - "Please enter a number from %s to %s.": 253, + "Please enter a number from %.f to %.f.": 261, + "Please enter a number from %s to %s.": 262, "Please enter a number greater than %d.": 9, "Please enter a valid number.": 13, - "Please enter the correct URL list.": 245, - "Please select one of the provided options.": 256, - "Plugin": 166, - "Plugin Name": 167, + "Please enter the correct URL list.": 254, + "Please select one of the provided options.": 265, + "Plugin": 167, + "Plugin Name": 168, "Pool Count": 95, - "Port": 206, - "Preferences": 208, + "Port": 215, + "Preferences": 217, "Protocol": 93, - "Proxy Protocol": 151, - "Proxy already exists": 181, - "Public Network": 191, - "Quick Add": 226, - "Random": 129, - "Re-enter password": 222, - "Ready": 244, + "Proxy Protocol": 152, + "Proxy already exists": 182, + "Public Network": 200, + "Quick Add": 235, + "Random": 130, + "Re-enter password": 231, + "Ready": 253, "Relative": 88, - "Remote Address": 198, - "Remote Desktop": 227, - "Remote Port": 137, - "Rename automatically": 243, - "Request headers": 146, - "Retry Count": 157, - "Retry Interval": 159, - "Role": 131, - "Route User": 148, - "Running": 193, + "Remote Address": 207, + "Remote Desktop": 236, + "Remote Port": 138, + "Rename automatically": 252, + "Request headers": 147, + "Requires local port or plugin.": 185, + "Retry Count": 158, + "Retry Interval": 160, + "Role": 132, + "Route User": 149, + "Running": 202, "STUN Server": 61, "Scope": 68, "Secret": 66, - "Secret Key": 134, + "Secret Key": 135, "Select Certificate File": 109, "Select Certificate Key File": 111, "Select Log File": 77, "Select Trusted CA File": 113, - "Select Unix Path": 169, - "Select a folder for directory listing.": 171, + "Select Unix Path": 170, + "Select a folder for directory listing.": 172, "Select a local directory that the admin server will load resources from.": 84, - "Select language": 216, - "Selection Required": 255, - "Server": 132, + "Select language": 225, + "Selection Required": 264, + "Server": 133, "Server Address": 58, - "Server Name": 141, + "Server Name": 142, "Server Port": 59, - "Server User": 142, - "Service": 201, - "Set Defaults": 219, + "Server User": 143, + "Service": 210, + "Set Defaults": 228, "Show in Folder": 37, "Source Address": 116, - "Start": 200, - "Starting": 195, - "Status": 197, - "Stop": 204, - "Stop config \"%s\"": 202, - "Stopped": 194, - "Stopping": 196, - "Strip Prefix": 172, - "Subdomain": 143, + "Start": 209, + "Starting": 204, + "Status": 206, + "Stop": 213, + "Stop config \"%s\"": 211, + "Stopped": 203, + "Stopping": 205, + "Strip Prefix": 173, + "Subdomain": 144, "TCP Mux": 117, "The config \"%s\" already removed.": 34, "The config name \"%s\" already exists.": 126, - "The current display language is": 214, - "The file \"%s\" is not a valid ZIP file.": 52, - "The password is incorrect. Re-enter password.": 250, - "The proxy name \"%s\" already exists.": 182, - "The text does not match the required pattern.": 254, - "There are currently no updates available.": 22, - "This feature only supports text in INI or TOML format.": 234, - "Timeout": 100, - "Times/Hour": 158, - "Token": 65, - "Token Endpoint": 69, - "Trusted CA": 112, - "Type": 130, - "UDP Packet Size": 96, - "Unix Path": 168, - "Unknown": 192, + "The current display language is": 223, + "The file \"%s\" is not a valid ZIP file.": 52, + "The number of local ports should be the same as the number of remote ports.": 190, + "The password is incorrect. Re-enter password.": 259, + "The plugin does not support range ports.": 188, + "The proxy name \"%s\" already exists.": 183, + "The text does not match the required pattern.": 263, + "There are currently no updates available.": 22, + "This feature only supports text in INI or TOML format.": 243, + "Timeout": 100, + "Times/Hour": 159, + "Token": 65, + "Token Endpoint": 69, + "Trusted CA": 112, + "Type": 131, + "UDP Packet Size": 96, + "Unable to upgrade your config file due to proxy conversion failure, please check the proxy config and try again.\n\nBad proxy: %s": 127, + "Unix Path": 169, + "Unknown": 201, "Use legacy format config file": 120, - "Use master password": 211, + "Use master password": 220, "Use server SVCB records": 124, "User": 60, "Value": 26, "Version: %s": 0, - "Visitor": 133, + "Visitor": 134, "Work Conns": 73, - "Yes": 189, - "You can set a password to restrict access to this program.\nYou will be asked to enter it the next time you use this program.": 210, - "You must enter an administration password to operate the %s.": 248, - "You must restart program to apply the modification.": 215, - "auto": 152, - "default": 153, - "ms": 162, + "Yes": 198, + "You can set a password to restrict access to this program.\nYou will be asked to enter it the next time you use this program.": 219, + "You must enter an administration password to operate the %s.": 257, + "You must restart program to apply the modification.": 224, + "auto": 153, + "default": 154, + "ms": 163, "s": 99, } -var en_USIndex = []uint32{ // 259 elements +var en_USIndex = []uint32{ // 268 elements // Entry 0 - 1F 0x00000000, 0x0000000f, 0x00000022, 0x00000032, 0x0000003c, 0x00000050, 0x00000062, 0x0000006c, @@ -341,46 +350,48 @@ var en_USIndex = []uint32{ // 259 elements 0x000007e3, 0x00000801, 0x0000080a, 0x00000820, 0x00000862, 0x0000087a, 0x00000890, 0x000008b8, // Entry 80 - 9F - 0x000008c2, 0x000008d5, 0x000008dc, 0x000008e1, - 0x000008e6, 0x000008ed, 0x000008f5, 0x00000900, - 0x0000090e, 0x00000919, 0x00000925, 0x00000931, - 0x0000093e, 0x00000948, 0x00000954, 0x00000960, - 0x0000096a, 0x00000979, 0x00000983, 0x00000993, - 0x0000099f, 0x000009aa, 0x000009b1, 0x000009bb, - 0x000009ca, 0x000009cf, 0x000009d7, 0x000009e3, - 0x000009ee, 0x000009fa, 0x00000a06, 0x00000a11, + 0x0000093b, 0x00000945, 0x00000958, 0x0000095f, + 0x00000964, 0x00000969, 0x00000970, 0x00000978, + 0x00000983, 0x00000991, 0x0000099c, 0x000009a8, + 0x000009b4, 0x000009c1, 0x000009cb, 0x000009d7, + 0x000009e3, 0x000009ed, 0x000009fc, 0x00000a06, + 0x00000a16, 0x00000a22, 0x00000a2d, 0x00000a34, + 0x00000a3e, 0x00000a4d, 0x00000a52, 0x00000a5a, + 0x00000a66, 0x00000a71, 0x00000a7d, 0x00000a89, // Entry A0 - BF - 0x00000a20, 0x00000a29, 0x00000a3a, 0x00000a3d, - 0x00000a47, 0x00000a55, 0x00000a62, 0x00000a69, - 0x00000a75, 0x00000a7f, 0x00000a90, 0x00000a9b, - 0x00000ac2, 0x00000acf, 0x00000adc, 0x00000ae2, - 0x00000aec, 0x00000af9, 0x00000b04, 0x00000b12, - 0x00000b20, 0x00000b2f, 0x00000b44, 0x00000b6b, - 0x00000b7b, 0x00000b82, 0x00000b87, 0x00000b90, - 0x00000b99, 0x00000baa, 0x00000bae, 0x00000bb1, + 0x00000a94, 0x00000aa3, 0x00000aac, 0x00000abd, + 0x00000ac0, 0x00000aca, 0x00000ad8, 0x00000ae5, + 0x00000aec, 0x00000af8, 0x00000b02, 0x00000b13, + 0x00000b1e, 0x00000b45, 0x00000b52, 0x00000b5f, + 0x00000b65, 0x00000b6f, 0x00000b7c, 0x00000b87, + 0x00000b95, 0x00000ba3, 0x00000bb2, 0x00000bc7, + 0x00000bee, 0x00000c05, 0x00000c24, 0x00000c38, + 0x00000c56, 0x00000c7f, 0x00000c94, 0x00000ce0, // Entry C0 - DF - 0x00000bc0, 0x00000bc8, 0x00000bd0, 0x00000bd8, - 0x00000be1, 0x00000bea, 0x00000bf1, 0x00000c00, - 0x00000c05, 0x00000c0b, 0x00000c13, 0x00000c27, - 0x00000c5b, 0x00000c60, 0x00000c70, 0x00000c75, - 0x00000c7f, 0x00000c8b, 0x00000c9b, 0x00000d18, - 0x00000d2c, 0x00000d3c, 0x00000d46, 0x00000d66, - 0x00000d9a, 0x00000daa, 0x00000db3, 0x00000e2a, - 0x00000e37, 0x00000e49, 0x00000e5d, 0x00000e6f, + 0x00000d24, 0x00000d34, 0x00000d3b, 0x00000d40, + 0x00000d49, 0x00000d52, 0x00000d63, 0x00000d67, + 0x00000d6a, 0x00000d79, 0x00000d81, 0x00000d89, + 0x00000d91, 0x00000d9a, 0x00000da3, 0x00000daa, + 0x00000db9, 0x00000dbe, 0x00000dc4, 0x00000dcc, + 0x00000de0, 0x00000e14, 0x00000e19, 0x00000e29, + 0x00000e2e, 0x00000e38, 0x00000e44, 0x00000e54, + 0x00000ed1, 0x00000ee5, 0x00000ef5, 0x00000eff, // Entry E0 - FF - 0x00000e80, 0x00000e8a, 0x00000e98, 0x00000ea2, - 0x00000eb1, 0x00000ec2, 0x00000eca, 0x00000ed6, - 0x00000ee2, 0x00000eea, 0x00000efe, 0x00000f35, - 0x00000f4a, 0x00000f7f, 0x00000f95, 0x00000fcb, - 0x00000fd2, 0x00000fe5, 0x00000ff1, 0x0000101c, - 0x00001031, 0x00001037, 0x0000105a, 0x00001063, - 0x00001072, 0x000010b2, 0x000010d0, 0x000010fe, - 0x0000110c, 0x00001139, 0x00001164, 0x00001192, + 0x00000f1f, 0x00000f53, 0x00000f63, 0x00000f6c, + 0x00000fe3, 0x00000ff0, 0x00001002, 0x00001016, + 0x00001028, 0x00001039, 0x00001043, 0x00001051, + 0x0000105b, 0x0000106a, 0x0000107b, 0x00001083, + 0x0000108f, 0x0000109b, 0x000010a3, 0x000010b7, + 0x000010ee, 0x00001103, 0x00001138, 0x0000114e, + 0x00001184, 0x0000118b, 0x0000119e, 0x000011aa, + 0x000011d5, 0x000011ea, 0x000011f0, 0x00001213, // Entry 100 - 11F - 0x000011a5, 0x000011d0, 0x000011e9, -} // Size: 1060 bytes + 0x0000121c, 0x0000122b, 0x0000126b, 0x00001289, + 0x000012b7, 0x000012c5, 0x000012f2, 0x0000131d, + 0x0000134b, 0x0000135e, 0x00001389, 0x000013a2, +} // Size: 1096 bytes -const en_USData string = "" + // Size: 4585 bytes +const en_USData string = "" + // Size: 5026 bytes "\x02Version: %[1]s\x02FRP version: %[1]s\x02Built on: %[1]s\x02All Files" + "\x02Configuration Files\x02Certificate Files\x02Key Files\x02Log Files" + "\x02Number out of allowed range\x02Please enter a number greater than %[" + @@ -418,47 +429,54 @@ const en_USData string = "" + // Size: 4585 bytes " file\x02Metadata\x02Experimental Features\x02* The following features m" + "ay affect the stability of the service.\x02Use server SVCB records\x02Co" + "nfig already exists\x02The config name \x22%[1]s\x22 already exists.\x02" + - "New Proxy\x02Edit Proxy - %[1]s\x02Random\x02Type\x02Role\x02Server\x02V" + - "isitor\x02Secret Key\x02Local Address\x02Local Port\x02Remote Port\x02Al" + - "low Users\x02Bind Address\x02Bind Port\x02Server Name\x02Server User\x02" + - "Subdomain\x02Custom Domains\x02Locations\x02Request headers\x02Multiplex" + - "er\x02Route User\x02Client\x02Bandwidth\x02Proxy Protocol\x02auto\x02def" + - "ault\x02Keep Tunnel\x02Encryption\x02Compression\x02Retry Count\x02Times" + - "/Hour\x02Retry Interval\x02Fallback\x02Fallback Timeout\x02ms\x02HTTP Us" + - "er\x02HTTP Password\x02Host Rewrite\x02Plugin\x02Plugin Name\x02Unix Pat" + - "h\x02Select Unix Path\x02Local Path\x02Select a folder for directory lis" + - "ting.\x02Strip Prefix\x02Load Balance\x02Group\x02Group Key\x02Health Ch" + - "eck\x02Check Type\x02Check Timeout\x02Failure Count\x02Check Interval" + - "\x02Proxy already exists\x02The proxy name \x22%[1]s\x22 already exists." + - "\x02Open Log Folder\x02Latest\x02Item\x02NAT Type\x02Behavior\x02Externa" + - "l Address\x02Yes\x02No\x02Public Network\x02Unknown\x02Running\x02Stoppe" + - "d\x02Starting\x02Stopping\x02Status\x02Remote Address\x02Copy\x02Start" + - "\x02Service\x02Stop config \x22%[1]s\x22\x02Are you sure you would like " + - "to stop config \x22%[1]s\x22?\x02Stop\x02Local Directory\x02Port\x02Open" + - " Port\x02Preferences\x02Master password\x02You can set a password to res" + - "trict access to this program.\x0aYou will be asked to enter it the next " + - "time you use this program.\x02Use master password\x02Change Password\x02" + - "Languages\x02The current display language is\x02You must restart program" + - " to apply the modification.\x02Select language\x02Defaults\x02Define the" + - " default value when creating a new configuration.\x0aThe value here will" + - " not affect the existing configuration.\x02Set Defaults\x02Password remo" + - "ved.\x02New master password\x02Re-enter password\x02Password is set.\x02" + - "Log Level\x02Log retention\x02Quick Add\x02Remote Desktop\x02HTTP File S" + - "erver\x02Disable\x02Open Config\x02Direct Edit\x02Domains\x02Copy Access" + - " Address\x02This feature only supports text in INI or TOML format.\x02De" + - "lete proxy \x22%[1]s\x22\x02Are you sure you would like to delete proxy " + - "\x22%[1]s\x22?\x02Disable proxy \x22%[1]s\x22\x02Are you sure you would " + - "like to disable proxy \x22%[1]s\x22?\x02Enable\x02Passive Port Range\x02" + - "FRP Manager\x02* Support batch import, one link per line.\x02Rename auto" + - "matically\x02Ready\x02Please enter the correct URL list.\x02Download\x02" + - "Enter Password\x02You must enter an administration password to operate t" + - "he %[1]s.\x02Enter Administration Password\x02The password is incorrect." + - " Re-enter password.\x02Invalid Input\x02Please enter a number from %.[1]" + - "f to %.[2]f.\x02Please enter a number from %[1]s to %[2]s.\x02The text d" + - "oes not match the required pattern.\x02Selection Required\x02Please sele" + - "ct one of the provided options.\x02A selection is required." + "Unable to upgrade your config file due to proxy conversion failure, plea" + + "se check the proxy config and try again.\x0a\x0aBad proxy: %[1]s\x02New " + + "Proxy\x02Edit Proxy - %[1]s\x02Random\x02Type\x02Role\x02Server\x02Visit" + + "or\x02Secret Key\x02Local Address\x02Local Port\x02Remote Port\x02Allow " + + "Users\x02Bind Address\x02Bind Port\x02Server Name\x02Server User\x02Subd" + + "omain\x02Custom Domains\x02Locations\x02Request headers\x02Multiplexer" + + "\x02Route User\x02Client\x02Bandwidth\x02Proxy Protocol\x02auto\x02defau" + + "lt\x02Keep Tunnel\x02Encryption\x02Compression\x02Retry Count\x02Times/H" + + "our\x02Retry Interval\x02Fallback\x02Fallback Timeout\x02ms\x02HTTP User" + + "\x02HTTP Password\x02Host Rewrite\x02Plugin\x02Plugin Name\x02Unix Path" + + "\x02Select Unix Path\x02Local Path\x02Select a folder for directory list" + + "ing.\x02Strip Prefix\x02Load Balance\x02Group\x02Group Key\x02Health Che" + + "ck\x02Check Type\x02Check Timeout\x02Failure Count\x02Check Interval\x02" + + "Proxy already exists\x02The proxy name \x22%[1]s\x22 already exists.\x02" + + "Bind port is required.\x02Requires local port or plugin.\x02Invalid loca" + + "l port.\x02Health check url is required.\x02The plugin does not support " + + "range ports.\x02Invalid remote port.\x02The number of local ports should" + + " be the same as the number of remote ports.\x02Custom domains and subdom" + + "ain should have at least one of these set.\x02Open Log Folder\x02Latest" + + "\x02Item\x02NAT Type\x02Behavior\x02External Address\x02Yes\x02No\x02Pub" + + "lic Network\x02Unknown\x02Running\x02Stopped\x02Starting\x02Stopping\x02" + + "Status\x02Remote Address\x02Copy\x02Start\x02Service\x02Stop config \x22" + + "%[1]s\x22\x02Are you sure you would like to stop config \x22%[1]s\x22?" + + "\x02Stop\x02Local Directory\x02Port\x02Open Port\x02Preferences\x02Maste" + + "r password\x02You can set a password to restrict access to this program." + + "\x0aYou will be asked to enter it the next time you use this program." + + "\x02Use master password\x02Change Password\x02Languages\x02The current d" + + "isplay language is\x02You must restart program to apply the modification" + + ".\x02Select language\x02Defaults\x02Define the default value when creati" + + "ng a new configuration.\x0aThe value here will not affect the existing c" + + "onfiguration.\x02Set Defaults\x02Password removed.\x02New master passwor" + + "d\x02Re-enter password\x02Password is set.\x02Log Level\x02Log retention" + + "\x02Quick Add\x02Remote Desktop\x02HTTP File Server\x02Disable\x02Open C" + + "onfig\x02Direct Edit\x02Domains\x02Copy Access Address\x02This feature o" + + "nly supports text in INI or TOML format.\x02Delete proxy \x22%[1]s\x22" + + "\x02Are you sure you would like to delete proxy \x22%[1]s\x22?\x02Disabl" + + "e proxy \x22%[1]s\x22\x02Are you sure you would like to disable proxy " + + "\x22%[1]s\x22?\x02Enable\x02Passive Port Range\x02FRP Manager\x02* Suppo" + + "rt batch import, one link per line.\x02Rename automatically\x02Ready\x02" + + "Please enter the correct URL list.\x02Download\x02Enter Password\x02You " + + "must enter an administration password to operate the %[1]s.\x02Enter Adm" + + "inistration Password\x02The password is incorrect. Re-enter password." + + "\x02Invalid Input\x02Please enter a number from %.[1]f to %.[2]f.\x02Ple" + + "ase enter a number from %[1]s to %[2]s.\x02The text does not match the r" + + "equired pattern.\x02Selection Required\x02Please select one of the provi" + + "ded options.\x02A selection is required." -var es_ESIndex = []uint32{ // 259 elements +var es_ESIndex = []uint32{ // 268 elements // Entry 0 - 1F 0x00000000, 0x00000010, 0x00000024, 0x00000041, 0x00000054, 0x0000006f, 0x00000087, 0x00000096, @@ -496,46 +514,48 @@ var es_ESIndex = []uint32{ // 259 elements 0x00000a74, 0x00000aa7, 0x00000ab1, 0x00000ad1, 0x00000b1f, 0x00000b40, 0x00000b5c, 0x00000b8b, // Entry 80 - 9F - 0x00000b97, 0x00000bac, 0x00000bb6, 0x00000bbb, - 0x00000bc0, 0x00000bc9, 0x00000bd3, 0x00000be1, - 0x00000bf2, 0x00000bff, 0x00000c0d, 0x00000c1f, - 0x00000c34, 0x00000c45, 0x00000c59, 0x00000c6e, - 0x00000c79, 0x00000c91, 0x00000c9a, 0x00000cb0, - 0x00000cbc, 0x00000ccc, 0x00000cd4, 0x00000ce0, - 0x00000cf0, 0x00000cf5, 0x00000d01, 0x00000d11, - 0x00000d19, 0x00000d25, 0x00000d3b, 0x00000d46, + 0x00000c46, 0x00000c52, 0x00000c67, 0x00000c71, + 0x00000c76, 0x00000c7b, 0x00000c84, 0x00000c8e, + 0x00000c9c, 0x00000cad, 0x00000cba, 0x00000cc8, + 0x00000cda, 0x00000cef, 0x00000d00, 0x00000d14, + 0x00000d29, 0x00000d34, 0x00000d4c, 0x00000d55, + 0x00000d6b, 0x00000d77, 0x00000d87, 0x00000d8f, + 0x00000d9b, 0x00000dab, 0x00000db0, 0x00000dbc, + 0x00000dcc, 0x00000dd4, 0x00000de0, 0x00000df6, // Entry A0 - BF - 0x00000d5d, 0x00000d66, 0x00000d7e, 0x00000d8a, - 0x00000d97, 0x00000da8, 0x00000dbc, 0x00000dc5, - 0x00000dcc, 0x00000dd6, 0x00000df1, 0x00000dfc, - 0x00000e31, 0x00000e41, 0x00000e55, 0x00000e5b, - 0x00000e6a, 0x00000e7b, 0x00000e80, 0x00000e94, - 0x00000ea7, 0x00000eb1, 0x00000ec4, 0x00000eea, - 0x00000ef9, 0x00000f01, 0x00000f07, 0x00000f13, - 0x00000f22, 0x00000f35, 0x00000f39, 0x00000f3c, + 0x00000e01, 0x00000e18, 0x00000e21, 0x00000e39, + 0x00000e45, 0x00000e52, 0x00000e63, 0x00000e77, + 0x00000e80, 0x00000e87, 0x00000e91, 0x00000eac, + 0x00000eb7, 0x00000eec, 0x00000efc, 0x00000f10, + 0x00000f16, 0x00000f25, 0x00000f36, 0x00000f3b, + 0x00000f4f, 0x00000f62, 0x00000f6c, 0x00000f7f, + 0x00000fa5, 0x00000fc9, 0x00000fee, 0x00001007, + 0x00001036, 0x00001061, 0x0000107b, 0x000010d0, // Entry C0 - DF - 0x00000f49, 0x00000f55, 0x00000f5c, 0x00000f65, - 0x00000f70, 0x00000f77, 0x00000f7e, 0x00000f90, - 0x00000f97, 0x00000fa0, 0x00000fa9, 0x00000fc8, - 0x00001007, 0x00001012, 0x00001023, 0x0000102a, - 0x00001039, 0x00001046, 0x0000105a, 0x000010ea, - 0x00001103, 0x0000111a, 0x00001122, 0x00001148, - 0x00001182, 0x00001197, 0x000011a7, 0x00001222, - 0x00001231, 0x00001248, 0x00001262, 0x00001282, + 0x0000112a, 0x00001139, 0x00001141, 0x00001147, + 0x00001153, 0x00001162, 0x00001175, 0x00001179, + 0x0000117c, 0x00001189, 0x00001195, 0x0000119c, + 0x000011a5, 0x000011b0, 0x000011b7, 0x000011be, + 0x000011d0, 0x000011d7, 0x000011e0, 0x000011e9, + 0x00001208, 0x00001247, 0x00001252, 0x00001263, + 0x0000126a, 0x00001279, 0x00001286, 0x0000129a, + 0x0000132a, 0x00001343, 0x0000135a, 0x00001362, // Entry E0 - FF - 0x000012a4, 0x000012b6, 0x000012ce, 0x000012de, - 0x000012f0, 0x0000130a, 0x00001317, 0x0000132c, - 0x0000133d, 0x00001346, 0x00001362, 0x00001399, - 0x000013b0, 0x000013e7, 0x00001402, 0x0000143b, - 0x00001445, 0x0000145d, 0x00001472, 0x000014a9, - 0x000014c4, 0x000014ca, 0x000014ef, 0x000014f9, - 0x00001513, 0x00001557, 0x00001581, 0x000015c0, - 0x000015d1, 0x000015f8, 0x0000161d, 0x0000164c, + 0x00001388, 0x000013c2, 0x000013d7, 0x000013e7, + 0x00001462, 0x00001471, 0x00001488, 0x000014a2, + 0x000014c2, 0x000014e4, 0x000014f6, 0x0000150e, + 0x0000151e, 0x00001530, 0x0000154a, 0x00001557, + 0x0000156c, 0x0000157d, 0x00001586, 0x000015a2, + 0x000015d9, 0x000015f0, 0x00001627, 0x00001642, + 0x0000167b, 0x00001685, 0x0000169d, 0x000016b2, + 0x000016e9, 0x00001704, 0x0000170a, 0x0000172f, // Entry 100 - 11F - 0x00001661, 0x00001690, 0x000016ac, -} // Size: 1060 bytes + 0x00001739, 0x00001753, 0x00001797, 0x000017c1, + 0x00001800, 0x00001811, 0x00001838, 0x0000185d, + 0x0000188c, 0x000018a1, 0x000018d0, 0x000018ec, +} // Size: 1096 bytes -const es_ESData string = "" + // Size: 5804 bytes +const es_ESData string = "" + // Size: 6380 bytes "\x02Versión: %[1]s\x02Versión FRP: %[1]s\x02Fecha de compilación: %[1]s" + "\x02Todos los archivos\x02Archivos de configuración\x02Archivos de certi" + "ficado\x02Archivos clave\x02Archivos de registro\x02Número fuera del ran" + @@ -582,54 +602,62 @@ const es_ESData string = "" + // Size: 5804 bytes "ticas experimentales\x02* Las siguientes características pueden afectar " + "la estabilidad del servicio.\x02Usar registros SVCB del servidor\x02La c" + "onfiguración ya existe\x02El nombre de configuración \x22%[1]s\x22 ya ex" + - "iste.\x02Nuevo Proxy\x02Editar Proxy - %[1]s\x02Aleatorio\x02Tipo\x02Rol" + - "e\x02Servidor\x02Visitante\x02Llave secreta\x02Dirección local\x02Puerto" + - " local\x02Puerto remoto\x02Permitir usuarios\x02Dirección de enlace\x02P" + - "uerto de enlace\x02Nombre del servidor\x02Usuario del servidor\x02Subdom" + - "inio\x02Dominios personalizados\x02Ruta URL\x02Solicitar encabezados\x02" + - "Multiplexor\x02Usuario de ruta\x02Cliente\x02Banda ancha\x02Protocolo pr" + - "oxy\x02auto\x02por defecto\x02Mantener túnel\x02Cifrado\x02Compresión" + - "\x02Número de reintentos\x02Veces/Hora\x02Intervalo de reintento\x02Repu" + - "esto\x02Interruptor de respaldo\x02milisegundo\x02Usuario HTTP\x02Contra" + - "seña HTTP\x02Reescritura de host\x02Enchufar\x02Nombre\x02Ruta Unix\x02S" + - "eleccione la ruta de Unix\x02Ruta local\x02Seleccione una carpeta para l" + - "a lista de directorios.\x02Prefijo de tira\x02Equilibrio de carga\x02Gru" + - "po\x02Clave de grupo\x02Chequeo de salud\x02Tipo\x02Se acabó el tiempo" + - "\x02Recuento de fallas\x02Intervalo\x02El proxy ya existe\x02El nombre d" + - "e proxy \x22%[1]s\x22 ya existe.\x02Abrir registro\x02Último\x02Ítem\x02" + - "Tipo de NAT\x02Comportamiento\x02Dirección externa\x02Sí\x02No\x02Red pú" + - "blica\x02Desconocido\x02Correr\x02Detenido\x02Comenzando\x02Parada\x02Es" + - "tado\x02Dirección remota\x02Copiar\x02Comienzo\x02Servicio\x02Detener co" + - "nfiguración \x22%[1]s\x22\x02¿Está seguro de que desea detener la config" + - "uración \x22%[1]s\x22?\x02Deténgase\x02Directorio local\x02Puerto\x02Pue" + - "rto abierto\x02Preferencias\x02Contraseña maestra\x02Puede establecer un" + - "a contraseña para restringir el acceso a este programa.\x0aSe le pedirá " + - "que lo ingrese la próxima vez que use este programa.\x02Usar contraseña " + - "maestra\x02Cambiar la contraseña\x02Idiomas\x02El idioma de visualizació" + - "n actual es\x02Debe reiniciar el programa para aplicar la modificación." + - "\x02Seleccione el idioma\x02Predeterminados\x02Defina el valor predeterm" + - "inado al crear una nueva configuración.\x0aEl valor aquí no afectará la " + - "configuración existente.\x02Valor ajustado\x02Contraseña eliminada.\x02N" + - "ueva contraseña maestra\x02Escriba la contraseña otra vez\x02La contrase" + - "ña está configurada.\x02Nivel de registro\x02Retención de registros\x02" + - "Añadir rápido\x02Escritorio remoto\x02Servidor de archivos HTTP\x02Desha" + - "bilitar\x02Abrir configuración\x02Edición directa\x02Dominios\x02Copiar " + - "dirección de acceso\x02Esta función solo admite texto en formato INI o T" + - "OML.\x02Eliminar proxy \x22%[1]s\x22\x02¿Está seguro de que desea elimin" + - "ar el proxy \x22%[1]s\x22?\x02Deshabilitar proxy \x22%[1]s\x22\x02¿Está " + - "seguro de que desea desactivar el proxy \x22%[1]s\x22?\x02Habilitar\x02G" + - "ama de puertos pasivos\x02Administrador de FRP\x02* Admite importación p" + - "or lotes, un enlace por línea.\x02Renombrar automáticamente\x02Listo\x02" + - "Introduzca la lista de URL correcta.\x02Descargar\x02Introducir la contr" + - "aseña\x02Debe ingresar una contraseña de administración para operar %[1]" + - "s.\x02Ingrese la contraseña de administración\x02La contraseña es incorr" + - "ecta. Escriba la contraseña otra vez.\x02Entrada invalida\x02Ingrese un " + - "número de %.[1]f a %.[2]f.\x02Ingrese un número de %[1]s a %[2]s.\x02El " + - "texto no coincide con el patrón requerido.\x02Selección requerida\x02Sel" + - "eccione una de las opciones proporcionadas.\x02Se requiere una selección" + - "." + "iste.\x02No se puede actualizar su archivo de configuración debido a un " + + "error en la conversión del proxy. Verifique la configuración del proxy e" + + " inténtelo nuevamente.\x0a\x0aProxy incorrecto: %[1]s\x02Nuevo Proxy\x02" + + "Editar Proxy - %[1]s\x02Aleatorio\x02Tipo\x02Role\x02Servidor\x02Visitan" + + "te\x02Llave secreta\x02Dirección local\x02Puerto local\x02Puerto remoto" + + "\x02Permitir usuarios\x02Dirección de enlace\x02Puerto de enlace\x02Nomb" + + "re del servidor\x02Usuario del servidor\x02Subdominio\x02Dominios person" + + "alizados\x02Ruta URL\x02Solicitar encabezados\x02Multiplexor\x02Usuario " + + "de ruta\x02Cliente\x02Banda ancha\x02Protocolo proxy\x02auto\x02por defe" + + "cto\x02Mantener túnel\x02Cifrado\x02Compresión\x02Número de reintentos" + + "\x02Veces/Hora\x02Intervalo de reintento\x02Repuesto\x02Interruptor de r" + + "espaldo\x02milisegundo\x02Usuario HTTP\x02Contraseña HTTP\x02Reescritura" + + " de host\x02Enchufar\x02Nombre\x02Ruta Unix\x02Seleccione la ruta de Uni" + + "x\x02Ruta local\x02Seleccione una carpeta para la lista de directorios." + + "\x02Prefijo de tira\x02Equilibrio de carga\x02Grupo\x02Clave de grupo" + + "\x02Chequeo de salud\x02Tipo\x02Se acabó el tiempo\x02Recuento de fallas" + + "\x02Intervalo\x02El proxy ya existe\x02El nombre de proxy \x22%[1]s\x22 " + + "ya existe.\x02Se requiere puerto de vinculación.\x02Requiere puerto loca" + + "l o complemento.\x02Puerto local no válido.\x02Se requiere la URL de ver" + + "ificación de estado.\x02El complemento no admite puertos de rango.\x02Pu" + + "erto remoto no válido.\x02La cantidad de puertos locales debe ser la mis" + + "ma que la cantidad de puertos remotos.\x02Los dominios y subdominios per" + + "sonalizados deben tener al menos uno de estos configurados.\x02Abrir reg" + + "istro\x02Último\x02Ítem\x02Tipo de NAT\x02Comportamiento\x02Dirección ex" + + "terna\x02Sí\x02No\x02Red pública\x02Desconocido\x02Correr\x02Detenido" + + "\x02Comenzando\x02Parada\x02Estado\x02Dirección remota\x02Copiar\x02Comi" + + "enzo\x02Servicio\x02Detener configuración \x22%[1]s\x22\x02¿Está seguro " + + "de que desea detener la configuración \x22%[1]s\x22?\x02Deténgase\x02Dir" + + "ectorio local\x02Puerto\x02Puerto abierto\x02Preferencias\x02Contraseña " + + "maestra\x02Puede establecer una contraseña para restringir el acceso a e" + + "ste programa.\x0aSe le pedirá que lo ingrese la próxima vez que use este" + + " programa.\x02Usar contraseña maestra\x02Cambiar la contraseña\x02Idioma" + + "s\x02El idioma de visualización actual es\x02Debe reiniciar el programa " + + "para aplicar la modificación.\x02Seleccione el idioma\x02Predeterminados" + + "\x02Defina el valor predeterminado al crear una nueva configuración.\x0a" + + "El valor aquí no afectará la configuración existente.\x02Valor ajustado" + + "\x02Contraseña eliminada.\x02Nueva contraseña maestra\x02Escriba la cont" + + "raseña otra vez\x02La contraseña está configurada.\x02Nivel de registro" + + "\x02Retención de registros\x02Añadir rápido\x02Escritorio remoto\x02Serv" + + "idor de archivos HTTP\x02Deshabilitar\x02Abrir configuración\x02Edición " + + "directa\x02Dominios\x02Copiar dirección de acceso\x02Esta función solo a" + + "dmite texto en formato INI o TOML.\x02Eliminar proxy \x22%[1]s\x22\x02¿E" + + "stá seguro de que desea eliminar el proxy \x22%[1]s\x22?\x02Deshabilitar" + + " proxy \x22%[1]s\x22\x02¿Está seguro de que desea desactivar el proxy " + + "\x22%[1]s\x22?\x02Habilitar\x02Gama de puertos pasivos\x02Administrador " + + "de FRP\x02* Admite importación por lotes, un enlace por línea.\x02Renomb" + + "rar automáticamente\x02Listo\x02Introduzca la lista de URL correcta.\x02" + + "Descargar\x02Introducir la contraseña\x02Debe ingresar una contraseña de" + + " administración para operar %[1]s.\x02Ingrese la contraseña de administr" + + "ación\x02La contraseña es incorrecta. Escriba la contraseña otra vez." + + "\x02Entrada invalida\x02Ingrese un número de %.[1]f a %.[2]f.\x02Ingrese" + + " un número de %[1]s a %[2]s.\x02El texto no coincide con el patrón reque" + + "rido.\x02Selección requerida\x02Seleccione una de las opciones proporcio" + + "nadas.\x02Se requiere una selección." -var ja_JPIndex = []uint32{ // 259 elements +var ja_JPIndex = []uint32{ // 268 elements // Entry 0 - 1F 0x00000000, 0x00000018, 0x00000034, 0x0000004f, 0x00000068, 0x0000007b, 0x00000091, 0x000000a7, @@ -667,46 +695,48 @@ var ja_JPIndex = []uint32{ // 259 elements 0x00000bf3, 0x00000c27, 0x00000c37, 0x00000c4a, 0x00000ca7, 0x00000cd3, 0x00000cf5, 0x00000d28, // Entry 80 - 9F - 0x00000d3e, 0x00000d5c, 0x00000d69, 0x00000d73, - 0x00000d7a, 0x00000d84, 0x00000d91, 0x00000d9b, - 0x00000db4, 0x00000dca, 0x00000de0, 0x00000dfc, - 0x00000e15, 0x00000e2b, 0x00000e3b, 0x00000e54, - 0x00000e67, 0x00000e80, 0x00000e97, 0x00000eb3, - 0x00000ec9, 0x00000edf, 0x00000ef2, 0x00000efc, - 0x00000f18, 0x00000f1f, 0x00000f29, 0x00000f45, - 0x00000f4f, 0x00000f56, 0x00000f69, 0x00000f74, + 0x00000df5, 0x00000e0b, 0x00000e29, 0x00000e36, + 0x00000e40, 0x00000e47, 0x00000e51, 0x00000e5e, + 0x00000e68, 0x00000e81, 0x00000e97, 0x00000ead, + 0x00000ec9, 0x00000ee2, 0x00000ef8, 0x00000f08, + 0x00000f21, 0x00000f34, 0x00000f4d, 0x00000f64, + 0x00000f80, 0x00000f96, 0x00000fac, 0x00000fbf, + 0x00000fc9, 0x00000fe5, 0x00000fec, 0x00000ff6, + 0x00001012, 0x0000101c, 0x00001023, 0x00001036, // Entry A0 - BF - 0x00000f84, 0x00000f8b, 0x00000fb3, 0x00000fbd, - 0x00000fcf, 0x00000fe4, 0x00000ffd, 0x0000100d, - 0x00001020, 0x0000102c, 0x00001041, 0x00001054, - 0x00001094, 0x000010b3, 0x000010c0, 0x000010cd, - 0x000010e3, 0x000010f0, 0x000010fa, 0x0000110d, - 0x00001117, 0x0000112a, 0x00001152, 0x0000118b, - 0x000011a7, 0x000011ae, 0x000011b5, 0x000011c3, - 0x000011ca, 0x000011dd, 0x000011e4, 0x000011ee, + 0x00001041, 0x00001051, 0x00001058, 0x00001080, + 0x0000108a, 0x0000109c, 0x000010b1, 0x000010ca, + 0x000010da, 0x000010ed, 0x000010f9, 0x0000110e, + 0x00001121, 0x00001161, 0x00001180, 0x0000118d, + 0x0000119a, 0x000011b0, 0x000011bd, 0x000011c7, + 0x000011da, 0x000011e4, 0x000011f7, 0x0000121f, + 0x00001258, 0x00001280, 0x000012c0, 0x000012e8, + 0x00001316, 0x0000135c, 0x00001384, 0x000013ea, // Entry C0 - DF - 0x0000120a, 0x0000121a, 0x0000122a, 0x00001231, - 0x00001238, 0x0000123f, 0x00001246, 0x0000125f, - 0x00001269, 0x00001273, 0x00001280, 0x000012a4, - 0x000012de, 0x000012e8, 0x000012f5, 0x000012ff, - 0x0000130f, 0x0000131c, 0x00001338, 0x000013f4, - 0x0000141f, 0x0000143e, 0x00001445, 0x0000145e, - 0x000014b6, 0x000014cc, 0x000014dc, 0x0000156b, - 0x00001584, 0x000015af, 0x000015d4, 0x000015de, + 0x00001479, 0x00001495, 0x0000149c, 0x000014a3, + 0x000014b1, 0x000014b8, 0x000014cb, 0x000014d2, + 0x000014dc, 0x000014f8, 0x00001508, 0x00001518, + 0x0000151f, 0x00001526, 0x0000152d, 0x00001534, + 0x0000154d, 0x00001557, 0x00001561, 0x0000156e, + 0x00001592, 0x000015cc, 0x000015d6, 0x000015e3, + 0x000015ed, 0x000015fd, 0x0000160a, 0x00001626, + 0x000016e2, 0x0000170d, 0x0000172c, 0x00001733, // Entry E0 - FF - 0x0000160c, 0x0000161c, 0x00001629, 0x0000163c, - 0x0000165b, 0x00001679, 0x00001680, 0x00001690, - 0x0000169d, 0x000016ad, 0x000016d2, 0x0000172e, - 0x00001758, 0x00001798, 0x000017c2, 0x00001805, - 0x0000180c, 0x00001828, 0x0000183c, 0x0000189b, - 0x000018b7, 0x000018be, 0x000018f2, 0x00001905, - 0x00001924, 0x0000197f, 0x000019a1, 0x000019eb, - 0x000019f8, 0x00001a3b, 0x00001a7c, 0x00001ab9, + 0x0000174c, 0x000017a4, 0x000017ba, 0x000017ca, + 0x00001859, 0x00001872, 0x0000189d, 0x000018c2, + 0x000018cc, 0x000018fa, 0x0000190a, 0x00001917, + 0x0000192a, 0x00001949, 0x00001967, 0x0000196e, + 0x0000197e, 0x0000198b, 0x0000199b, 0x000019c0, + 0x00001a1c, 0x00001a46, 0x00001a86, 0x00001ab0, + 0x00001af3, 0x00001afa, 0x00001b16, 0x00001b2a, + 0x00001b89, 0x00001ba5, 0x00001bac, 0x00001be0, // Entry 100 - 11F - 0x00001ac6, 0x00001b12, 0x00001b2b, -} // Size: 1060 bytes + 0x00001bf3, 0x00001c12, 0x00001c6d, 0x00001c8f, + 0x00001cd9, 0x00001ce6, 0x00001d29, 0x00001d6a, + 0x00001da7, 0x00001db4, 0x00001e00, 0x00001e19, +} // Size: 1096 bytes -const ja_JPData string = "" + // Size: 6955 bytes +const ja_JPData string = "" + // Size: 7705 bytes "\x02バージョン:%[1]s\x02FRP バージョン:%[1]s\x02コンパイル日:%[1]s\x02すべてのファイル\x02設定ファイル" + "\x02証明書ファイル\x02秘密鍵ファイル\x02ログファイル\x02許容範囲外の数値\x02%[1]d より大きい数値を入力してください。" + "\x02パスワードの不一致\x02もう一度確認してください。\x02数字ではありません\x02有効な数値を入力してください。\x02新しいバージ" + @@ -731,34 +761,38 @@ const ja_JPData string = "" + // Size: 6955 bytes "イルを選択します\x02カスタムの先頭バイトを無効にする\x02高度\x02送信元アドレス\x02多重化\x02ログイン失敗後に終了\x02" + "起動時に自動起動を無効にする\x02従来の形式の設定ファイルを使用する\x02メタデータ\x02実験的な機能\x02* 以下の機能はサービス" + "の安定性に影響を与える可能性があります。\x02サーバーSVCBレコードを使用する\x02設定はすでに存在します\x02設定名「%[1]s」" + - "はすでに存在します。\x02新しいプロキシ\x02プロキシの編集 - %[1]s\x02ランダム\x02タイプ\x02役割\x02サーバ" + - "\x02ビジター\x02秘密鍵\x02ローカルアドレス\x02ローカルポート\x02リモートポート\x02ユーザーを許可する\x02バインドアド" + - "レス\x02バインドポート\x02サーバー名\x02サーバーユーザー\x02サブドメイン\x02カスタムドメイン\x02URL ルーティング" + - "\x02リクエストヘッダー\x02マルチプレクサ\x02ルートユーザー\x02クライアント\x02帯域幅\x02プロキシプロトコル\x02自動" + - "\x02既定値\x02トンネルを維持する\x02暗号化\x02圧縮\x02リトライ回数\x02回/時間\x02再試行間隔\x02代替\x02フォ" + - "ールバックタイムアウト\x02ミリ秒\x02HTTP ユーザー\x02HTTP パスワード\x02ホストの書き換え\x02プラグイン\x02" + - "プラグイン名\x02Unix パス\x02Unix パスを選択\x02ローカルパス\x02ディレクトリリストのフォルダを選択します。\x02" + - "プレフィックスを削除\x02負荷平衡\x02グループ\x02グループ秘密鍵\x02健康診断\x02タイプ\x02タイムアウト\x02失敗数" + - "\x02チェック間隔\x02プロキシはすでに存在します\x02プロキシ名「%[1]s」はすでに存在します。\x02ログフォルダを開く\x02最新" + - "\x02項目\x02NAT タイプ\x02挙動\x02外部アドレス\x02はい\x02いいえ\x02公共のネットワーク\x02わからない\x02" + - "ランニング\x02停止\x02起動\x02停止\x02状態\x02リモートアドレス\x02コピー\x02始める\x02サービス\x02設定「" + - "%[1]s」を停止します\x02設定「%[1]s」を停止してもよろしいですか?\x02止まる\x02フォルダ\x02ポート\x02ポート開放" + - "\x02環境設定\x02マスターパスワード\x02パスワードを設定して、このプログラムへのアクセスを制限できます。\x0a次回このプログラムを使" + - "用するときに入力するよう求められます。\x02マスターパスワードを使用する\x02パスワードを変更する\x02言語\x02現在の表示言語は" + - "\x02変更を適用するには、プログラムを再起動する必要があります。\x02言語を選択する\x02デフォルト\x02新しい設定を作成するときのデフ" + - "ォルト値を定義します。\x0aここでの値は、既存の設定には影響しません。\x02デフォルトの設定\x02パスワードが解除されました。\x02" + - "新しいマスターパスワード\x02再入力\x02パスワードが設定されています。\x02ログレベル\x02ログ保持\x02クイック追加\x02リ" + - "モートデスクトップ\x02HTTP ファイルサーバー\x02無効\x02設定を開く\x02直接編集\x02ドメイン名\x02アクセスアドレス" + - "のコピー\x02この機能は、INI または TOML 形式のテキストのみをサポートします。\x02プロキシ「%[1]s」を削除します\x02" + - "プロキシ「%[1]s」を削除してもよろしいですか?\x02プロキシ「%[1]s」を無効にする\x02プロキシ「%[1]s」を無効にしてもよろ" + - "しいですか?\x02有効\x02パッシブポート範囲\x02FRP マネージャ\x02* バッチインポートをサポートします、1行に1つのリンク" + - "があります。\x02自動的に名前を変更\x02準備\x02正しいURLリストを入力してください。\x02ダウンロード\x02パスワードを入力" + - "する\x02%[1]s を操作するには、管理パスワードを入力する必要があります。\x02管理者パスワードを入力\x02パスワードが正しくあり" + - "ません。 パスワード再入力。\x02無効入力\x02%.[1]f から %.[2]f までの数字を入力してください。\x02%[1]s から" + - " %[2]s までの数値を入力してください。\x02テキストが必要なパターンと一致しません。\x02選択必須\x02提供されたオプションのいずれ" + - "かを選択してください。\x02選択が必要です。" + "はすでに存在します。\x02プロキシ変換が失敗したため、設定ファイルをアップグレードできません。プロキシ設定を確認して、もう一度試してくださ" + + "い。\x0a\x0a不正なプロキシ: %[1]s\x02新しいプロキシ\x02プロキシの編集 - %[1]s\x02ランダム\x02タイプ" + + "\x02役割\x02サーバ\x02ビジター\x02秘密鍵\x02ローカルアドレス\x02ローカルポート\x02リモートポート\x02ユーザーを許" + + "可する\x02バインドアドレス\x02バインドポート\x02サーバー名\x02サーバーユーザー\x02サブドメイン\x02カスタムドメイン" + + "\x02URL ルーティング\x02リクエストヘッダー\x02マルチプレクサ\x02ルートユーザー\x02クライアント\x02帯域幅\x02プロ" + + "キシプロトコル\x02自動\x02既定値\x02トンネルを維持する\x02暗号化\x02圧縮\x02リトライ回数\x02回/時間\x02再試" + + "行間隔\x02代替\x02フォールバックタイムアウト\x02ミリ秒\x02HTTP ユーザー\x02HTTP パスワード\x02ホストの書き" + + "換え\x02プラグイン\x02プラグイン名\x02Unix パス\x02Unix パスを選択\x02ローカルパス\x02ディレクトリリストの" + + "フォルダを選択します。\x02プレフィックスを削除\x02負荷平衡\x02グループ\x02グループ秘密鍵\x02健康診断\x02タイプ" + + "\x02タイムアウト\x02失敗数\x02チェック間隔\x02プロキシはすでに存在します\x02プロキシ名「%[1]s」はすでに存在します。" + + "\x02バインドポートは必須です。\x02ローカルポートまたはプラグインが必要です。\x02ローカルポートが無効です。\x02ヘルスチェックのU" + + "RLは必須です。\x02プラグインは範囲ポートをサポートしていません。\x02無効なリモートポートです。\x02ローカル ポートの数はリモート " + + "ポートの数と同じである必要があります。\x02カスタム ドメインとサブドメインには、これらのうち少なくとも 1 つが設定されている必要があり" + + "ます。\x02ログフォルダを開く\x02最新\x02項目\x02NAT タイプ\x02挙動\x02外部アドレス\x02はい\x02いいえ" + + "\x02公共のネットワーク\x02わからない\x02ランニング\x02停止\x02起動\x02停止\x02状態\x02リモートアドレス\x02コ" + + "ピー\x02始める\x02サービス\x02設定「%[1]s」を停止します\x02設定「%[1]s」を停止してもよろしいですか?\x02止まる" + + "\x02フォルダ\x02ポート\x02ポート開放\x02環境設定\x02マスターパスワード\x02パスワードを設定して、このプログラムへのアクセ" + + "スを制限できます。\x0a次回このプログラムを使用するときに入力するよう求められます。\x02マスターパスワードを使用する\x02パスワード" + + "を変更する\x02言語\x02現在の表示言語は\x02変更を適用するには、プログラムを再起動する必要があります。\x02言語を選択する" + + "\x02デフォルト\x02新しい設定を作成するときのデフォルト値を定義します。\x0aここでの値は、既存の設定には影響しません。\x02デフォル" + + "トの設定\x02パスワードが解除されました。\x02新しいマスターパスワード\x02再入力\x02パスワードが設定されています。\x02ログ" + + "レベル\x02ログ保持\x02クイック追加\x02リモートデスクトップ\x02HTTP ファイルサーバー\x02無効\x02設定を開く" + + "\x02直接編集\x02ドメイン名\x02アクセスアドレスのコピー\x02この機能は、INI または TOML 形式のテキストのみをサポートしま" + + "す。\x02プロキシ「%[1]s」を削除します\x02プロキシ「%[1]s」を削除してもよろしいですか?\x02プロキシ「%[1]s」を無効" + + "にする\x02プロキシ「%[1]s」を無効にしてもよろしいですか?\x02有効\x02パッシブポート範囲\x02FRP マネージャ\x02*" + + " バッチインポートをサポートします、1行に1つのリンクがあります。\x02自動的に名前を変更\x02準備\x02正しいURLリストを入力してくだ" + + "さい。\x02ダウンロード\x02パスワードを入力する\x02%[1]s を操作するには、管理パスワードを入力する必要があります。\x02管" + + "理者パスワードを入力\x02パスワードが正しくありません。 パスワード再入力。\x02無効入力\x02%.[1]f から %.[2]f まで" + + "の数字を入力してください。\x02%[1]s から %[2]s までの数値を入力してください。\x02テキストが必要なパターンと一致しません" + + "。\x02選択必須\x02提供されたオプションのいずれかを選択してください。\x02選択が必要です。" -var ko_KRIndex = []uint32{ // 259 elements +var ko_KRIndex = []uint32{ // 268 elements // Entry 0 - 1F 0x00000000, 0x0000000e, 0x00000020, 0x00000035, 0x00000043, 0x00000051, 0x00000062, 0x00000070, @@ -796,46 +830,48 @@ var ko_KRIndex = []uint32{ // 259 elements 0x000009c5, 0x000009eb, 0x000009fb, 0x00000a0c, 0x00000a5c, 0x00000a76, 0x00000a95, 0x00000acc, // Entry 80 - 9F - 0x00000ada, 0x00000af3, 0x00000b00, 0x00000b07, - 0x00000b0e, 0x00000b15, 0x00000b1f, 0x00000b2a, - 0x00000b38, 0x00000b46, 0x00000b54, 0x00000b65, - 0x00000b76, 0x00000b87, 0x00000b95, 0x00000ba6, - 0x00000bb7, 0x00000bd2, 0x00000be0, 0x00000bee, - 0x00000bfe, 0x00000c0f, 0x00000c1f, 0x00000c29, - 0x00000c40, 0x00000c47, 0x00000c51, 0x00000c5f, - 0x00000c69, 0x00000c70, 0x00000c81, 0x00000c8c, + 0x00000b79, 0x00000b87, 0x00000ba0, 0x00000bad, + 0x00000bb4, 0x00000bbb, 0x00000bc2, 0x00000bcc, + 0x00000bd7, 0x00000be5, 0x00000bf3, 0x00000c01, + 0x00000c12, 0x00000c23, 0x00000c34, 0x00000c42, + 0x00000c53, 0x00000c64, 0x00000c7f, 0x00000c8d, + 0x00000c9b, 0x00000cab, 0x00000cbc, 0x00000ccc, + 0x00000cd6, 0x00000ced, 0x00000cf4, 0x00000cfe, + 0x00000d0c, 0x00000d16, 0x00000d1d, 0x00000d2e, // Entry A0 - BF - 0x00000c9d, 0x00000ca4, 0x00000cb9, 0x00000cc3, - 0x00000cd2, 0x00000ce4, 0x00000cf8, 0x00000d05, - 0x00000d19, 0x00000d25, 0x00000d38, 0x00000d46, - 0x00000d82, 0x00000d96, 0x00000da4, 0x00000dab, - 0x00000dbd, 0x00000dcb, 0x00000dd2, 0x00000de0, - 0x00000dee, 0x00000df5, 0x00000e17, 0x00000e51, - 0x00000e66, 0x00000e6d, 0x00000e74, 0x00000e7f, - 0x00000e86, 0x00000e94, 0x00000e98, 0x00000ea2, + 0x00000d39, 0x00000d4a, 0x00000d51, 0x00000d66, + 0x00000d70, 0x00000d7f, 0x00000d91, 0x00000da5, + 0x00000db2, 0x00000dc6, 0x00000dd2, 0x00000de5, + 0x00000df3, 0x00000e2f, 0x00000e43, 0x00000e51, + 0x00000e58, 0x00000e6a, 0x00000e78, 0x00000e7f, + 0x00000e8d, 0x00000e9b, 0x00000ea2, 0x00000ec4, + 0x00000efe, 0x00000f23, 0x00000f59, 0x00000f81, + 0x00000fa7, 0x00000fe3, 0x0000100b, 0x0000104d, // Entry C0 - DF - 0x00000eb6, 0x00000eca, 0x00000ed4, 0x00000ede, - 0x00000ee5, 0x00000eec, 0x00000ef3, 0x00000f01, - 0x00000f08, 0x00000f0f, 0x00000f19, 0x00000f2f, - 0x00000f5b, 0x00000f62, 0x00000f76, 0x00000f7d, - 0x00000f8b, 0x00000f92, 0x00000fa9, 0x00001065, - 0x00001083, 0x00001097, 0x0000109e, 0x000010b6, - 0x00001102, 0x00001110, 0x0000111a, 0x00001192, - 0x000011a9, 0x000011ca, 0x000011e5, 0x000011fc, + 0x000010ba, 0x000010cf, 0x000010d6, 0x000010dd, + 0x000010e8, 0x000010ef, 0x000010fd, 0x00001101, + 0x0000110b, 0x0000111f, 0x00001133, 0x0000113d, + 0x00001147, 0x0000114e, 0x00001155, 0x0000115c, + 0x0000116a, 0x00001171, 0x00001178, 0x00001182, + 0x00001198, 0x000011c4, 0x000011cb, 0x000011df, + 0x000011e6, 0x000011f4, 0x000011fb, 0x00001212, + 0x000012ce, 0x000012ec, 0x00001300, 0x00001307, // Entry E0 - FF - 0x00001227, 0x00001235, 0x00001243, 0x00001251, - 0x00001265, 0x00001278, 0x0000127f, 0x0000128d, - 0x0000129b, 0x000012a5, 0x000012bd, 0x00001303, - 0x0000131c, 0x0000134b, 0x0000136a, 0x0000139f, - 0x000013a6, 0x000013be, 0x000013cc, 0x00001415, - 0x00001433, 0x00001441, 0x0000146a, 0x00001477, - 0x00001488, 0x000014cf, 0x000014ea, 0x0000153d, - 0x0000154e, 0x00001586, 0x000015c0, 0x000015f9, + 0x0000131f, 0x0000136b, 0x00001379, 0x00001383, + 0x000013fb, 0x00001412, 0x00001433, 0x0000144e, + 0x00001465, 0x00001490, 0x0000149e, 0x000014ac, + 0x000014ba, 0x000014ce, 0x000014e1, 0x000014e8, + 0x000014f6, 0x00001504, 0x0000150e, 0x00001526, + 0x0000156c, 0x00001585, 0x000015b4, 0x000015d3, + 0x00001608, 0x0000160f, 0x00001627, 0x00001635, + 0x0000167e, 0x0000169c, 0x000016aa, 0x000016d3, // Entry 100 - 11F - 0x00001607, 0x0000163a, 0x00001655, -} // Size: 1060 bytes + 0x000016e0, 0x000016f1, 0x00001738, 0x00001753, + 0x000017a6, 0x000017b7, 0x000017ef, 0x00001829, + 0x00001862, 0x00001870, 0x000018a3, 0x000018be, +} // Size: 1096 bytes -const ko_KRData string = "" + // Size: 5717 bytes +const ko_KRData string = "" + // Size: 6334 bytes "\x02버전: %[1]s\x02FRP 버전: %[1]s\x02빌드 날짜: %[1]s\x02모든 파일\x02구성 파일\x02인증서 " + "파일\x02열쇠 파일\x02로그 파일\x02허용 범위를 벗어난 숫자\x02%[1]d보다 큰 숫자를 입력하세요.\x02암호 불일" + "치\x02확인하고 다시 시도해 주세요.\x02숫자가 아님\x02유효한 숫자를 입력하세요.\x02새로운 버전!\x02에 대한" + @@ -859,34 +895,38 @@ const ko_KRData string = "" + // Size: 5717 bytes "\x02신뢰할 수 있는 CA 파일 선택\x02맞춤 첫 번째 바이트 비활성화\x02고급의\x02소스 주소\x02다중화\x02로그인 " + "실패 후 종료\x02부팅 시 자동 시작 비활성화\x02레거시 형식 구성 파일 사용\x02메타데이터\x02실험적 기능\x02* " + "다음 기능은 서비스의 안정성에 영향을 미칠 수 있습니다.\x02서버 SVCB 기록 사용\x02구성이 이미 있습니다.\x02구성" + - " 이름 \x22%[1]s\x22 이(가) 이미 존재합니다.\x02새 프록시\x02프록시 편집 - %[1]s\x02무작위의\x02유" + - "형\x02역할\x02서버\x02방문객\x02비밀 키\x02지역 주소\x02로컬 포트\x02원격 포트\x02사용자 허용\x02바" + - "인드 주소\x02바인드 포트\x02서버 이름\x02서버 사용자\x02하위 도메인\x02사용자 정의 도메인\x02URL 라우팅" + - "\x02요청 헤더\x02멀티플렉서\x02경로 사용자\x02클라이언트\x02대역폭\x02프록시 프로토콜\x02자동\x02기본값" + - "\x02터널 유지\x02암호화\x02압축\x02재시도 횟수\x02회/시간\x02재시도 간격\x02폴백\x02대체 시간 초과\x02" + - "밀리초\x02HTTP 사용자\x02HTTP 비밀번호\x02호스트 재작성\x02플러그인\x02플러그인 이름\x02Unix 경로" + - "\x02선택 Unix 경로\x02로컬 경로\x02디렉토리 목록에 대한 폴더를 선택하십시오.\x02스트립 접두사\x02부하 분산" + - "\x02그룹\x02그룹 비밀 키\x02건강 체크\x02유형\x02시간 초과\x02실패 횟수\x02간격\x02프록시가 이미 있습니다" + - ".\x02프록시 이름 \x22%[1]s\x22 이(가) 이미 존재합니다.\x02로그 폴더 열기\x02최신\x02안건\x02NAT " + - "유형\x02행실\x02외부 주소\x02예\x02아니요\x02공용 네트워크\x02알려지지 않은\x02달리기\x02중지됨\x02시" + - "작\x02멎는\x02상태\x02원격 주소\x02복사\x02시작\x02서비스\x02\x22%[1]s\x22 구성 중지\x02" + - "\x22%[1]s\x22 구성을 중지하시겠습니까?\x02중지\x02로컬 디렉토리\x02포트\x02오픈 포트\x02옵션\x02마스터" + - " 비밀번호\x02이 프로그램에 대한 액세스를 제한하기 위해 암호를 설정할 수 있습니다.\x0a다음에 이 프로그램을 사용할 때 입력" + - "하라는 메시지가 표시됩니다.\x02마스터 비밀번호 사용\x02비밀번호 변경\x02언어\x02현재 표시 언어는\x02수정 사항을" + - " 적용하려면 프로그램을 재시작해야 합니다.\x02언어 선택\x02기본값\x02새 구성을 만들 때 기본값을 정의합니다.\x0a여기의" + - " 값은 기존 구성에 영향을 주지 않습니다.\x02기본값으로 설정\x02암호가 제거되었습니다.\x02새 마스터 비밀번호\x02비밀번" + - "호 재입력\x02비밀번호가 설정되어 있습니다.\x02로그 수준\x02로그 보존\x02빠른 추가\x02원격 데스크탑\x02HTT" + - "P 파일 서버\x02폐쇄\x02구성 열기\x02직접 편집\x02도메인\x02액세스 주소 복사\x02이 기능은 INI 또는 TOML" + - " 형식의 텍스트만 지원합니다.\x02프록시 \x22%[1]s\x22 삭제\x02\x22%[1]s\x22 프록시를 삭제하시겠습니까?" + - "\x02프록시 \x22%[1]s\x22 비활성화\x02\x22%[1]s\x22 프록시를 비활성화하시겠습니까?\x02켜다\x02패시" + - "브 포트 범위\x02FRP 관리자\x02* 한 줄에 하나의 링크로 일괄 가져오기를 지원합니다.\x02자동으로 이름 바꾸기" + - "\x02준비가 된\x02올바른 URL 목록을 입력하세요.\x02다운로드\x02암호를 입력\x02%[1]s을(를) 작동하려면 관리 " + - "암호를 입력해야 합니다.\x02관리 비밀번호 입력\x02비밀번호가 올바르지 않습니다. 비밀번호를 다시 입력하세요.\x02잘못된" + - " 입력\x02%.[1]f에서 %.[2]f까지의 숫자를 입력하세요.\x02%[1]s에서 %[2]s 사이의 숫자를 입력하십시오." + - "\x02텍스트가 필수 패턴과 일치하지 않습니다.\x02선택 필수\x02제공된 옵션 중 하나를 선택하십시오.\x02선택이 필요합니다" + - "." + " 이름 \x22%[1]s\x22 이(가) 이미 존재합니다.\x02프록시 변환 실패로 인해 구성 파일을 업그레이드할 수 없습니다. " + + "프록시 구성을 확인하고 다시 시도하세요.\x0a\x0a잘못된 프록시: %[1]s\x02새 프록시\x02프록시 편집 - %[1]" + + "s\x02무작위의\x02유형\x02역할\x02서버\x02방문객\x02비밀 키\x02지역 주소\x02로컬 포트\x02원격 포트" + + "\x02사용자 허용\x02바인드 주소\x02바인드 포트\x02서버 이름\x02서버 사용자\x02하위 도메인\x02사용자 정의 도메" + + "인\x02URL 라우팅\x02요청 헤더\x02멀티플렉서\x02경로 사용자\x02클라이언트\x02대역폭\x02프록시 프로토콜" + + "\x02자동\x02기본값\x02터널 유지\x02암호화\x02압축\x02재시도 횟수\x02회/시간\x02재시도 간격\x02폴백" + + "\x02대체 시간 초과\x02밀리초\x02HTTP 사용자\x02HTTP 비밀번호\x02호스트 재작성\x02플러그인\x02플러그인 " + + "이름\x02Unix 경로\x02선택 Unix 경로\x02로컬 경로\x02디렉토리 목록에 대한 폴더를 선택하십시오.\x02스트립" + + " 접두사\x02부하 분산\x02그룹\x02그룹 비밀 키\x02건강 체크\x02유형\x02시간 초과\x02실패 횟수\x02간격" + + "\x02프록시가 이미 있습니다.\x02프록시 이름 \x22%[1]s\x22 이(가) 이미 존재합니다.\x02바인드 포트가 필요합니" + + "다.\x02로컬 포트 또는 플러그인이 필요합니다.\x02로컬 포트가 잘못되었습니다.\x02상태 확인 URL이 필요합니다." + + "\x02플러그인은 범위 포트를 지원하지 않습니다.\x02원격 포트가 잘못되었습니다.\x02로컬 포트 수는 원격 포트 수와 동일해야" + + " 합니다.\x02사용자 정의 도메인 및 하위 도메인에는 이러한 세트가 하나 이상 있어야 합니다.\x02로그 폴더 열기\x02최신" + + "\x02안건\x02NAT 유형\x02행실\x02외부 주소\x02예\x02아니요\x02공용 네트워크\x02알려지지 않은\x02달리기" + + "\x02중지됨\x02시작\x02멎는\x02상태\x02원격 주소\x02복사\x02시작\x02서비스\x02\x22%[1]s\x22 구" + + "성 중지\x02\x22%[1]s\x22 구성을 중지하시겠습니까?\x02중지\x02로컬 디렉토리\x02포트\x02오픈 포트" + + "\x02옵션\x02마스터 비밀번호\x02이 프로그램에 대한 액세스를 제한하기 위해 암호를 설정할 수 있습니다.\x0a다음에 이 프" + + "로그램을 사용할 때 입력하라는 메시지가 표시됩니다.\x02마스터 비밀번호 사용\x02비밀번호 변경\x02언어\x02현재 표시 " + + "언어는\x02수정 사항을 적용하려면 프로그램을 재시작해야 합니다.\x02언어 선택\x02기본값\x02새 구성을 만들 때 기본값" + + "을 정의합니다.\x0a여기의 값은 기존 구성에 영향을 주지 않습니다.\x02기본값으로 설정\x02암호가 제거되었습니다.\x02" + + "새 마스터 비밀번호\x02비밀번호 재입력\x02비밀번호가 설정되어 있습니다.\x02로그 수준\x02로그 보존\x02빠른 추가" + + "\x02원격 데스크탑\x02HTTP 파일 서버\x02폐쇄\x02구성 열기\x02직접 편집\x02도메인\x02액세스 주소 복사" + + "\x02이 기능은 INI 또는 TOML 형식의 텍스트만 지원합니다.\x02프록시 \x22%[1]s\x22 삭제\x02\x22%[1" + + "]s\x22 프록시를 삭제하시겠습니까?\x02프록시 \x22%[1]s\x22 비활성화\x02\x22%[1]s\x22 프록시를 비활" + + "성화하시겠습니까?\x02켜다\x02패시브 포트 범위\x02FRP 관리자\x02* 한 줄에 하나의 링크로 일괄 가져오기를 지원합" + + "니다.\x02자동으로 이름 바꾸기\x02준비가 된\x02올바른 URL 목록을 입력하세요.\x02다운로드\x02암호를 입력" + + "\x02%[1]s을(를) 작동하려면 관리 암호를 입력해야 합니다.\x02관리 비밀번호 입력\x02비밀번호가 올바르지 않습니다. 비" + + "밀번호를 다시 입력하세요.\x02잘못된 입력\x02%.[1]f에서 %.[2]f까지의 숫자를 입력하세요.\x02%[1]s에서 %" + + "[2]s 사이의 숫자를 입력하십시오.\x02텍스트가 필수 패턴과 일치하지 않습니다.\x02선택 필수\x02제공된 옵션 중 하나를 " + + "선택하십시오.\x02선택이 필요합니다." -var zh_CNIndex = []uint32{ // 259 elements +var zh_CNIndex = []uint32{ // 268 elements // Entry 0 - 1F 0x00000000, 0x0000000f, 0x00000022, 0x00000037, 0x00000044, 0x00000051, 0x0000005e, 0x0000006b, @@ -924,46 +964,48 @@ var zh_CNIndex = []uint32{ // 259 elements 0x000007dc, 0x000007f8, 0x00000802, 0x00000812, 0x00000845, 0x00000861, 0x00000871, 0x00000892, // Entry 80 - 9F - 0x0000089f, 0x000008b4, 0x000008c1, 0x000008c8, - 0x000008cf, 0x000008d9, 0x000008e3, 0x000008ea, - 0x000008f7, 0x00000904, 0x00000911, 0x0000091e, - 0x0000092b, 0x00000938, 0x00000945, 0x00000952, - 0x0000095c, 0x0000096c, 0x00000977, 0x00000981, - 0x0000098b, 0x00000998, 0x000009a2, 0x000009af, - 0x000009bc, 0x000009c3, 0x000009ca, 0x000009d7, - 0x000009e4, 0x000009f1, 0x000009fe, 0x00000a09, + 0x00000909, 0x00000916, 0x0000092b, 0x00000938, + 0x0000093f, 0x00000946, 0x00000950, 0x0000095a, + 0x00000961, 0x0000096e, 0x0000097b, 0x00000988, + 0x00000995, 0x000009a2, 0x000009af, 0x000009bc, + 0x000009c9, 0x000009d3, 0x000009e3, 0x000009ee, + 0x000009f8, 0x00000a02, 0x00000a0f, 0x00000a19, + 0x00000a26, 0x00000a33, 0x00000a3a, 0x00000a41, + 0x00000a4e, 0x00000a5b, 0x00000a68, 0x00000a75, // Entry A0 - BF - 0x00000a16, 0x00000a1d, 0x00000a2a, 0x00000a31, - 0x00000a3d, 0x00000a49, 0x00000a55, 0x00000a5c, - 0x00000a69, 0x00000a75, 0x00000a88, 0x00000a95, - 0x00000ac3, 0x00000ad0, 0x00000add, 0x00000aea, - 0x00000af7, 0x00000b04, 0x00000b11, 0x00000b1e, - 0x00000b2b, 0x00000b38, 0x00000b48, 0x00000b69, - 0x00000b7f, 0x00000b86, 0x00000b8d, 0x00000b98, - 0x00000b9f, 0x00000bac, 0x00000bb0, 0x00000bb4, + 0x00000a80, 0x00000a8d, 0x00000a94, 0x00000aa1, + 0x00000aa8, 0x00000ab4, 0x00000ac0, 0x00000acc, + 0x00000ad3, 0x00000ae0, 0x00000aec, 0x00000aff, + 0x00000b0c, 0x00000b3a, 0x00000b47, 0x00000b54, + 0x00000b61, 0x00000b6e, 0x00000b7b, 0x00000b88, + 0x00000b95, 0x00000ba2, 0x00000baf, 0x00000bbf, + 0x00000be0, 0x00000bfc, 0x00000c21, 0x00000c3a, + 0x00000c5b, 0x00000c7a, 0x00000c93, 0x00000ccd, // Entry C0 - DF - 0x00000bbb, 0x00000bc2, 0x00000bcf, 0x00000bd9, - 0x00000be6, 0x00000bf3, 0x00000bfa, 0x00000c07, - 0x00000c0e, 0x00000c15, 0x00000c1c, 0x00000c34, - 0x00000c5b, 0x00000c62, 0x00000c6f, 0x00000c76, - 0x00000c83, 0x00000c8a, 0x00000c94, 0x00000d02, - 0x00000d12, 0x00000d1f, 0x00000d26, 0x00000d3c, - 0x00000d6d, 0x00000d7a, 0x00000d84, 0x00000dd4, - 0x00000de4, 0x00000df7, 0x00000e04, 0x00000e11, + 0x00000d07, 0x00000d1d, 0x00000d24, 0x00000d2b, + 0x00000d36, 0x00000d3d, 0x00000d4a, 0x00000d4e, + 0x00000d52, 0x00000d59, 0x00000d60, 0x00000d6d, + 0x00000d77, 0x00000d84, 0x00000d91, 0x00000d98, + 0x00000da5, 0x00000dac, 0x00000db3, 0x00000dba, + 0x00000dd2, 0x00000df9, 0x00000e00, 0x00000e0d, + 0x00000e14, 0x00000e21, 0x00000e28, 0x00000e32, + 0x00000ea0, 0x00000eb0, 0x00000ebd, 0x00000ec4, // Entry E0 - FF - 0x00000e24, 0x00000e31, 0x00000e3e, 0x00000e4b, - 0x00000e58, 0x00000e6a, 0x00000e71, 0x00000e84, - 0x00000e91, 0x00000e98, 0x00000eab, 0x00000ede, - 0x00000ef6, 0x00000f1d, 0x00000f35, 0x00000f5c, - 0x00000f63, 0x00000f76, 0x00000f84, 0x00000fb1, - 0x00000fc1, 0x00000fce, 0x00000fef, 0x00000ff6, - 0x00001003, 0x00001031, 0x00001044, 0x00001066, - 0x00001073, 0x000010a5, 0x000010d5, 0x000010fa, + 0x00000eda, 0x00000f0b, 0x00000f18, 0x00000f22, + 0x00000f72, 0x00000f82, 0x00000f95, 0x00000fa2, + 0x00000faf, 0x00000fc2, 0x00000fcf, 0x00000fdc, + 0x00000fe9, 0x00000ff6, 0x00001008, 0x0000100f, + 0x00001022, 0x0000102f, 0x00001036, 0x00001049, + 0x0000107c, 0x00001094, 0x000010bb, 0x000010d3, + 0x000010fa, 0x00001101, 0x00001114, 0x00001122, + 0x0000114f, 0x0000115f, 0x0000116c, 0x0000118d, // Entry 100 - 11F - 0x00001104, 0x00001123, 0x00001133, -} // Size: 1060 bytes + 0x00001194, 0x000011a1, 0x000011cf, 0x000011e2, + 0x00001204, 0x00001211, 0x00001243, 0x00001273, + 0x00001298, 0x000012a2, 0x000012c1, 0x000012d1, +} // Size: 1096 bytes -const zh_CNData string = "" + // Size: 4403 bytes +const zh_CNData string = "" + // Size: 4817 bytes "\x02版本:%[1]s\x02FRP 版本:%[1]s\x02构建日期:%[1]s\x02所有文件\x02配置文件\x02证书文件\x02密钥" + "文件\x02日志文件\x02数值超出允许范围\x02请输入一个大于 %[1]d 的数字。\x02密码不匹配\x02请检查并重试。\x02不是" + "数字\x02请输入一个有效的数字。\x02发现更新!\x02关于\x02下载更新\x02正在检查更新\x02检查更新\x02如有任何意见或报" + @@ -982,27 +1024,30 @@ const zh_CNData string = "" + // Size: 4403 bytes "\x02开启\x02关闭\x02主机名称\x02证书文件\x02选择证书文件\x02密钥文件\x02选择证书密钥文件\x02受信任证书\x02选" + "择受信任的证书\x02禁用自定义首字节\x02高级\x02使用源地址\x02多路复用\x02初次登录失败后退出\x02禁用开机自启动\x02" + "使用旧格式配置文件\x02元数据\x02实验性功能\x02* 以下功能可能会影响服务的稳定性。\x02使用服务器 SVCB 记录\x02配置" + - "已存在\x02配置名「%[1]s」已存在。\x02新建代理\x02编辑代理 - %[1]s\x02随机名称\x02类型\x02角色\x02服" + - "务端\x02访问者\x02私钥\x02本地地址\x02本地端口\x02远程端口\x02允许用户\x02绑定地址\x02绑定端口\x02服务名" + - "称\x02服务用户\x02子域名\x02自定义域名\x02URL 路由\x02请求头\x02复用器\x02路由用户\x02客户端\x02带宽" + - "限流\x02代理协议\x02自动\x02默认\x02隧道保活\x02加密传输\x02压缩传输\x02重试次数\x02次/小时\x02重试间隔" + - "\x02备用\x02备用超时\x02毫秒\x02HTTP 用户\x02HTTP 密码\x02Host 替换\x02插件\x02插件名称\x02U" + - "nix 路径\x02选择 Unix 路径\x02本地路径\x02选择需要显示目录列表的文件夹。\x02移除前缀\x02负载均衡\x02分组名称" + - "\x02分组密钥\x02健康检查\x02检查类型\x02检查超时\x02错误次数\x02检查周期\x02代理已存在\x02代理名「%[1]s」已" + - "存在。\x02打开日志文件夹\x02最新\x02项目\x02NAT 类型\x02行为\x02外部地址\x02是\x02否\x02公网\x02" + - "未知\x02正在运行\x02已停止\x02正在启动\x02正在停止\x02状态\x02远程地址\x02复制\x02启动\x02服务\x02停" + - "止配置「%[1]s」\x02确定要停止配置「%[1]s」吗?\x02停止\x02本地目录\x02端口\x02打开端口\x02选项\x02主密" + - "码\x02您可以设置密码来限制访问此程序。\x0a在下次使用此程序时,您将被要求输入密码。\x02使用主密码\x02修改密码\x02语言" + - "\x02目前的显示语言\x02您必须重新启动程序才能应用修改。\x02选择语言\x02默认值\x02定义新建配置时的默认值。\x0a此处的值不会" + - "影响现有的配置。\x02设置默认值\x02密码已删除。\x02新主密码\x02确认密码\x02密码已设定。\x02日志级别\x02日志保留" + - "\x02快速添加\x02远程桌面\x02HTTP 文件服务\x02禁用\x02打开配置文件\x02直接编辑\x02域名\x02复制访问地址" + - "\x02此功能仅支持 INI 或 TOML 格式的文本。\x02删除代理「%[1]s」\x02确定要删除代理「%[1]s」吗?\x02禁用代理「" + - "%[1]s」\x02确定要禁用代理「%[1]s」吗?\x02启用\x02被动端口范围\x02FRP 管理器\x02* 支持批量导入,每行一个链接" + - "。\x02自动重命名\x02准备就绪\x02请输入正确的 URL 列表。\x02下载\x02输入密码\x02您必须输入管理密码来使用 %[1" + - "]s。\x02输入管理密码\x02密码错误。请重新输入。\x02输入无效\x02请输入一个从 %.[1]f 到 %.[2]f 的数字。\x02请" + - "输入一个从 %[1]s 到 %[2]s 的数字。\x02文本与要求的模式不匹配。\x02必填项\x02请选择其中一个选项。\x02需要选择。" + "已存在\x02配置名「%[1]s」已存在。\x02由于代理转换失败,无法升级您的配置文件,请检查代理配置并重试。\x0a\x0a出错的代理:" + + "%[1]s\x02新建代理\x02编辑代理 - %[1]s\x02随机名称\x02类型\x02角色\x02服务端\x02访问者\x02私钥" + + "\x02本地地址\x02本地端口\x02远程端口\x02允许用户\x02绑定地址\x02绑定端口\x02服务名称\x02服务用户\x02子域名" + + "\x02自定义域名\x02URL 路由\x02请求头\x02复用器\x02路由用户\x02客户端\x02带宽限流\x02代理协议\x02自动" + + "\x02默认\x02隧道保活\x02加密传输\x02压缩传输\x02重试次数\x02次/小时\x02重试间隔\x02备用\x02备用超时\x02" + + "毫秒\x02HTTP 用户\x02HTTP 密码\x02Host 替换\x02插件\x02插件名称\x02Unix 路径\x02选择 Uni" + + "x 路径\x02本地路径\x02选择需要显示目录列表的文件夹。\x02移除前缀\x02负载均衡\x02分组名称\x02分组密钥\x02健康检查" + + "\x02检查类型\x02检查超时\x02错误次数\x02检查周期\x02代理已存在\x02代理名「%[1]s」已存在。\x02必须填写绑定端口。" + + "\x02必须填写本地端口或插件。\x02无效的本地端口。\x02健康检查 URL 为必填项。\x02插件不支持范围端口。\x02无效的远程端口。" + + "\x02本地端口的数量应与远程端口的数量相同。\x02自定义域名和子域名应至少填写其中之一。\x02打开日志文件夹\x02最新\x02项目" + + "\x02NAT 类型\x02行为\x02外部地址\x02是\x02否\x02公网\x02未知\x02正在运行\x02已停止\x02正在启动" + + "\x02正在停止\x02状态\x02远程地址\x02复制\x02启动\x02服务\x02停止配置「%[1]s」\x02确定要停止配置「%[1]s" + + "」吗?\x02停止\x02本地目录\x02端口\x02打开端口\x02选项\x02主密码\x02您可以设置密码来限制访问此程序。\x0a在下" + + "次使用此程序时,您将被要求输入密码。\x02使用主密码\x02修改密码\x02语言\x02目前的显示语言\x02您必须重新启动程序才能应用修" + + "改。\x02选择语言\x02默认值\x02定义新建配置时的默认值。\x0a此处的值不会影响现有的配置。\x02设置默认值\x02密码已删除。" + + "\x02新主密码\x02确认密码\x02密码已设定。\x02日志级别\x02日志保留\x02快速添加\x02远程桌面\x02HTTP 文件服务" + + "\x02禁用\x02打开配置文件\x02直接编辑\x02域名\x02复制访问地址\x02此功能仅支持 INI 或 TOML 格式的文本。\x02" + + "删除代理「%[1]s」\x02确定要删除代理「%[1]s」吗?\x02禁用代理「%[1]s」\x02确定要禁用代理「%[1]s」吗?\x02" + + "启用\x02被动端口范围\x02FRP 管理器\x02* 支持批量导入,每行一个链接。\x02自动重命名\x02准备就绪\x02请输入正确的" + + " URL 列表。\x02下载\x02输入密码\x02您必须输入管理密码来使用 %[1]s。\x02输入管理密码\x02密码错误。请重新输入。" + + "\x02输入无效\x02请输入一个从 %.[1]f 到 %.[2]f 的数字。\x02请输入一个从 %[1]s 到 %[2]s 的数字。\x02" + + "文本与要求的模式不匹配。\x02必填项\x02请选择其中一个选项。\x02需要选择。" -var zh_TWIndex = []uint32{ // 259 elements +var zh_TWIndex = []uint32{ // 268 elements // Entry 0 - 1F 0x00000000, 0x0000000f, 0x00000022, 0x00000037, 0x00000044, 0x00000051, 0x0000005e, 0x0000006b, @@ -1040,46 +1085,48 @@ var zh_TWIndex = []uint32{ // 259 elements 0x000007d9, 0x000007f2, 0x000007fc, 0x0000080c, 0x0000083f, 0x0000085b, 0x0000086b, 0x0000088c, // Entry 80 - 9F - 0x00000899, 0x000008ae, 0x000008bb, 0x000008c2, - 0x000008c9, 0x000008d3, 0x000008dd, 0x000008e4, - 0x000008f1, 0x000008fe, 0x0000090b, 0x00000918, - 0x00000925, 0x00000932, 0x0000093f, 0x0000094c, - 0x00000956, 0x00000966, 0x00000971, 0x0000097b, - 0x00000985, 0x00000992, 0x0000099c, 0x000009a9, - 0x000009b6, 0x000009bd, 0x000009c4, 0x000009d1, - 0x000009de, 0x000009eb, 0x000009f8, 0x00000a03, + 0x00000903, 0x00000910, 0x00000925, 0x00000932, + 0x00000939, 0x00000940, 0x0000094a, 0x00000954, + 0x0000095b, 0x00000968, 0x00000975, 0x00000982, + 0x0000098f, 0x0000099c, 0x000009a9, 0x000009b6, + 0x000009c3, 0x000009cd, 0x000009dd, 0x000009e8, + 0x000009f2, 0x000009fc, 0x00000a09, 0x00000a13, + 0x00000a20, 0x00000a2d, 0x00000a34, 0x00000a3b, + 0x00000a48, 0x00000a55, 0x00000a62, 0x00000a6f, // Entry A0 - BF - 0x00000a10, 0x00000a17, 0x00000a24, 0x00000a2b, - 0x00000a37, 0x00000a43, 0x00000a4f, 0x00000a56, - 0x00000a63, 0x00000a6f, 0x00000a82, 0x00000a8f, - 0x00000abd, 0x00000aca, 0x00000ad7, 0x00000ae4, - 0x00000af1, 0x00000afe, 0x00000b0b, 0x00000b18, - 0x00000b25, 0x00000b32, 0x00000b42, 0x00000b63, - 0x00000b79, 0x00000b80, 0x00000b87, 0x00000b92, - 0x00000b99, 0x00000ba6, 0x00000baa, 0x00000bae, + 0x00000a7a, 0x00000a87, 0x00000a8e, 0x00000a9b, + 0x00000aa2, 0x00000aae, 0x00000aba, 0x00000ac6, + 0x00000acd, 0x00000ada, 0x00000ae6, 0x00000af9, + 0x00000b06, 0x00000b34, 0x00000b41, 0x00000b4e, + 0x00000b5b, 0x00000b68, 0x00000b75, 0x00000b82, + 0x00000b8f, 0x00000b9c, 0x00000ba9, 0x00000bb9, + 0x00000bda, 0x00000bf6, 0x00000c1b, 0x00000c34, + 0x00000c55, 0x00000c74, 0x00000c8d, 0x00000cc7, // Entry C0 - DF - 0x00000bb5, 0x00000bbc, 0x00000bc9, 0x00000bd3, - 0x00000be0, 0x00000bed, 0x00000bf4, 0x00000c01, - 0x00000c08, 0x00000c0f, 0x00000c16, 0x00000c2e, - 0x00000c55, 0x00000c5c, 0x00000c69, 0x00000c70, - 0x00000c7d, 0x00000c84, 0x00000c8e, 0x00000cfc, - 0x00000d0c, 0x00000d19, 0x00000d20, 0x00000d36, - 0x00000d67, 0x00000d74, 0x00000d7e, 0x00000dce, - 0x00000dde, 0x00000df1, 0x00000dfe, 0x00000e0b, + 0x00000cfe, 0x00000d14, 0x00000d1b, 0x00000d22, + 0x00000d2d, 0x00000d34, 0x00000d41, 0x00000d45, + 0x00000d49, 0x00000d50, 0x00000d57, 0x00000d64, + 0x00000d6e, 0x00000d7b, 0x00000d88, 0x00000d8f, + 0x00000d9c, 0x00000da3, 0x00000daa, 0x00000db1, + 0x00000dc9, 0x00000df0, 0x00000df7, 0x00000e04, + 0x00000e0b, 0x00000e18, 0x00000e1f, 0x00000e29, + 0x00000e97, 0x00000ea7, 0x00000eb4, 0x00000ebb, // Entry E0 - FF - 0x00000e1e, 0x00000e2b, 0x00000e38, 0x00000e45, - 0x00000e52, 0x00000e64, 0x00000e6b, 0x00000e7e, - 0x00000e8b, 0x00000e92, 0x00000ea5, 0x00000ed8, - 0x00000ef0, 0x00000f17, 0x00000f2f, 0x00000f56, - 0x00000f5d, 0x00000f70, 0x00000f7e, 0x00000fab, - 0x00000fbb, 0x00000fc8, 0x00000fe9, 0x00000ff0, - 0x00000ffd, 0x0000102b, 0x0000103e, 0x00001060, - 0x0000106d, 0x0000109f, 0x000010cf, 0x000010f4, + 0x00000ed1, 0x00000f02, 0x00000f0f, 0x00000f19, + 0x00000f69, 0x00000f79, 0x00000f8c, 0x00000f99, + 0x00000fa6, 0x00000fb9, 0x00000fc6, 0x00000fd3, + 0x00000fe0, 0x00000fed, 0x00000fff, 0x00001006, + 0x00001019, 0x00001026, 0x0000102d, 0x00001040, + 0x00001073, 0x0000108b, 0x000010b2, 0x000010ca, + 0x000010f1, 0x000010f8, 0x0000110b, 0x00001119, + 0x00001146, 0x00001156, 0x00001163, 0x00001184, // Entry 100 - 11F - 0x000010fe, 0x0000111d, 0x0000112d, -} // Size: 1060 bytes + 0x0000118b, 0x00001198, 0x000011c6, 0x000011d9, + 0x000011fb, 0x00001208, 0x0000123a, 0x0000126a, + 0x0000128f, 0x00001299, 0x000012b8, 0x000012c8, +} // Size: 1096 bytes -const zh_TWData string = "" + // Size: 4397 bytes +const zh_TWData string = "" + // Size: 4808 bytes "\x02版本:%[1]s\x02FRP 版本:%[1]s\x02構建日期:%[1]s\x02所有文件\x02配置文件\x02證書文件\x02密鑰" + "文件\x02日誌文件\x02數值超出允許範圍\x02請輸入一個大於 %[1]d 的數字。\x02密碼不匹配\x02請檢查並重試。\x02不是" + "數字\x02請輸入一個有效的數字。\x02發現更新!\x02關於\x02下載更新\x02正在檢查更新\x02檢查更新\x02如有任何意見或報" + @@ -1098,24 +1145,27 @@ const zh_TWData string = "" + // Size: 4397 bytes "\x02開啟\x02關閉\x02主機名稱\x02證書文件\x02選擇證書文件\x02密鑰文件\x02選擇證書密鑰文件\x02受信任證書\x02選" + "擇受信任的證書\x02停用自訂首字節\x02高級\x02使用源地址\x02多路復用\x02初次登錄失敗後退出\x02禁用開機自啟動\x02使" + "用舊格式設定檔\x02元數據\x02實驗性功能\x02* 以下功能可能會影響服務的穩定性。\x02使用服務器 SVCB 記錄\x02配置已存" + - "在\x02配置名「%[1]s」已存在。\x02新建代理\x02編輯代理 - %[1]s\x02隨機名稱\x02類型\x02角色\x02服務端" + - "\x02訪問者\x02私鑰\x02本地地址\x02本地端口\x02遠程端口\x02允許用戶\x02綁定地址\x02綁定端口\x02服務名稱" + - "\x02服務用戶\x02子域名\x02自定義域名\x02URL 路由\x02請求頭\x02復用器\x02路由用戶\x02客戶端\x02帶寬限流" + - "\x02代理協議\x02自動\x02默認\x02隧道保活\x02加密傳輸\x02壓縮傳輸\x02重試次數\x02次/小時\x02重試間隔\x02" + - "備用\x02備用超時\x02毫秒\x02HTTP 用戶\x02HTTP 密碼\x02Host 替換\x02插件\x02插件名稱\x02Uni" + - "x 路徑\x02選擇 Unix 路徑\x02本地路徑\x02選擇需要顯示目錄列表的文件夾。\x02移除前綴\x02負載均衡\x02分組名稱" + - "\x02分組密鑰\x02健康檢查\x02檢查類型\x02檢查超時\x02錯誤次數\x02檢查週期\x02代理已存在\x02代理名「%[1]s」已" + - "存在。\x02打開日誌文件夾\x02最新\x02項目\x02NAT 類型\x02行為\x02外部地址\x02是\x02否\x02公網\x02" + - "未知\x02正在運行\x02已停止\x02正在啟動\x02正在停止\x02狀態\x02遠程地址\x02複製\x02啟動\x02服務\x02停" + - "止配置「%[1]s」\x02確定要停止配置「%[1]s」嗎?\x02停止\x02本地目錄\x02端口\x02打開端口\x02選項\x02主密" + - "碼\x02您可以設置密碼來限制訪問此程式。\x0a在下次使用此程式時,您將被要求輸入密碼。\x02使用主密碼\x02修改密碼\x02語言" + - "\x02目前的顯示語言\x02您必須重新啟動程式才能應用修改。\x02選擇語言\x02默認值\x02定義新建配置時的默認值。\x0a此處的值不會" + - "影響現有的配置。\x02設置默認值\x02密碼已刪除。\x02新主密碼\x02確認密碼\x02密碼已設定。\x02日誌級別\x02日誌保留" + - "\x02快速添加\x02遠程桌面\x02HTTP 文件服務\x02禁用\x02打開配置文件\x02直接編輯\x02域名\x02複製訪問地址" + - "\x02此功能僅支援 INI 或 TOML 格式的文字。\x02刪除代理「%[1]s」\x02確定要刪除代理「%[1]s」嗎?\x02禁用代理「" + - "%[1]s」\x02確定要禁用代理「%[1]s」嗎?\x02啟用\x02被動端口範圍\x02FRP 管理器\x02* 支持批量導入,每行一個鏈接" + - "。\x02自動重命名\x02準備就緒\x02請輸入正確的 URL 列表。\x02下載\x02輸入密碼\x02您必須輸入管理密碼來使用 %[1" + - "]s。\x02輸入管理密碼\x02密碼錯誤。請重新輸入。\x02輸入無效\x02請輸入一個從 %.[1]f 到 %.[2]f 的數字。\x02請" + - "輸入一個從 %[1]s 到 %[2]s 的數字。\x02文本與要求的模式不匹配。\x02必填項\x02請選擇其中一個選項。\x02需要選擇。" + "在\x02配置名「%[1]s」已存在。\x02由於代理轉換失敗,無法升級您的配置文件,請檢查代理配置並重試。\x0a\x0a出錯的代理:%[" + + "1]s\x02新建代理\x02編輯代理 - %[1]s\x02隨機名稱\x02類型\x02角色\x02服務端\x02訪問者\x02私鑰\x02本" + + "地地址\x02本地端口\x02遠程端口\x02允許用戶\x02綁定地址\x02綁定端口\x02服務名稱\x02服務用戶\x02子域名\x02" + + "自定義域名\x02URL 路由\x02請求頭\x02復用器\x02路由用戶\x02客戶端\x02帶寬限流\x02代理協議\x02自動\x02" + + "默認\x02隧道保活\x02加密傳輸\x02壓縮傳輸\x02重試次數\x02次/小時\x02重試間隔\x02備用\x02備用超時\x02毫秒" + + "\x02HTTP 用戶\x02HTTP 密碼\x02Host 替換\x02插件\x02插件名稱\x02Unix 路徑\x02選擇 Unix 路徑" + + "\x02本地路徑\x02選擇需要顯示目錄列表的文件夾。\x02移除前綴\x02負載均衡\x02分組名稱\x02分組密鑰\x02健康檢查\x02檢" + + "查類型\x02檢查超時\x02錯誤次數\x02檢查週期\x02代理已存在\x02代理名「%[1]s」已存在。\x02必須填寫綁定端口。" + + "\x02必須填寫本地端口或插件。\x02無效的本地端口。\x02健康檢查 URL 為必填項。\x02插件不支援範圍端口。\x02無效的遠端端口。" + + "\x02本地端口的數量應與遠端端口的數量相同。\x02自訂網域和子網域應至少填寫其中之一。\x02打開日誌文件夾\x02最新\x02項目\x02" + + "NAT 類型\x02行為\x02外部地址\x02是\x02否\x02公網\x02未知\x02正在運行\x02已停止\x02正在啟動\x02正在停" + + "止\x02狀態\x02遠程地址\x02複製\x02啟動\x02服務\x02停止配置「%[1]s」\x02確定要停止配置「%[1]s」嗎?" + + "\x02停止\x02本地目錄\x02端口\x02打開端口\x02選項\x02主密碼\x02您可以設置密碼來限制訪問此程式。\x0a在下次使用此程" + + "式時,您將被要求輸入密碼。\x02使用主密碼\x02修改密碼\x02語言\x02目前的顯示語言\x02您必須重新啟動程式才能應用修改。" + + "\x02選擇語言\x02默認值\x02定義新建配置時的默認值。\x0a此處的值不會影響現有的配置。\x02設置默認值\x02密碼已刪除。\x02" + + "新主密碼\x02確認密碼\x02密碼已設定。\x02日誌級別\x02日誌保留\x02快速添加\x02遠程桌面\x02HTTP 文件服務" + + "\x02禁用\x02打開配置文件\x02直接編輯\x02域名\x02複製訪問地址\x02此功能僅支援 INI 或 TOML 格式的文字。\x02" + + "刪除代理「%[1]s」\x02確定要刪除代理「%[1]s」嗎?\x02禁用代理「%[1]s」\x02確定要禁用代理「%[1]s」嗎?\x02" + + "啟用\x02被動端口範圍\x02FRP 管理器\x02* 支持批量導入,每行一個鏈接。\x02自動重命名\x02準備就緒\x02請輸入正確的" + + " URL 列表。\x02下載\x02輸入密碼\x02您必須輸入管理密碼來使用 %[1]s。\x02輸入管理密碼\x02密碼錯誤。請重新輸入。" + + "\x02輸入無效\x02請輸入一個從 %.[1]f 到 %.[2]f 的數字。\x02請輸入一個從 %[1]s 到 %[2]s 的數字。\x02" + + "文本與要求的模式不匹配。\x02必填項\x02請選擇其中一個選項。\x02需要選擇。" - // Total table size 38221 bytes (37KiB); checksum: 49783779 + // Total table size 41646 bytes (40KiB); checksum: 2F2F6E2F diff --git a/i18n/locales/en-US/messages.gotext.json b/i18n/locales/en-US/messages.gotext.json index 4913e89b..15b603c6 100644 --- a/i18n/locales/en-US/messages.gotext.json +++ b/i18n/locales/en-US/messages.gotext.json @@ -1018,6 +1018,23 @@ ], "fuzzy": true }, + { + "id": "Unable to upgrade your config file due to proxy conversion failure, please check the proxy config and try again.\n\nBad proxy: {Name}", + "message": "Unable to upgrade your config file due to proxy conversion failure, please check the proxy config and try again.\n\nBad proxy: {Name}", + "translation": "Unable to upgrade your config file due to proxy conversion failure, please check the proxy config and try again.\n\nBad proxy: {Name}", + "translatorComment": "Copied from source.", + "placeholders": [ + { + "id": "Name", + "string": "%[1]s", + "type": "string", + "underlyingType": "string", + "argNum": 1, + "expr": "v.Name" + } + ], + "fuzzy": true + }, { "id": "New Proxy", "message": "New Proxy", @@ -1430,6 +1447,62 @@ ], "fuzzy": true }, + { + "id": "Bind port is required.", + "message": "Bind port is required.", + "translation": "Bind port is required.", + "translatorComment": "Copied from source.", + "fuzzy": true + }, + { + "id": "Requires local port or plugin.", + "message": "Requires local port or plugin.", + "translation": "Requires local port or plugin.", + "translatorComment": "Copied from source.", + "fuzzy": true + }, + { + "id": "Invalid local port.", + "message": "Invalid local port.", + "translation": "Invalid local port.", + "translatorComment": "Copied from source.", + "fuzzy": true + }, + { + "id": "Health check url is required.", + "message": "Health check url is required.", + "translation": "Health check url is required.", + "translatorComment": "Copied from source.", + "fuzzy": true + }, + { + "id": "The plugin does not support range ports.", + "message": "The plugin does not support range ports.", + "translation": "The plugin does not support range ports.", + "translatorComment": "Copied from source.", + "fuzzy": true + }, + { + "id": "Invalid remote port.", + "message": "Invalid remote port.", + "translation": "Invalid remote port.", + "translatorComment": "Copied from source.", + "fuzzy": true + }, + { + "id": "The number of local ports should be the same as the number of remote ports.", + "message": "The number of local ports should be the same as the number of remote ports.", + "translation": "The number of local ports should be the same as the number of remote ports.", + "translatorComment": "Copied from source.", + "fuzzy": true + }, + { + "id": "Custom domains and subdomain should have at least one of these set.", + "message": "Custom domains and subdomain should have at least one of these set.", + "translation": "Custom domains and subdomain should have at least one of these set.", + "translatorComment": "Copied from source.", + "fuzzy": true + }, { "id": "Open Log Folder", "message": "Open Log Folder", diff --git a/i18n/locales/es-ES/messages.gotext.json b/i18n/locales/es-ES/messages.gotext.json index a4cf791c..4d3d8116 100644 --- a/i18n/locales/es-ES/messages.gotext.json +++ b/i18n/locales/es-ES/messages.gotext.json @@ -764,6 +764,21 @@ } ] }, + { + "id": "Unable to upgrade your config file due to proxy conversion failure, please check the proxy config and try again.\n\nBad proxy: {Name}", + "message": "Unable to upgrade your config file due to proxy conversion failure, please check the proxy config and try again.\n\nBad proxy: {Name}", + "translation": "No se puede actualizar su archivo de configuración debido a un error en la conversión del proxy. Verifique la configuración del proxy e inténtelo nuevamente.\n\nProxy incorrecto: {Name}", + "placeholders": [ + { + "id": "Name", + "string": "%[1]s", + "type": "string", + "underlyingType": "string", + "argNum": 1, + "expr": "v.Name" + } + ] + }, { "id": "New Proxy", "message": "New Proxy", @@ -1064,6 +1079,46 @@ } ] }, + { + "id": "Bind port is required.", + "message": "Bind port is required.", + "translation": "Se requiere puerto de vinculación." + }, + { + "id": "Requires local port or plugin.", + "message": "Requires local port or plugin.", + "translation": "Requiere puerto local o complemento." + }, + { + "id": "Invalid local port.", + "message": "Invalid local port.", + "translation": "Puerto local no válido." + }, + { + "id": "Health check url is required.", + "message": "Health check url is required.", + "translation": "Se requiere la URL de verificación de estado." + }, + { + "id": "The plugin does not support range ports.", + "message": "The plugin does not support range ports.", + "translation": "El complemento no admite puertos de rango." + }, + { + "id": "Invalid remote port.", + "message": "Invalid remote port.", + "translation": "Puerto remoto no válido." + }, + { + "id": "The number of local ports should be the same as the number of remote ports.", + "message": "The number of local ports should be the same as the number of remote ports.", + "translation": "La cantidad de puertos locales debe ser la misma que la cantidad de puertos remotos." + }, + { + "id": "Custom domains and subdomain should have at least one of these set.", + "message": "Custom domains and subdomain should have at least one of these set.", + "translation": "Los dominios y subdominios personalizados deben tener al menos uno de estos configurados." + }, { "id": "Open Log Folder", "message": "Open Log Folder", diff --git a/i18n/locales/ja-JP/messages.gotext.json b/i18n/locales/ja-JP/messages.gotext.json index cddbbc8b..dfad4d40 100644 --- a/i18n/locales/ja-JP/messages.gotext.json +++ b/i18n/locales/ja-JP/messages.gotext.json @@ -774,6 +774,21 @@ } ] }, + { + "id": "Unable to upgrade your config file due to proxy conversion failure, please check the proxy config and try again.\n\nBad proxy: {Name}", + "message": "Unable to upgrade your config file due to proxy conversion failure, please check the proxy config and try again.\n\nBad proxy: {Name}", + "translation": "プロキシ変換が失敗したため、設定ファイルをアップグレードできません。プロキシ設定を確認して、もう一度試してください。\n\n不正なプロキシ: {Name}", + "placeholders": [ + { + "id": "Name", + "string": "%[1]s", + "type": "string", + "underlyingType": "string", + "argNum": 1, + "expr": "v.Name" + } + ] + }, { "id": "New Proxy", "message": "New Proxy", @@ -1074,6 +1089,46 @@ } ] }, + { + "id": "Bind port is required.", + "message": "Bind port is required.", + "translation": "バインドポートは必須です。" + }, + { + "id": "Requires local port or plugin.", + "message": "Requires local port or plugin.", + "translation": "ローカルポートまたはプラグインが必要です。" + }, + { + "id": "Invalid local port.", + "message": "Invalid local port.", + "translation": "ローカルポートが無効です。" + }, + { + "id": "Health check url is required.", + "message": "Health check url is required.", + "translation": "ヘルスチェックのURLは必須です。" + }, + { + "id": "The plugin does not support range ports.", + "message": "The plugin does not support range ports.", + "translation": "プラグインは範囲ポートをサポートしていません。" + }, + { + "id": "Invalid remote port.", + "message": "Invalid remote port.", + "translation": "無効なリモートポートです。" + }, + { + "id": "The number of local ports should be the same as the number of remote ports.", + "message": "The number of local ports should be the same as the number of remote ports.", + "translation": "ローカル ポートの数はリモート ポートの数と同じである必要があります。" + }, + { + "id": "Custom domains and subdomain should have at least one of these set.", + "message": "Custom domains and subdomain should have at least one of these set.", + "translation": "カスタム ドメインとサブドメインには、これらのうち少なくとも 1 つが設定されている必要があります。" + }, { "id": "Open Log Folder", "message": "Open Log Folder", diff --git a/i18n/locales/ko-KR/messages.gotext.json b/i18n/locales/ko-KR/messages.gotext.json index 13f091e2..57da7d4e 100644 --- a/i18n/locales/ko-KR/messages.gotext.json +++ b/i18n/locales/ko-KR/messages.gotext.json @@ -764,6 +764,21 @@ } ] }, + { + "id": "Unable to upgrade your config file due to proxy conversion failure, please check the proxy config and try again.\n\nBad proxy: {Name}", + "message": "Unable to upgrade your config file due to proxy conversion failure, please check the proxy config and try again.\n\nBad proxy: {Name}", + "translation": "프록시 변환 실패로 인해 구성 파일을 업그레이드할 수 없습니다. 프록시 구성을 확인하고 다시 시도하세요.\n\n잘못된 프록시: {Name}", + "placeholders": [ + { + "id": "Name", + "string": "%[1]s", + "type": "string", + "underlyingType": "string", + "argNum": 1, + "expr": "v.Name" + } + ] + }, { "id": "New Proxy", "message": "New Proxy", @@ -1064,6 +1079,46 @@ } ] }, + { + "id": "Bind port is required.", + "message": "Bind port is required.", + "translation": "바인드 포트가 필요합니다." + }, + { + "id": "Requires local port or plugin.", + "message": "Requires local port or plugin.", + "translation": "로컬 포트 또는 플러그인이 필요합니다." + }, + { + "id": "Invalid local port.", + "message": "Invalid local port.", + "translation": "로컬 포트가 잘못되었습니다." + }, + { + "id": "Health check url is required.", + "message": "Health check url is required.", + "translation": "상태 확인 URL이 필요합니다." + }, + { + "id": "The plugin does not support range ports.", + "message": "The plugin does not support range ports.", + "translation": "플러그인은 범위 포트를 지원하지 않습니다." + }, + { + "id": "Invalid remote port.", + "message": "Invalid remote port.", + "translation": "원격 포트가 잘못되었습니다." + }, + { + "id": "The number of local ports should be the same as the number of remote ports.", + "message": "The number of local ports should be the same as the number of remote ports.", + "translation": "로컬 포트 수는 원격 포트 수와 동일해야 합니다." + }, + { + "id": "Custom domains and subdomain should have at least one of these set.", + "message": "Custom domains and subdomain should have at least one of these set.", + "translation": "사용자 정의 도메인 및 하위 도메인에는 이러한 세트가 하나 이상 있어야 합니다." + }, { "id": "Open Log Folder", "message": "Open Log Folder", diff --git a/i18n/locales/zh-CN/messages.gotext.json b/i18n/locales/zh-CN/messages.gotext.json index 321e7fa1..c6944a1e 100644 --- a/i18n/locales/zh-CN/messages.gotext.json +++ b/i18n/locales/zh-CN/messages.gotext.json @@ -764,6 +764,21 @@ } ] }, + { + "id": "Unable to upgrade your config file due to proxy conversion failure, please check the proxy config and try again.\n\nBad proxy: {Name}", + "message": "Unable to upgrade your config file due to proxy conversion failure, please check the proxy config and try again.\n\nBad proxy: {Name}", + "translation": "由于代理转换失败,无法升级您的配置文件,请检查代理配置并重试。\n\n出错的代理:{Name}", + "placeholders": [ + { + "id": "Name", + "string": "%[1]s", + "type": "string", + "underlyingType": "string", + "argNum": 1, + "expr": "v.Name" + } + ] + }, { "id": "New Proxy", "message": "New Proxy", @@ -1064,6 +1079,46 @@ } ] }, + { + "id": "Bind port is required.", + "message": "Bind port is required.", + "translation": "必须填写绑定端口。" + }, + { + "id": "Requires local port or plugin.", + "message": "Requires local port or plugin.", + "translation": "必须填写本地端口或插件。" + }, + { + "id": "Invalid local port.", + "message": "Invalid local port.", + "translation": "无效的本地端口。" + }, + { + "id": "Health check url is required.", + "message": "Health check url is required.", + "translation": "健康检查 URL 为必填项。" + }, + { + "id": "The plugin does not support range ports.", + "message": "The plugin does not support range ports.", + "translation": "插件不支持范围端口。" + }, + { + "id": "Invalid remote port.", + "message": "Invalid remote port.", + "translation": "无效的远程端口。" + }, + { + "id": "The number of local ports should be the same as the number of remote ports.", + "message": "The number of local ports should be the same as the number of remote ports.", + "translation": "本地端口的数量应与远程端口的数量相同。" + }, + { + "id": "Custom domains and subdomain should have at least one of these set.", + "message": "Custom domains and subdomain should have at least one of these set.", + "translation": "自定义域名和子域名应至少填写其中之一。" + }, { "id": "Open Log Folder", "message": "Open Log Folder", diff --git a/i18n/locales/zh-TW/messages.gotext.json b/i18n/locales/zh-TW/messages.gotext.json index 8f8d76a9..f5970335 100644 --- a/i18n/locales/zh-TW/messages.gotext.json +++ b/i18n/locales/zh-TW/messages.gotext.json @@ -764,6 +764,21 @@ } ] }, + { + "id": "Unable to upgrade your config file due to proxy conversion failure, please check the proxy config and try again.\n\nBad proxy: {Name}", + "message": "Unable to upgrade your config file due to proxy conversion failure, please check the proxy config and try again.\n\nBad proxy: {Name}", + "translation": "由於代理轉換失敗,無法升級您的配置文件,請檢查代理配置並重試。\n\n出錯的代理:{Name}", + "placeholders": [ + { + "id": "Name", + "string": "%[1]s", + "type": "string", + "underlyingType": "string", + "argNum": 1, + "expr": "v.Name" + } + ] + }, { "id": "New Proxy", "message": "New Proxy", @@ -1064,6 +1079,46 @@ } ] }, + { + "id": "Bind port is required.", + "message": "Bind port is required.", + "translation": "必須填寫綁定端口。" + }, + { + "id": "Requires local port or plugin.", + "message": "Requires local port or plugin.", + "translation": "必須填寫本地端口或插件。" + }, + { + "id": "Invalid local port.", + "message": "Invalid local port.", + "translation": "無效的本地端口。" + }, + { + "id": "Health check url is required.", + "message": "Health check url is required.", + "translation": "健康檢查 URL 為必填項。" + }, + { + "id": "The plugin does not support range ports.", + "message": "The plugin does not support range ports.", + "translation": "插件不支援範圍端口。" + }, + { + "id": "Invalid remote port.", + "message": "Invalid remote port.", + "translation": "無效的遠端端口。" + }, + { + "id": "The number of local ports should be the same as the number of remote ports.", + "message": "The number of local ports should be the same as the number of remote ports.", + "translation": "本地端口的數量應與遠端端口的數量相同。" + }, + { + "id": "Custom domains and subdomain should have at least one of these set.", + "message": "Custom domains and subdomain should have at least one of these set.", + "translation": "自訂網域和子網域應至少填寫其中之一。" + }, { "id": "Open Log Folder", "message": "Open Log Folder", diff --git a/pkg/config/client.go b/pkg/config/client.go index f01926d3..685cbfa1 100644 --- a/pkg/config/client.go +++ b/pkg/config/client.go @@ -1,7 +1,6 @@ package config import ( - "bytes" "fmt" "os" "slices" @@ -18,21 +17,6 @@ import ( "github.com/koho/frpmgr/pkg/util" ) -type ClientConfigV1 struct { - v1.ClientCommonConfig - - Proxies []v1.TypedProxyConfig `json:"proxies,omitempty"` - Visitors []v1.TypedVisitorConfig `json:"visitors,omitempty"` - - Internal Internal `json:"frpmgr,omitempty"` -} - -type Internal struct { - ManualStart bool `json:"manualStart,omitempty"` - SVCBEnable bool `json:"svcbEnable,omitempty"` - AutoDelete AutoDelete `json:"autoDelete,omitempty"` -} - type ClientAuth struct { AuthMethod string `ini:"authentication_method,omitempty"` AuthenticateHeartBeats bool `ini:"authenticate_heartbeats,omitempty" token:"true" oidc:"true"` @@ -241,15 +225,14 @@ type Proxy struct { // GetAlias returns the alias of this proxy. // It's usually equal to the proxy name, but proxies that start with "range:" differ from it. func (p *Proxy) GetAlias() []string { - if strings.HasPrefix(p.Name, consts.RangePrefix) { - prefix := strings.TrimSpace(strings.TrimPrefix(p.Name, consts.RangePrefix)) + if p.IsRange() { localPorts, err := frputil.ParseRangeNumbers(p.LocalPort) if err != nil { return []string{p.Name} } alias := make([]string, len(localPorts)) for i := range localPorts { - alias[i] = fmt.Sprintf("%s_%d", prefix, i) + alias[i] = fmt.Sprintf("%s_%d", p.Name, i) } return alias } @@ -263,25 +246,9 @@ func (p *Proxy) IsVisitor() bool { p.Type == consts.ProxyTypeSUDP) && p.Role == "visitor" } -// Marshal returns the encoded proxy. -func (p *Proxy) Marshal() ([]byte, error) { - // We must complete the proxy. - // Otherwise, it contains redundant parameters. - p.Complete() - // Serialize to ini format - cfg := ini.Empty() - tp, err := cfg.NewSection(p.Name) - if err != nil { - return nil, err - } - if err = tp.ReflectFrom(p); err != nil { - return nil, err - } - proxyBuffer := bytes.NewBuffer(nil) - if _, err = cfg.WriteTo(proxyBuffer); err != nil { - return nil, err - } - return proxyBuffer.Bytes(), nil +func (p *Proxy) IsRange() bool { + return (p.Type == consts.ProxyTypeTCP || p.Type == consts.ProxyTypeUDP) && + lo.Some([]rune(p.LocalPort+p.RemotePort), []rune{',', '-'}) } // Complete removes redundant parameters base on the proxy type. @@ -307,6 +274,8 @@ func (p *Proxy) Complete() { } else { // Plugins if base.Plugin != "" { + base.LocalIP = "" + base.LocalPort = "" if pluginParams, err := util.PruneByTag(base.PluginParams, "true", base.Plugin); err == nil { base.PluginParams = pluginParams.(PluginParams) } @@ -402,7 +371,11 @@ func (conf *ClientConfig) saveINI(path string) error { common.Key("oidc_additional_" + k).SetValue(v) } for _, proxy := range conf.Proxies { - p, err := cfg.NewSection(proxy.Name) + name := proxy.Name + if proxy.IsRange() && !strings.HasPrefix(name, consts.RangePrefix) { + name = consts.RangePrefix + name + } + p, err := cfg.NewSection(name) if err != nil { return err } @@ -425,7 +398,7 @@ func (conf *ClientConfig) saveINI(path string) error { func (conf *ClientConfig) saveTOML(path string) error { c := ClientConfigV1{ ClientCommonConfig: ClientCommonToV1(&conf.ClientCommon), - Internal: Internal{ + Mgr: Mgr{ ManualStart: conf.ManualStart, SVCBEnable: conf.SVCBEnable, AutoDelete: conf.AutoDelete, @@ -435,11 +408,11 @@ func (conf *ClientConfig) saveTOML(path string) error { if v.IsVisitor() { c.Visitors = append(c.Visitors, ClientVisitorToV1(v)) } else { - p, err := ClientProxyToV1(v) + proxies, err := ClientProxyToV1(v) if err != nil { return err } - c.Proxies = append(c.Proxies, p) + c.Proxies = append(c.Proxies, proxies...) } } obj, err := toMap(&c, "json") @@ -540,6 +513,7 @@ func NewProxyFromIni(name string, section *ini.Section) (*Proxy, error) { proxy.Metas = util.GetMapWithoutPrefix(section.KeysHash(), "meta_") proxy.Headers = util.GetMapWithoutPrefix(section.KeysHash(), "header_") proxy.PluginHeaders = util.GetMapWithoutPrefix(section.KeysHash(), "plugin_header_") + proxy.Name = strings.TrimPrefix(proxy.Name, consts.RangePrefix) return proxy, nil } @@ -631,12 +605,28 @@ func UnmarshalClientConf(source interface{}) (*ClientConfig, error) { } var r ClientConfig r.ClientCommon = ClientCommonFromV1(&cfg.ClientCommonConfig) - r.ManualStart = cfg.Internal.ManualStart - r.SVCBEnable = cfg.Internal.SVCBEnable - r.AutoDelete = cfg.Internal.AutoDelete - for _, v := range cfg.Proxies { - r.Proxies = append(r.Proxies, ClientProxyFromV1(v)) + r.ManualStart = cfg.Mgr.ManualStart + r.SVCBEnable = cfg.Mgr.SVCBEnable + r.AutoDelete = cfg.Mgr.AutoDelete + // Proxies + ignore := make(map[string]struct{}) + proxies := make([]*Proxy, len(cfg.Proxies)) + for i, v := range cfg.Proxies { + p := ClientProxyFromV1(v) + if p.IsRange() { + for _, name := range p.GetAlias() { + if name != p.Name { + ignore[name] = struct{}{} + } + } + } + proxies[i] = p } + r.Proxies = lo.Filter(proxies, func(item *Proxy, index int) bool { + _, ok := ignore[item.Name] + return !ok + }) + // Visitors for _, v := range cfg.Visitors { r.Proxies = append(r.Proxies, ClientVisitorFromV1(v)) } diff --git a/pkg/config/conversion.go b/pkg/config/conversion.go index 9e95e68b..24148693 100644 --- a/pkg/config/conversion.go +++ b/pkg/config/conversion.go @@ -9,6 +9,7 @@ import ( "github.com/fatedier/frp/pkg/config/types" "github.com/fatedier/frp/pkg/config/v1" + frputil "github.com/fatedier/frp/pkg/util/util" "github.com/samber/lo" "github.com/koho/frpmgr/pkg/consts" @@ -90,14 +91,23 @@ func ClientCommonFromV1(c *v1.ClientCommonConfig) (r ClientCommon) { return } -func ClientProxyFromV1(pxyCfg v1.TypedProxyConfig) *Proxy { +func ClientProxyFromV1(pxyCfg TypedProxyConfig) *Proxy { var r Proxy clientProxyBaseFromV1(pxyCfg.GetBaseConfig(), &r) + setRemotePort := func(port int) { + if pxyCfg.Mgr.Range.Local != "" && pxyCfg.Mgr.Range.Remote != "" && strings.HasSuffix(r.Name, "_0") { + r.Name = strings.TrimSuffix(r.Name, "_0") + r.LocalPort = pxyCfg.Mgr.Range.Local + r.RemotePort = pxyCfg.Mgr.Range.Remote + } else { + r.RemotePort = strconv.Itoa(port) + } + } switch v := pxyCfg.ProxyConfigurer.(type) { case *v1.TCPProxyConfig: - r.RemotePort = strconv.Itoa(v.RemotePort) + setRemotePort(v.RemotePort) case *v1.UDPProxyConfig: - r.RemotePort = strconv.Itoa(v.RemotePort) + setRemotePort(v.RemotePort) case *v1.HTTPProxyConfig: r.SubDomain = v.SubDomain r.CustomDomains = strings.Join(v.CustomDomains, ",") @@ -299,8 +309,43 @@ func ClientCommonToV1(c *ClientCommon) (r v1.ClientCommonConfig) { return } -func ClientProxyToV1(p *Proxy) (v1.TypedProxyConfig, error) { - r := v1.TypedProxyConfig{Type: p.Type} +func ClientProxyToV1(p *Proxy) ([]TypedProxyConfig, error) { + if p.IsRange() { + localPorts, err := frputil.ParseRangeNumbers(p.LocalPort) + if err != nil { + return nil, err + } + remotePorts, err := frputil.ParseRangeNumbers(p.RemotePort) + if err != nil { + return nil, err + } + if len(localPorts) != len(remotePorts) { + return nil, fmt.Errorf("local ports number should be same with remote ports number") + } + r := make([]TypedProxyConfig, len(localPorts)) + for i := range localPorts { + subPxy := *p + subPxy.Name = fmt.Sprintf("%s_%d", p.Name, i) + subPxy.LocalPort = strconv.FormatInt(localPorts[i], 10) + subPxy.RemotePort = strconv.FormatInt(remotePorts[i], 10) + if r[i], err = singleClientProxyToV1(&subPxy); err != nil { + return nil, err + } + } + r[0].Mgr.Range.Local = p.LocalPort + r[0].Mgr.Range.Remote = p.RemotePort + return r, nil + } else { + r, err := singleClientProxyToV1(p) + if err != nil { + return nil, err + } + return []TypedProxyConfig{r}, nil + } +} + +func singleClientProxyToV1(p *Proxy) (TypedProxyConfig, error) { + r := TypedProxyConfig{TypedProxyConfig: v1.TypedProxyConfig{Type: p.Type}} base, err := clientProxyBaseToV1(&p.BaseProxyConf) if err != nil { return r, err diff --git a/pkg/config/v1.go b/pkg/config/v1.go new file mode 100644 index 00000000..97086e15 --- /dev/null +++ b/pkg/config/v1.go @@ -0,0 +1,50 @@ +package config + +import ( + "encoding/json" + + "github.com/fatedier/frp/pkg/config/v1" +) + +type ClientConfigV1 struct { + v1.ClientCommonConfig + + Proxies []TypedProxyConfig `json:"proxies,omitempty"` + Visitors []v1.TypedVisitorConfig `json:"visitors,omitempty"` + + Mgr Mgr `json:"frpmgr,omitempty"` +} + +type Mgr struct { + ManualStart bool `json:"manualStart,omitempty"` + SVCBEnable bool `json:"svcbEnable,omitempty"` + AutoDelete AutoDelete `json:"autoDelete,omitempty"` +} + +type TypedProxyConfig struct { + v1.TypedProxyConfig + Mgr ProxyMgr `json:"frpmgr,omitempty"` +} + +type ProxyMgr struct { + Range RangePort `json:"range"` +} + +type RangePort struct { + Local string `json:"local"` + Remote string `json:"remote"` +} + +func (c *TypedProxyConfig) UnmarshalJSON(b []byte) error { + if err := c.TypedProxyConfig.UnmarshalJSON(b); err != nil { + return err + } + s := struct { + Mgr ProxyMgr `json:"frpmgr"` + }{} + if err := json.Unmarshal(b, &s); err != nil { + return err + } + c.Mgr = s.Mgr + return nil +} diff --git a/services/frp.go b/services/frp.go index 81a67bb1..14e3bdc9 100644 --- a/services/frp.go +++ b/services/frp.go @@ -4,8 +4,6 @@ import ( "os" frpconfig "github.com/fatedier/frp/pkg/config" - "github.com/fatedier/frp/pkg/config/legacy" - "github.com/fatedier/frp/pkg/config/v1" "github.com/fatedier/frp/pkg/config/v1/validation" "github.com/fatedier/frp/pkg/util/log" @@ -44,26 +42,3 @@ func VerifyClientConfig(path string) error { _, err = validation.ValidateAllClientConfig(cfg, proxyCfgs, visitorCfgs) return err } - -// VerifyClientProxy validates the frp proxy -func VerifyClientProxy(source []byte) error { - proxyCfgs, visitorCfgs, err := legacy.LoadAllProxyConfsFromIni("", source, nil) - if err != nil { - return err - } - for _, c := range proxyCfgs { - v1Cfg := legacy.Convert_ProxyConf_To_v1(c) - v1Cfg.Complete("") - if err = validation.ValidateProxyConfigurerForClient(v1Cfg); err != nil { - return err - } - } - for _, c := range visitorCfgs { - v1Cfg := legacy.Convert_VisitorConf_To_v1(c) - v1Cfg.Complete(new(v1.ClientCommonConfig)) - if err = validation.ValidateVisitorConfigurer(v1Cfg); err != nil { - return err - } - } - return nil -} diff --git a/ui/editclient.go b/ui/editclient.go index 38e9c23f..02e4a794 100644 --- a/ui/editclient.go +++ b/ui/editclient.go @@ -2,6 +2,7 @@ package ui import ( "fmt" + "math" "os" "path/filepath" "strings" @@ -346,6 +347,7 @@ func (cd *EditClientDialog) tlsConfPage() TabPage { func (cd *EditClientDialog) advancedConfPage() TabPage { muxChecked := Bind("muxCheck.Checked") + var legacy *walk.CheckBox return TabPage{ Title: i18n.Sprintf("Advanced"), Layout: Grid{Columns: 2}, @@ -374,6 +376,7 @@ func (cd *EditClientDialog) advancedConfPage() TabPage { Enabled: muxChecked, Value: Bind("TCPMuxKeepaliveInterval"), MinValue: 0, + MaxValue: math.MaxFloat64, SpinButtonsVisible: true, MinSize: Size{Width: 85}, Style: win.ES_RIGHT, @@ -384,9 +387,15 @@ func (cd *EditClientDialog) advancedConfPage() TabPage { CheckBox{Text: i18n.Sprintf("Exit after login failure"), Checked: Bind("LoginFailExit")}, CheckBox{Text: i18n.Sprintf("Disable auto-start at boot"), Checked: Bind("ManualStart")}, CheckBox{ - Name: "legacyFormat", - Text: i18n.Sprintf("Use legacy format config file"), - Checked: Bind("LegacyFormat"), + AssignTo: &legacy, + Name: "legacyFormat", + Text: i18n.Sprintf("Use legacy format config file"), + Checked: Bind("LegacyFormat"), + OnCheckedChanged: func() { + if !legacy.Checked() && !cd.canUpgradeFormat() { + legacy.SetChecked(true) + } + }, }, VSpacer{Size: 4}, Composite{ @@ -538,3 +547,16 @@ func (cd *EditClientDialog) hasConf(name string) bool { func (cd *EditClientDialog) Run(owner walk.Form) (int, error) { return cd.View().Run(owner) } + +func (cd *EditClientDialog) canUpgradeFormat() bool { + for _, v := range cd.data.Proxies { + if !v.IsVisitor() { + if _, err := config.ClientProxyToV1(v); err != nil { + showErrorMessage(cd.Form(), "", i18n.Sprintf("Unable to upgrade your config file due to proxy conversion failure, "+ + "please check the proxy config and try again.\n\nBad proxy: %s", v.Name)) + return false + } + } + } + return true +} diff --git a/ui/editproxy.go b/ui/editproxy.go index 8a23257b..e12b851d 100644 --- a/ui/editproxy.go +++ b/ui/editproxy.go @@ -1,17 +1,20 @@ package ui import ( + "math" "slices" + "strconv" "strings" + frputil "github.com/fatedier/frp/pkg/util/util" "github.com/lxn/walk" . "github.com/lxn/walk/declarative" + "github.com/lxn/win" "github.com/samber/lo" "github.com/koho/frpmgr/i18n" "github.com/koho/frpmgr/pkg/config" "github.com/koho/frpmgr/pkg/consts" - "github.com/koho/frpmgr/services" ) type EditProxyDialog struct { @@ -31,11 +34,9 @@ type EditProxyDialog struct { metaModel *AttributeModel // Views - nameView *walk.LineEdit - localPortView *walk.LineEdit - remotePortView *walk.LineEdit - typeView *walk.ComboBox - pluginView *walk.ComboBox + nameView *walk.LineEdit + typeView *walk.ComboBox + pluginView *walk.ComboBox } // View model for ui logics @@ -69,7 +70,7 @@ type editProxyBinder struct { // Extra fields needed for ui display Visitor bool - BandwidthNum string + BandwidthNum int64 BandwidthUnit string } @@ -126,11 +127,7 @@ func (pd *EditProxyDialog) View() Dialog { Children: []Widget{ LineEdit{AssignTo: &pd.nameView, Text: Bind("Name", consts.ValidateNonEmpty)}, PushButton{Text: i18n.SprintfLSpace("Random"), Image: loadIcon(consts.IconRandom, 16), OnClicked: func() { - rs := lo.RandomString(8, lo.AlphanumericCharset) - if strings.HasPrefix(pd.nameView.Text(), consts.RangePrefix) { - rs = consts.RangePrefix + rs - } - pd.nameView.SetText(rs) + pd.nameView.SetText(lo.RandomString(8, lo.AlphanumericCharset)) }}, }, }, @@ -186,21 +183,15 @@ func (pd *EditProxyDialog) basicProxyPage() TabPage { Label{Visible: Bind("vm.LocalAddrVisible"), Text: i18n.SprintfColon("Local Address")}, LineEdit{Visible: Bind("vm.LocalAddrVisible"), Text: Bind("LocalIP")}, Label{Visible: Bind("vm.LocalPortVisible"), Text: i18n.SprintfColon("Local Port")}, - LineEdit{ - AssignTo: &pd.localPortView, Visible: Bind("vm.LocalPortVisible"), - Text: Bind("LocalPort"), OnTextChanged: pd.watchRangePort, - }, + LineEdit{Visible: Bind("vm.LocalPortVisible"), Text: Bind("LocalPort")}, Label{Visible: Bind("vm.RemotePortVisible"), Text: i18n.SprintfColon("Remote Port")}, - LineEdit{ - AssignTo: &pd.remotePortView, Visible: Bind("vm.RemotePortVisible"), - Text: Bind("RemotePort"), OnTextChanged: pd.watchRangePort, - }, + LineEdit{Visible: Bind("vm.RemotePortVisible"), Text: Bind("RemotePort")}, Label{Visible: Bind("vm.RoleVisible && !vm.ServerNameVisible"), Text: i18n.SprintfColon("Allow Users")}, LineEdit{Visible: Bind("vm.RoleVisible && !vm.ServerNameVisible"), Text: Bind("AllowUsers")}, Label{Visible: Bind("vm.BindAddrVisible"), Text: i18n.SprintfColon("Bind Address")}, LineEdit{Visible: Bind("vm.BindAddrVisible"), Text: Bind("BindAddr")}, Label{Visible: Bind("vm.BindPortVisible"), Text: i18n.SprintfColon("Bind Port")}, - NumberEdit{Visible: Bind("vm.BindPortVisible"), Value: Bind("BindPort"), MinValue: 0, MaxValue: 65535}, + NumberEdit{Visible: Bind("vm.BindPortVisible"), Value: Bind("BindPort"), MinValue: -math.MaxFloat64, MaxValue: 65535}, Label{Visible: Bind("vm.ServerNameVisible"), Text: i18n.SprintfColon("Server Name")}, LineEdit{Visible: Bind("vm.ServerNameVisible"), Text: Bind("ServerName")}, Label{Visible: Bind("vm.ServerNameVisible"), Text: i18n.SprintfColon("Server User")}, @@ -245,7 +236,13 @@ func (pd *EditProxyDialog) advancedProxyPage() TabPage { Visible: Bind("vm.PluginEnable"), Layout: HBox{MarginsZero: true}, Children: []Widget{ - LineEdit{Text: Bind("BandwidthNum")}, + NumberEdit{ + Value: Bind("BandwidthNum"), + MinValue: 0, + MaxValue: math.MaxFloat64, + SpinButtonsVisible: true, + Style: win.ES_RIGHT, + }, ComboBox{Model: consts.Bandwidth, Value: Bind("BandwidthUnit")}, Label{Text: "@"}, ComboBox{ @@ -441,8 +438,8 @@ func (pd *EditProxyDialog) onSave() { pd.binder.Proxy.Role = "" } // Update bandwidth - if pd.binder.BandwidthNum != "" { - pd.binder.Proxy.BandwidthLimit = pd.binder.BandwidthNum + pd.binder.BandwidthUnit + if pd.binder.BandwidthNum > 0 { + pd.binder.Proxy.BandwidthLimit = strconv.FormatInt(pd.binder.BandwidthNum, 10) + pd.binder.BandwidthUnit if pd.binder.Proxy.BandwidthLimitMode == consts.BandwidthMode[0] { pd.binder.Proxy.BandwidthLimitMode = "" } @@ -450,16 +447,13 @@ func (pd *EditProxyDialog) onSave() { pd.binder.Proxy.BandwidthLimit = "" pd.binder.Proxy.BandwidthLimitMode = "" } - pb, err := pd.binder.Proxy.Marshal() - if err != nil { - showError(err, pd.Form()) - return - } - if err = services.VerifyClientProxy(pb); err != nil { - showError(err, pd.Form()) + pd.binder.Proxy.LocalPort = strings.TrimSpace(pd.binder.Proxy.LocalPort) + pd.binder.Proxy.RemotePort = strings.TrimSpace(pd.binder.Proxy.RemotePort) + if ok := pd.validateProxy(pd.binder.Proxy); !ok { return } *pd.Proxy = pd.binder.Proxy + pd.Proxy.Complete() pd.Accept() } @@ -533,44 +527,84 @@ func (pd *EditProxyDialog) switchType() { } } } - pd.watchRangePort() pd.vmDB.Reset() } -func (pd *EditProxyDialog) watchRangePort() { - var isRange bool - // The "range:" function requires both local port and remote port are set - if pd.viewModel.LocalPortVisible && pd.viewModel.RemotePortVisible { - for _, portView := range []*walk.LineEdit{pd.localPortView, pd.remotePortView} { - portText := portView.Text() - isRange = strings.Contains(portText, "-") || strings.Contains(portText, ",") - if isRange { - break - } - } +func splitBandwidth(s string) (int64, string) { + s = strings.TrimSpace(s) + if s == "" { + return 0, "MB" } - proxyName := pd.nameView.Text() - hasPrefix := strings.HasPrefix(proxyName, consts.RangePrefix) - if isRange { - if !hasPrefix { - pd.nameView.SetText(consts.RangePrefix + proxyName) - } - } else { - if hasPrefix { - pd.nameView.SetText(strings.TrimPrefix(proxyName, consts.RangePrefix)) - } + + if strings.HasSuffix(s, "MB") || strings.HasSuffix(s, "KB") { + unit := s[len(s)-2:] + num, _ := strconv.ParseInt(strings.TrimSuffix(s, unit), 10, 64) + return num, unit } + return 0, "MB" } -func splitBandwidth(s string) (string, string) { - s = strings.TrimSpace(s) - if s == "" { - return "", "MB" +func (pd *EditProxyDialog) validateProxy(p config.Proxy) bool { + if p.IsVisitor() { + if p.BindPort == 0 { + showErrorMessage(pd.Form(), "", i18n.Sprintf("Bind port is required.")) + return false + } + return true + } + if p.Plugin == "" && p.LocalPort == "" { + showErrorMessage(pd.Form(), "", i18n.Sprintf("Requires local port or plugin.")) + return false + } + if p.Plugin != "" { + p.LocalIP = "" + p.LocalPort = "" + } else if p.Type != consts.ProxyTypeTCP && p.Type != consts.ProxyTypeUDP { + if port, err := strconv.ParseInt(p.LocalPort, 10, 64); err != nil || port <= 0 { + showErrorMessage(pd.Form(), "", i18n.Sprintf("Invalid local port.")) + return false + } } - if strings.HasSuffix(s, "MB") { - return strings.TrimSuffix(s, "MB"), "MB" - } else if strings.HasSuffix(s, "KB") { - return strings.TrimSuffix(s, "KB"), "KB" + if p.HealthCheckType == "http" && p.HealthCheckURL == "" { + showErrorMessage(pd.Form(), "", i18n.Sprintf("Health check url is required.")) + return false + } + + switch p.Type { + case consts.ProxyTypeTCP, consts.ProxyTypeUDP: + if p.RemotePort == "" { + p.RemotePort = "0" + } + if p.Plugin != "" { + if p.IsRange() { + showErrorMessage(pd.Form(), "", i18n.Sprintf("The plugin does not support range ports.")) + } else if port, err := strconv.ParseInt(p.RemotePort, 10, 64); err != nil || port < 0 { + showErrorMessage(pd.Form(), "", i18n.Sprintf("Invalid remote port.")) + } else { + break + } + return false + } else { + localPorts, err := frputil.ParseRangeNumbers(p.LocalPort) + if err != nil { + showError(err, pd.Form()) + return false + } + remotePorts, err := frputil.ParseRangeNumbers(p.RemotePort) + if err != nil { + showError(err, pd.Form()) + return false + } + if p.IsRange() && len(localPorts) != len(remotePorts) { + showErrorMessage(pd.Form(), "", i18n.Sprintf("The number of local ports should be the same as the number of remote ports.")) + return false + } + } + case consts.ProxyTypeTCPMUX, consts.ProxyTypeHTTP, consts.ProxyTypeHTTPS: + if p.CustomDomains == "" && p.SubDomain == "" { + showErrorMessage(pd.Form(), "", i18n.Sprintf("Custom domains and subdomain should have at least one of these set.")) + return false + } } - return "", "MB" + return true } diff --git a/ui/proxyview.go b/ui/proxyview.go index 45a6ff63..107f2428 100644 --- a/ui/proxyview.go +++ b/ui/proxyview.go @@ -353,7 +353,9 @@ func (pv *ProxyView) onCopyAccessAddr() { } case consts.ProxyTypeXTCP, consts.ProxyTypeSTCP, consts.ProxyTypeSUDP: if proxy.Role == "visitor" { - access = util.GetOrElse(proxy.BindAddr, "127.0.0.1") + ":" + strconv.Itoa(proxy.BindPort) + if proxy.BindPort > 0 { + access = util.GetOrElse(proxy.BindAddr, "127.0.0.1") + ":" + strconv.Itoa(proxy.BindPort) + } } else { access = util.GetOrElse(proxy.LocalIP, "127.0.0.1") + ":" + proxy.LocalPort } @@ -378,7 +380,7 @@ func (pv *ProxyView) onClipboardImport() { var proxy *config.Proxy if strings.HasPrefix(text, "[[proxies]]") { var proxies struct { - C []v1.TypedProxyConfig `json:"proxies"` + C []config.TypedProxyConfig `json:"proxies"` } if err = frpconfig.LoadConfigure([]byte(text), &proxies, false); err == nil && len(proxies.C) > 0 { proxy = config.ClientProxyFromV1(proxies.C[0]) diff --git a/ui/simpleproxy.go b/ui/simpleproxy.go index 39290743..581ff791 100644 --- a/ui/simpleproxy.go +++ b/ui/simpleproxy.go @@ -96,7 +96,6 @@ func (sp *SimpleProxyDialog) onSave() { RemotePort: sp.binder.RemotePort, } if sp.binder.LocalPortMin != "" && sp.binder.LocalPortMax != "" { - proxy.Name = consts.RangePrefix + proxy.Name portRange := fmt.Sprintf("%s-%s", sp.binder.LocalPortMin, sp.binder.LocalPortMax) proxy.LocalPort += "," + portRange proxy.RemotePort += "," + portRange From c64becdde1d4ebf8043f40a2fdfbee002465d998 Mon Sep 17 00:00:00 2001 From: Gerhard Tan Date: Sun, 10 Mar 2024 01:48:42 +0800 Subject: [PATCH 5/6] Add greedy layout for number edit --- go.mod | 4 ++-- go.sum | 4 ++-- pkg/consts/res.go | 1 - ui/editproxy.go | 1 + 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/go.mod b/go.mod index 1d326483..879d6cd4 100644 --- a/go.mod +++ b/go.mod @@ -8,6 +8,7 @@ require ( github.com/lxn/walk v0.0.0-20210112085537-c389da54e794 github.com/lxn/win v0.0.0-20210218163916-a377121e959e github.com/miekg/dns v1.1.58 + github.com/pelletier/go-toml/v2 v2.1.0 github.com/samber/lo v1.39.0 golang.org/x/sys v0.17.0 golang.org/x/text v0.14.0 @@ -33,7 +34,6 @@ require ( github.com/klauspost/cpuid/v2 v2.0.6 // indirect github.com/klauspost/reedsolomon v1.9.15 // indirect github.com/onsi/ginkgo/v2 v2.11.0 // indirect - github.com/pelletier/go-toml/v2 v2.1.0 // indirect github.com/pion/dtls/v2 v2.2.7 // indirect github.com/pion/logging v0.2.2 // indirect github.com/pion/stun v0.6.1 // indirect @@ -64,4 +64,4 @@ require ( sigs.k8s.io/yaml v1.3.0 // indirect ) -replace github.com/lxn/walk => github.com/koho/frpmgr v0.0.0-20240228174759-ec59bb05f3d7 +replace github.com/lxn/walk => github.com/koho/frpmgr v0.0.0-20240309173424-3817a91bcc39 diff --git a/go.sum b/go.sum index ee5ba967..3e7996c6 100644 --- a/go.sum +++ b/go.sum @@ -75,8 +75,8 @@ github.com/klauspost/cpuid/v2 v2.0.6 h1:dQ5ueTiftKxp0gyjKSx5+8BtPWkyQbd95m8Gys/R github.com/klauspost/cpuid/v2 v2.0.6/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= github.com/klauspost/reedsolomon v1.9.15 h1:g2erWKD2M6rgnPf89fCji6jNlhMKMdXcuNHMW1SYCIo= github.com/klauspost/reedsolomon v1.9.15/go.mod h1:eqPAcE7xar5CIzcdfwydOEdcmchAKAP/qs14y4GCBOk= -github.com/koho/frpmgr v0.0.0-20240228174759-ec59bb05f3d7 h1:GbWLEZJc4BL9/cePQ2Z8hnYAEEbeeZ4GBfhhinNLy54= -github.com/koho/frpmgr v0.0.0-20240228174759-ec59bb05f3d7/go.mod h1:CdksCbC3x4Swi/ePNXCeg08K1i3XdIVdy3o7elo92k8= +github.com/koho/frpmgr v0.0.0-20240309173424-3817a91bcc39 h1:xn1qQrWzrxVNwnxVmHmKPyoPbYKWK7WmefftOad86Z0= +github.com/koho/frpmgr v0.0.0-20240309173424-3817a91bcc39/go.mod h1:CdksCbC3x4Swi/ePNXCeg08K1i3XdIVdy3o7elo92k8= github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0= github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= diff --git a/pkg/consts/res.go b/pkg/consts/res.go index 4a3b127e..d6954417 100644 --- a/pkg/consts/res.go +++ b/pkg/consts/res.go @@ -129,7 +129,6 @@ var ( var ( ValidateNonEmpty = validators.Regexp{Pattern: "[^\\s]+"} ValidateRequireInteger = validators.Regexp{Pattern: "^\\d+$"} - ValidateInteger = validators.Regexp{Pattern: "^\\d*$"} ValidatePortRange = []Validator{ValidateRequireInteger, validators.Range{Min: 0, Max: 65535}} ) diff --git a/ui/editproxy.go b/ui/editproxy.go index e12b851d..b937e2b1 100644 --- a/ui/editproxy.go +++ b/ui/editproxy.go @@ -242,6 +242,7 @@ func (pd *EditProxyDialog) advancedProxyPage() TabPage { MaxValue: math.MaxFloat64, SpinButtonsVisible: true, Style: win.ES_RIGHT, + Greedy: true, }, ComboBox{Model: consts.Bandwidth, Value: Bind("BandwidthUnit")}, Label{Text: "@"}, From 723024a4eec6c1c55f00bd12efc969c6d561cf19 Mon Sep 17 00:00:00 2001 From: Gerhard Tan Date: Sun, 10 Mar 2024 01:57:02 +0800 Subject: [PATCH 6/6] Fix json tag --- pkg/config/v1.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/config/v1.go b/pkg/config/v1.go index 97086e15..b806c8ea 100644 --- a/pkg/config/v1.go +++ b/pkg/config/v1.go @@ -27,7 +27,7 @@ type TypedProxyConfig struct { } type ProxyMgr struct { - Range RangePort `json:"range"` + Range RangePort `json:"range,omitempty"` } type RangePort struct {