mirror of
https://github.com/bolucat/Archive.git
synced 2025-12-24 13:28:37 +08:00
Update On Wed Dec 10 19:41:24 CET 2025
This commit is contained in:
1
.github/update.log
vendored
1
.github/update.log
vendored
@@ -1207,3 +1207,4 @@ Update On Sat Dec 6 19:36:39 CET 2025
|
||||
Update On Sun Dec 7 19:36:46 CET 2025
|
||||
Update On Mon Dec 8 19:42:31 CET 2025
|
||||
Update On Tue Dec 9 19:39:21 CET 2025
|
||||
Update On Wed Dec 10 19:41:17 CET 2025
|
||||
|
||||
@@ -30,6 +30,7 @@ type SudokuOption struct {
|
||||
TableType string `proxy:"table-type,omitempty"` // "prefer_ascii" or "prefer_entropy"
|
||||
EnablePureDownlink *bool `proxy:"enable-pure-downlink,omitempty"`
|
||||
HTTPMask bool `proxy:"http-mask,omitempty"`
|
||||
CustomTable string `proxy:"custom-table,omitempty"` // optional custom byte layout, e.g. xpxvvpvv
|
||||
}
|
||||
|
||||
// DialContext implements C.ProxyAdapter
|
||||
@@ -178,13 +179,17 @@ func NewSudoku(option SudokuOption) (*Sudoku, error) {
|
||||
ServerAddress: net.JoinHostPort(option.Server, strconv.Itoa(option.Port)),
|
||||
Key: option.Key,
|
||||
AEADMethod: defaultConf.AEADMethod,
|
||||
Table: sudoku.NewTable(sudoku.ClientAEADSeed(option.Key), tableType),
|
||||
PaddingMin: paddingMin,
|
||||
PaddingMax: paddingMax,
|
||||
EnablePureDownlink: enablePureDownlink,
|
||||
HandshakeTimeoutSeconds: defaultConf.HandshakeTimeoutSeconds,
|
||||
DisableHTTPMask: !option.HTTPMask,
|
||||
}
|
||||
table, err := sudoku.NewTableWithCustom(sudoku.ClientAEADSeed(option.Key), tableType, option.CustomTable)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("build table failed: %w", err)
|
||||
}
|
||||
baseConf.Table = table
|
||||
if option.AEADMethod != "" {
|
||||
baseConf.AEADMethod = option.AEADMethod
|
||||
}
|
||||
|
||||
@@ -609,6 +609,13 @@ func (w *WireGuard) ResolveUDP(ctx context.Context, metadata *C.Metadata) error
|
||||
return nil
|
||||
}
|
||||
|
||||
// ProxyInfo implements C.ProxyAdapter
|
||||
func (w *WireGuard) ProxyInfo() C.ProxyInfo {
|
||||
info := w.Base.ProxyInfo()
|
||||
info.DialerProxy = w.option.DialerProxy
|
||||
return info
|
||||
}
|
||||
|
||||
// IsL3Protocol implements C.ProxyAdapter
|
||||
func (w *WireGuard) IsL3Protocol(metadata *C.Metadata) bool {
|
||||
return true
|
||||
|
||||
@@ -8,6 +8,7 @@ import (
|
||||
"reflect"
|
||||
"runtime"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/metacubex/mihomo/adapter"
|
||||
@@ -43,6 +44,7 @@ type providerForApi struct {
|
||||
}
|
||||
|
||||
type baseProvider struct {
|
||||
mutex sync.RWMutex
|
||||
name string
|
||||
proxies []C.Proxy
|
||||
healthCheck *HealthCheck
|
||||
@@ -54,6 +56,8 @@ func (bp *baseProvider) Name() string {
|
||||
}
|
||||
|
||||
func (bp *baseProvider) Version() uint32 {
|
||||
bp.mutex.RLock()
|
||||
defer bp.mutex.RUnlock()
|
||||
return bp.version
|
||||
}
|
||||
|
||||
@@ -73,10 +77,14 @@ func (bp *baseProvider) Type() P.ProviderType {
|
||||
}
|
||||
|
||||
func (bp *baseProvider) Proxies() []C.Proxy {
|
||||
bp.mutex.RLock()
|
||||
defer bp.mutex.RUnlock()
|
||||
return bp.proxies
|
||||
}
|
||||
|
||||
func (bp *baseProvider) Count() int {
|
||||
bp.mutex.RLock()
|
||||
defer bp.mutex.RUnlock()
|
||||
return len(bp.proxies)
|
||||
}
|
||||
|
||||
@@ -93,6 +101,8 @@ func (bp *baseProvider) RegisterHealthCheckTask(url string, expectedStatus utils
|
||||
}
|
||||
|
||||
func (bp *baseProvider) setProxies(proxies []C.Proxy) {
|
||||
bp.mutex.Lock()
|
||||
defer bp.mutex.Unlock()
|
||||
bp.proxies = proxies
|
||||
bp.version += 1
|
||||
bp.healthCheck.setProxies(proxies)
|
||||
|
||||
@@ -1048,8 +1048,9 @@ proxies: # socks5
|
||||
padding-min: 2 # 最小填充字节数
|
||||
padding-max: 7 # 最大填充字节数
|
||||
table-type: prefer_ascii # 可选值:prefer_ascii、prefer_entropy 前者全ascii映射,后者保证熵值(汉明1)低于3
|
||||
# custom-table: xpxvvpvv # 可选,自定义字节布局,必须包含2个x、2个p、4个v,可随意组合。启用此处则无需配置`table-type`
|
||||
http-mask: true # 是否启用http掩码
|
||||
enable-pure-downlink: false # 是否启用混淆下行,false的情况下能在保证数据安全的前提下极大提升下行速度
|
||||
enable-pure-downlink: false # 是否启用混淆下行,false的情况下能在保证数据安全的前提下极大提升下行速度,与服务端端保持相同(如果此处为false,则要求aead不可为none)
|
||||
|
||||
# anytls
|
||||
- name: anytls
|
||||
@@ -1589,8 +1590,9 @@ listeners:
|
||||
padding-min: 1 # 填充最小长度
|
||||
padding-max: 15 # 填充最大长度,均不建议过大
|
||||
table-type: prefer_ascii # 可选值:prefer_ascii、prefer_entropy 前者全ascii映射,后者保证熵值(汉明1)低于3
|
||||
# custom-table: xpxvvpvv # 可选,自定义字节布局,必须包含2个x、2个p、4个v
|
||||
handshake-timeout: 5 # optional
|
||||
enable-pure-downlink: false # 是否启用混淆下行,false的情况下能在保证数据安全的前提下极大提升下行速度,与客户端保持相同
|
||||
enable-pure-downlink: false # 是否启用混淆下行,false的情况下能在保证数据安全的前提下极大提升下行速度,与客户端保持相同(如果此处为false,则要求aead不可为none)
|
||||
|
||||
|
||||
|
||||
@@ -1742,4 +1744,3 @@ listeners:
|
||||
# alpn:
|
||||
# - h3
|
||||
# max-udp-relay-packet-size: 1500
|
||||
|
||||
|
||||
@@ -43,7 +43,7 @@ require (
|
||||
github.com/mroth/weightedrand/v2 v2.1.0
|
||||
github.com/openacid/low v0.1.21
|
||||
github.com/oschwald/maxminddb-golang v1.12.0 // lastest version compatible with golang1.20
|
||||
github.com/saba-futai/sudoku v0.0.2-b
|
||||
github.com/saba-futai/sudoku v0.0.2-c
|
||||
github.com/sagernet/cors v1.2.1
|
||||
github.com/sagernet/netlink v0.0.0-20240612041022-b9a21c07ac6a
|
||||
github.com/samber/lo v1.52.0
|
||||
|
||||
@@ -171,8 +171,8 @@ github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZN
|
||||
github.com/prashantv/gostub v1.1.0 h1:BTyx3RfQjRHnUWaGF9oQos79AlQ5k8WNktv7VGvVH4g=
|
||||
github.com/quic-go/qpack v0.4.0 h1:Cr9BXA1sQS2SmDUWjSofMPNKmvF6IiIfDRmgU0w1ZCo=
|
||||
github.com/quic-go/qpack v0.4.0/go.mod h1:UZVnYIfi5GRk+zI9UMaCPsmZ2xKJP7XBUvVyT1Knj9A=
|
||||
github.com/saba-futai/sudoku v0.0.2-b h1:IbBjgZe1IzzD4xjaCSAdAy8ZNrwOusT14AwCYm77NwI=
|
||||
github.com/saba-futai/sudoku v0.0.2-b/go.mod h1:Rvggsoprp7HQM7bMIZUd1M27bPj8THRsZdY1dGbIAvo=
|
||||
github.com/saba-futai/sudoku v0.0.2-c h1:0CaoCKx4Br8UL97fnIxn8Y7rnQpflBza7kfaIrdg2rI=
|
||||
github.com/saba-futai/sudoku v0.0.2-c/go.mod h1:Rvggsoprp7HQM7bMIZUd1M27bPj8THRsZdY1dGbIAvo=
|
||||
github.com/sagernet/cors v1.2.1 h1:Cv5Z8y9YSD6Gm+qSpNrL3LO4lD3eQVvbFYJSG7JCMHQ=
|
||||
github.com/sagernet/cors v1.2.1/go.mod h1:O64VyOjjhrkLmQIjF4KGRrJO/5dVXFdpEmCW/eISRAI=
|
||||
github.com/sagernet/netlink v0.0.0-20240612041022-b9a21c07ac6a h1:ObwtHN2VpqE0ZNjr6sGeT00J8uU7JF4cNUdb44/Duis=
|
||||
|
||||
@@ -14,6 +14,7 @@ type SudokuServer struct {
|
||||
TableType string `json:"table-type,omitempty"`
|
||||
HandshakeTimeoutSecond *int `json:"handshake-timeout,omitempty"`
|
||||
EnablePureDownlink *bool `json:"enable-pure-downlink,omitempty"`
|
||||
CustomTable string `json:"custom-table,omitempty"`
|
||||
}
|
||||
|
||||
func (s SudokuServer) String() string {
|
||||
|
||||
@@ -20,6 +20,7 @@ type SudokuOption struct {
|
||||
TableType string `inbound:"table-type,omitempty"` // "prefer_ascii" or "prefer_entropy"
|
||||
HandshakeTimeoutSecond *int `inbound:"handshake-timeout,omitempty"`
|
||||
EnablePureDownlink *bool `inbound:"enable-pure-downlink,omitempty"`
|
||||
CustomTable string `inbound:"custom-table,omitempty"` // optional custom byte layout, e.g. xpxvvpvv
|
||||
}
|
||||
|
||||
func (o SudokuOption) Equal(config C.InboundConfig) bool {
|
||||
@@ -52,6 +53,7 @@ func NewSudoku(options *SudokuOption) (*Sudoku, error) {
|
||||
TableType: options.TableType,
|
||||
HandshakeTimeoutSecond: options.HandshakeTimeoutSecond,
|
||||
EnablePureDownlink: options.EnablePureDownlink,
|
||||
CustomTable: options.CustomTable,
|
||||
}
|
||||
|
||||
return &Sudoku{
|
||||
|
||||
@@ -138,3 +138,27 @@ func TestInboundSudoku_PackedDownlink(t *testing.T) {
|
||||
testInboundSudoku(t, inboundOptions, outboundOptions)
|
||||
})
|
||||
}
|
||||
|
||||
func TestInboundSudoku_CustomTable(t *testing.T) {
|
||||
key := "test_key_custom"
|
||||
custom := "xpxvvpvv"
|
||||
inboundOptions := inbound.SudokuOption{
|
||||
Key: key,
|
||||
TableType: "prefer_entropy",
|
||||
CustomTable: custom,
|
||||
}
|
||||
outboundOptions := outbound.SudokuOption{
|
||||
Key: key,
|
||||
TableType: "prefer_entropy",
|
||||
CustomTable: custom,
|
||||
}
|
||||
testInboundSudoku(t, inboundOptions, outboundOptions)
|
||||
|
||||
t.Run("ed25519key", func(t *testing.T) {
|
||||
inboundOptions := inboundOptions
|
||||
outboundOptions := outboundOptions
|
||||
inboundOptions.Key = sudokuPublicKey
|
||||
outboundOptions.Key = sudokuPrivateKey
|
||||
testInboundSudoku(t, inboundOptions, outboundOptions)
|
||||
})
|
||||
}
|
||||
|
||||
@@ -152,6 +152,12 @@ func New(config LC.SudokuServer, tunnel C.Tunnel, additions ...inbound.Addition)
|
||||
enablePureDownlink = *config.EnablePureDownlink
|
||||
}
|
||||
|
||||
table, err := sudoku.NewTableWithCustom(config.Key, tableType, config.CustomTable)
|
||||
if err != nil {
|
||||
_ = l.Close()
|
||||
return nil, err
|
||||
}
|
||||
|
||||
handshakeTimeout := defaultConf.HandshakeTimeoutSeconds
|
||||
if config.HandshakeTimeoutSecond != nil {
|
||||
handshakeTimeout = *config.HandshakeTimeoutSecond
|
||||
@@ -160,7 +166,7 @@ func New(config LC.SudokuServer, tunnel C.Tunnel, additions ...inbound.Addition)
|
||||
protoConf := sudoku.ProtocolConfig{
|
||||
Key: config.Key,
|
||||
AEADMethod: defaultConf.AEADMethod,
|
||||
Table: sudoku.NewTable(config.Key, tableType),
|
||||
Table: table,
|
||||
PaddingMin: paddingMin,
|
||||
PaddingMax: paddingMax,
|
||||
EnablePureDownlink: enablePureDownlink,
|
||||
|
||||
@@ -146,12 +146,23 @@ func buildHandshakePayload(key string) [16]byte {
|
||||
}
|
||||
|
||||
func NewTable(key string, tableType string) *sudoku.Table {
|
||||
start := time.Now()
|
||||
table := sudoku.NewTable(key, tableType)
|
||||
log.Infoln("[Sudoku] Tables initialized (%s) in %v", tableType, time.Since(start))
|
||||
table, err := NewTableWithCustom(key, tableType, "")
|
||||
if err != nil {
|
||||
panic(fmt.Sprintf("[Sudoku] failed to init tables: %v", err))
|
||||
}
|
||||
return table
|
||||
}
|
||||
|
||||
func NewTableWithCustom(key string, tableType string, customTable string) (*sudoku.Table, error) {
|
||||
start := time.Now()
|
||||
table, err := sudoku.NewTableWithCustom(key, tableType, customTable)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
log.Infoln("[Sudoku] Tables initialized (%s, custom=%v) in %v", tableType, customTable != "", time.Since(start))
|
||||
return table, nil
|
||||
}
|
||||
|
||||
func ClientAEADSeed(key string) string {
|
||||
if recovered, err := crypto.RecoverPublicKey(key); err == nil {
|
||||
return crypto.EncodePoint(recovered)
|
||||
|
||||
@@ -228,3 +228,22 @@ func runPackedUoTSession(id int, cfg *apis.ProtocolConfig, errCh chan<- error) {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
func TestCustomTableHandshake(t *testing.T) {
|
||||
table, err := sudokuobfs.NewTableWithCustom("custom-seed", "prefer_entropy", "xpxvvpvv")
|
||||
if err != nil {
|
||||
t.Fatalf("build custom table: %v", err)
|
||||
}
|
||||
cfg := newPackedConfig(table)
|
||||
errCh := make(chan error, 2)
|
||||
|
||||
runPackedTCPSession(42, cfg, errCh)
|
||||
runPackedUoTSession(43, cfg, errCh)
|
||||
|
||||
close(errCh)
|
||||
for err := range errCh {
|
||||
if err != nil {
|
||||
t.Fatalf("custom table handshake failed: %v", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,9 +3,9 @@
|
||||
"latest": {
|
||||
"mihomo": "v1.19.17",
|
||||
"mihomo_alpha": "alpha-17b8eb8",
|
||||
"clash_rs": "v0.9.2",
|
||||
"clash_rs": "v0.9.3",
|
||||
"clash_premium": "2023-09-05-gdcc8d87",
|
||||
"clash_rs_alpha": "0.9.2-alpha+sha.c9fe9e2"
|
||||
"clash_rs_alpha": "0.9.3-alpha+sha.a6538ac"
|
||||
},
|
||||
"arch_template": {
|
||||
"mihomo": {
|
||||
@@ -69,5 +69,5 @@
|
||||
"linux-armv7hf": "clash-armv7-unknown-linux-gnueabihf"
|
||||
}
|
||||
},
|
||||
"updated_at": "2025-12-08T22:21:34.201Z"
|
||||
"updated_at": "2025-12-09T22:21:41.769Z"
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
FROM ghcr.io/linuxserver/baseimage-alpine:3.22
|
||||
FROM ghcr.io/linuxserver/baseimage-alpine:3.23
|
||||
|
||||
RUN apk update && \
|
||||
apk --no-cache add ca-certificates mailcap jq libcap
|
||||
|
||||
@@ -71,5 +71,5 @@
|
||||
"vite-plugin-compression2": "^2.3.1",
|
||||
"vue-tsc": "^3.1.3"
|
||||
},
|
||||
"packageManager": "pnpm@10.24.0+sha512.01ff8ae71b4419903b65c60fb2dc9d34cf8bb6e06d03bde112ef38f7a34d6904c424ba66bea5cdcf12890230bf39f9580473140ed9c946fef328b6e5238a345a"
|
||||
"packageManager": "pnpm@10.25.0+sha512.5e82639027af37cf832061bcc6d639c219634488e0f2baebe785028a793de7b525ffcd3f7ff574f5e9860654e098fe852ba8ac5dd5cefe1767d23a020a92f501"
|
||||
}
|
||||
|
||||
193
filebrowser/frontend/pnpm-lock.yaml
generated
193
filebrowser/frontend/pnpm-lock.yaml
generated
@@ -25,7 +25,7 @@ importers:
|
||||
version: 1.11.19
|
||||
dompurify:
|
||||
specifier: ^3.2.6
|
||||
version: 3.3.0
|
||||
version: 3.3.1
|
||||
epubjs:
|
||||
specifier: ^0.3.93
|
||||
version: 0.3.93
|
||||
@@ -107,16 +107,16 @@ importers:
|
||||
version: 4.17.12
|
||||
'@types/node':
|
||||
specifier: ^24.10.1
|
||||
version: 24.10.1
|
||||
version: 24.10.2
|
||||
'@typescript-eslint/eslint-plugin':
|
||||
specifier: ^8.37.0
|
||||
version: 8.48.1(@typescript-eslint/parser@8.37.0(eslint@9.39.1)(typescript@5.9.3))(eslint@9.39.1)(typescript@5.9.3)
|
||||
version: 8.49.0(@typescript-eslint/parser@8.37.0(eslint@9.39.1)(typescript@5.9.3))(eslint@9.39.1)(typescript@5.9.3)
|
||||
'@vitejs/plugin-legacy':
|
||||
specifier: ^7.2.1
|
||||
version: 7.2.1(terser@5.44.1)(vite@7.2.6(@types/node@24.10.1)(terser@5.44.1)(yaml@2.7.0))
|
||||
version: 7.2.1(terser@5.44.1)(vite@7.2.7(@types/node@24.10.2)(terser@5.44.1)(yaml@2.7.0))
|
||||
'@vitejs/plugin-vue':
|
||||
specifier: ^6.0.1
|
||||
version: 6.0.2(vite@7.2.6(@types/node@24.10.1)(terser@5.44.1)(yaml@2.7.0))(vue@3.5.25(typescript@5.9.3))
|
||||
version: 6.0.2(vite@7.2.7(@types/node@24.10.2)(terser@5.44.1)(yaml@2.7.0))(vue@3.5.25(typescript@5.9.3))
|
||||
'@vue/eslint-config-prettier':
|
||||
specifier: ^10.2.0
|
||||
version: 10.2.0(eslint@9.39.1)(prettier@3.7.4)
|
||||
@@ -155,13 +155,13 @@ importers:
|
||||
version: 5.9.3
|
||||
vite:
|
||||
specifier: ^7.2.2
|
||||
version: 7.2.6(@types/node@24.10.1)(terser@5.44.1)(yaml@2.7.0)
|
||||
version: 7.2.7(@types/node@24.10.2)(terser@5.44.1)(yaml@2.7.0)
|
||||
vite-plugin-compression2:
|
||||
specifier: ^2.3.1
|
||||
version: 2.3.1(rollup@4.53.3)
|
||||
version: 2.4.0(rollup@4.53.3)
|
||||
vue-tsc:
|
||||
specifier: ^3.1.3
|
||||
version: 3.1.5(typescript@5.9.3)
|
||||
version: 3.1.8(typescript@5.9.3)
|
||||
|
||||
packages:
|
||||
|
||||
@@ -1110,8 +1110,8 @@ packages:
|
||||
'@types/lodash@4.17.13':
|
||||
resolution: {integrity: sha512-lfx+dftrEZcdBPczf9d0Qv0x+j/rfNCMuC6OcfXmO8gkfeNAY88PgKUbvG56whcN23gc27yenwF6oJZXGFpYxg==}
|
||||
|
||||
'@types/node@24.10.1':
|
||||
resolution: {integrity: sha512-GNWcUTRBgIRJD5zj+Tq0fKOJ5XZajIiBroOF0yvj2bSU1WvNdYS/dn9UxwsujGW4JX06dnHyjV2y9rRaybH0iQ==}
|
||||
'@types/node@24.10.2':
|
||||
resolution: {integrity: sha512-WOhQTZ4G8xZ1tjJTvKOpyEVSGgOTvJAfDK3FNFgELyaTpzhdgHVHeqW8V+UJvzF5BT+/B54T/1S2K6gd9c7bbA==}
|
||||
|
||||
'@types/trusted-types@2.0.7':
|
||||
resolution: {integrity: sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==}
|
||||
@@ -1127,11 +1127,11 @@ packages:
|
||||
eslint: ^8.57.0 || ^9.0.0
|
||||
typescript: '>=4.8.4 <5.9.0'
|
||||
|
||||
'@typescript-eslint/eslint-plugin@8.48.1':
|
||||
resolution: {integrity: sha512-X63hI1bxl5ohelzr0LY5coufyl0LJNthld+abwxpCoo6Gq+hSqhKwci7MUWkXo67mzgUK6YFByhmaHmUcuBJmA==}
|
||||
'@typescript-eslint/eslint-plugin@8.49.0':
|
||||
resolution: {integrity: sha512-JXij0vzIaTtCwu6SxTh8qBc66kmf1xs7pI4UOiMDFVct6q86G0Zs7KRcEoJgY3Cav3x5Tq0MF5jwgpgLqgKG3A==}
|
||||
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
|
||||
peerDependencies:
|
||||
'@typescript-eslint/parser': ^8.48.1
|
||||
'@typescript-eslint/parser': ^8.49.0
|
||||
eslint: ^8.57.0 || ^9.0.0
|
||||
typescript: '>=4.8.4 <6.0.0'
|
||||
|
||||
@@ -1154,8 +1154,8 @@ packages:
|
||||
peerDependencies:
|
||||
typescript: '>=4.8.4 <6.0.0'
|
||||
|
||||
'@typescript-eslint/project-service@8.48.1':
|
||||
resolution: {integrity: sha512-HQWSicah4s9z2/HifRPQ6b6R7G+SBx64JlFQpgSSHWPKdvCZX57XCbszg/bapbRsOEv42q5tayTYcEFpACcX1w==}
|
||||
'@typescript-eslint/project-service@8.49.0':
|
||||
resolution: {integrity: sha512-/wJN0/DKkmRUMXjZUXYZpD1NEQzQAAn9QWfGwo+Ai8gnzqH7tvqS7oNVdTjKqOcPyVIdZdyCMoqN66Ia789e7g==}
|
||||
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
|
||||
peerDependencies:
|
||||
typescript: '>=4.8.4 <6.0.0'
|
||||
@@ -1168,8 +1168,8 @@ packages:
|
||||
resolution: {integrity: sha512-tMDbLGXb1wC+McN1M6QeDx7P7c0UWO5z9CXqp7J8E+xGcJuUuevWKxuG8j41FoweS3+L41SkyKKkia16jpX7CA==}
|
||||
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
|
||||
|
||||
'@typescript-eslint/scope-manager@8.48.1':
|
||||
resolution: {integrity: sha512-rj4vWQsytQbLxC5Bf4XwZ0/CKd362DkWMUkviT7DCS057SK64D5lH74sSGzhI6PDD2HCEq02xAP9cX68dYyg1w==}
|
||||
'@typescript-eslint/scope-manager@8.49.0':
|
||||
resolution: {integrity: sha512-npgS3zi+/30KSOkXNs0LQXtsg9ekZ8OISAOLGWA/ZOEn0ZH74Ginfl7foziV8DT+D98WfQ5Kopwqb/PZOaIJGg==}
|
||||
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
|
||||
|
||||
'@typescript-eslint/tsconfig-utils@8.37.0':
|
||||
@@ -1184,8 +1184,8 @@ packages:
|
||||
peerDependencies:
|
||||
typescript: '>=4.8.4 <6.0.0'
|
||||
|
||||
'@typescript-eslint/tsconfig-utils@8.48.1':
|
||||
resolution: {integrity: sha512-k0Jhs4CpEffIBm6wPaCXBAD7jxBtrHjrSgtfCjUvPp9AZ78lXKdTR8fxyZO5y4vWNlOvYXRtngSZNSn+H53Jkw==}
|
||||
'@typescript-eslint/tsconfig-utils@8.49.0':
|
||||
resolution: {integrity: sha512-8prixNi1/6nawsRYxet4YOhnbW+W9FK/bQPxsGB1D3ZrDzbJ5FXw5XmzxZv82X3B+ZccuSxo/X8q9nQ+mFecWA==}
|
||||
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
|
||||
peerDependencies:
|
||||
typescript: '>=4.8.4 <6.0.0'
|
||||
@@ -1197,8 +1197,8 @@ packages:
|
||||
eslint: ^8.57.0 || ^9.0.0
|
||||
typescript: '>=4.8.4 <5.9.0'
|
||||
|
||||
'@typescript-eslint/type-utils@8.48.1':
|
||||
resolution: {integrity: sha512-1jEop81a3LrJQLTf/1VfPQdhIY4PlGDBc/i67EVWObrtvcziysbLN3oReexHOM6N3jyXgCrkBsZpqwH0hiDOQg==}
|
||||
'@typescript-eslint/type-utils@8.49.0':
|
||||
resolution: {integrity: sha512-KTExJfQ+svY8I10P4HdxKzWsvtVnsuCifU5MvXrRwoP2KOlNZ9ADNEWWsQTJgMxLzS5VLQKDjkCT/YzgsnqmZg==}
|
||||
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
|
||||
peerDependencies:
|
||||
eslint: ^8.57.0 || ^9.0.0
|
||||
@@ -1212,8 +1212,8 @@ packages:
|
||||
resolution: {integrity: sha512-USjyxm3gQEePdUwJBFjjGNG18xY9A2grDVGuk7/9AkjIF1L+ZrVnwR5VAU5JXtUnBL/Nwt3H31KlRDaksnM7/w==}
|
||||
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
|
||||
|
||||
'@typescript-eslint/types@8.48.1':
|
||||
resolution: {integrity: sha512-+fZ3LZNeiELGmimrujsDCT4CRIbq5oXdHe7chLiW8qzqyPMnn1puNstCrMNVAqwcl2FdIxkuJ4tOs/RFDBVc/Q==}
|
||||
'@typescript-eslint/types@8.49.0':
|
||||
resolution: {integrity: sha512-e9k/fneezorUo6WShlQpMxXh8/8wfyc+biu6tnAqA81oWrEic0k21RHzP9uqqpyBBeBKu4T+Bsjy9/b8u7obXQ==}
|
||||
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
|
||||
|
||||
'@typescript-eslint/typescript-estree@8.37.0':
|
||||
@@ -1228,8 +1228,8 @@ packages:
|
||||
peerDependencies:
|
||||
typescript: '>=4.8.4 <6.0.0'
|
||||
|
||||
'@typescript-eslint/typescript-estree@8.48.1':
|
||||
resolution: {integrity: sha512-/9wQ4PqaefTK6POVTjJaYS0bynCgzh6ClJHGSBj06XEHjkfylzB+A3qvyaXnErEZSaxhIo4YdyBgq6j4RysxDg==}
|
||||
'@typescript-eslint/typescript-estree@8.49.0':
|
||||
resolution: {integrity: sha512-jrLdRuAbPfPIdYNppHJ/D0wN+wwNfJ32YTAm10eJVsFmrVpXQnDWBn8niCSMlWjvml8jsce5E/O+86IQtTbJWA==}
|
||||
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
|
||||
peerDependencies:
|
||||
typescript: '>=4.8.4 <6.0.0'
|
||||
@@ -1241,8 +1241,8 @@ packages:
|
||||
eslint: ^8.57.0 || ^9.0.0
|
||||
typescript: '>=4.8.4 <5.9.0'
|
||||
|
||||
'@typescript-eslint/utils@8.48.1':
|
||||
resolution: {integrity: sha512-fAnhLrDjiVfey5wwFRwrweyRlCmdz5ZxXz2G/4cLn0YDLjTapmN4gcCsTBR1N2rWnZSDeWpYtgLDsJt+FpmcwA==}
|
||||
'@typescript-eslint/utils@8.49.0':
|
||||
resolution: {integrity: sha512-N3W7rJw7Rw+z1tRsHZbK395TWSYvufBXumYtEGzypgMUthlg0/hmCImeA8hgO2d2G4pd7ftpxxul2J8OdtdaFA==}
|
||||
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
|
||||
peerDependencies:
|
||||
eslint: ^8.57.0 || ^9.0.0
|
||||
@@ -1256,8 +1256,8 @@ packages:
|
||||
resolution: {integrity: sha512-/++5CYLQqsO9HFGLI7APrxBJYo+5OCMpViuhV8q5/Qa3o5mMrF//eQHks+PXcsAVaLdn817fMuS7zqoXNNZGaw==}
|
||||
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
|
||||
|
||||
'@typescript-eslint/visitor-keys@8.48.1':
|
||||
resolution: {integrity: sha512-BmxxndzEWhE4TIEEMBs8lP3MBWN3jFPs/p6gPm/wkv02o41hI6cq9AuSmGAaTTHPtA1FTi2jBre4A9rm5ZmX+Q==}
|
||||
'@typescript-eslint/visitor-keys@8.49.0':
|
||||
resolution: {integrity: sha512-LlKaciDe3GmZFphXIc79THF/YYBugZ7FS1pO581E/edlVVNbZKDy93evqmrfQ9/Y4uN0vVhX4iuchq26mK/iiA==}
|
||||
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
|
||||
|
||||
'@videojs/http-streaming@3.17.2':
|
||||
@@ -1287,14 +1287,14 @@ packages:
|
||||
vite: ^5.0.0 || ^6.0.0 || ^7.0.0
|
||||
vue: ^3.2.25
|
||||
|
||||
'@volar/language-core@2.4.23':
|
||||
resolution: {integrity: sha512-hEEd5ET/oSmBC6pi1j6NaNYRWoAiDhINbT8rmwtINugR39loROSlufGdYMF9TaKGfz+ViGs1Idi3mAhnuPcoGQ==}
|
||||
'@volar/language-core@2.4.26':
|
||||
resolution: {integrity: sha512-hH0SMitMxnB43OZpyF1IFPS9bgb2I3bpCh76m2WEK7BE0A0EzpYsRp0CCH2xNKshr7kacU5TQBLYn4zj7CG60A==}
|
||||
|
||||
'@volar/source-map@2.4.23':
|
||||
resolution: {integrity: sha512-Z1Uc8IB57Lm6k7q6KIDu/p+JWtf3xsXJqAX/5r18hYOTpJyBn0KXUR8oTJ4WFYOcDzWC9n3IflGgHowx6U6z9Q==}
|
||||
'@volar/source-map@2.4.26':
|
||||
resolution: {integrity: sha512-JJw0Tt/kSFsIRmgTQF4JSt81AUSI1aEye5Zl65EeZ8H35JHnTvFGmpDOBn5iOxd48fyGE+ZvZBp5FcgAy/1Qhw==}
|
||||
|
||||
'@volar/typescript@2.4.23':
|
||||
resolution: {integrity: sha512-lAB5zJghWxVPqfcStmAP1ZqQacMpe90UrP5RJ3arDyrhy4aCUQqmxPPLB2PWDKugvylmO41ljK7vZ+t6INMTag==}
|
||||
'@volar/typescript@2.4.26':
|
||||
resolution: {integrity: sha512-N87ecLD48Sp6zV9zID/5yuS1+5foj0DfuYGdQ6KHj/IbKvyKv1zNX6VCmnKYwtmHadEO6mFc2EKISiu3RDPAvA==}
|
||||
|
||||
'@vue/compiler-core@3.5.25':
|
||||
resolution: {integrity: sha512-vay5/oQJdsNHmliWoZfHPoVZZRmnSWhug0BYT34njkYTPqClh3DNWLkZNJBVSjsNMrg0CCrBfoKkjZQPM/QVUw==}
|
||||
@@ -1337,8 +1337,8 @@ packages:
|
||||
typescript:
|
||||
optional: true
|
||||
|
||||
'@vue/language-core@3.1.5':
|
||||
resolution: {integrity: sha512-FMcqyzWN+sYBeqRMWPGT2QY0mUasZMVIuHvmb5NT3eeqPrbHBYtCP8JWEUCDCgM+Zr62uuWY/qoeBrPrzfa78w==}
|
||||
'@vue/language-core@3.1.8':
|
||||
resolution: {integrity: sha512-PfwAW7BLopqaJbneChNL6cUOTL3GL+0l8paYP5shhgY5toBNidWnMXWM+qDwL7MC9+zDtzCF2enT8r6VPu64iw==}
|
||||
peerDependencies:
|
||||
typescript: '*'
|
||||
peerDependenciesMeta:
|
||||
@@ -1456,8 +1456,8 @@ packages:
|
||||
ajv@6.12.6:
|
||||
resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==}
|
||||
|
||||
alien-signals@3.1.0:
|
||||
resolution: {integrity: sha512-yufC6VpSy8tK3I0lO67pjumo5JvDQVQyr38+3OHqe6CHl1t2VZekKZ7EKKZSqk0cRmE7U7tfZbpXiKNzuc+ckg==}
|
||||
alien-signals@3.1.1:
|
||||
resolution: {integrity: sha512-ogkIWbVrLwKtHY6oOAXaYkAxP+cTH7V5FZ5+Tm4NZFd8VDZ6uNMDrfzqctTZ42eTMCSR3ne3otpcxmqSnFfPYA==}
|
||||
|
||||
ansi-styles@4.3.0:
|
||||
resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==}
|
||||
@@ -1606,8 +1606,8 @@ packages:
|
||||
dom-walk@0.1.2:
|
||||
resolution: {integrity: sha512-6QvTW9mrGeIegrFXdtQi9pk7O/nSK6lSdXW2eqUspN5LWD7UTji2Fqw5V2YLjBpHEoU9Xl/eUWNpDeZvoyOv2w==}
|
||||
|
||||
dompurify@3.3.0:
|
||||
resolution: {integrity: sha512-r+f6MYR1gGN1eJv0TVQbhA7if/U7P87cdPl3HN5rikqaBSBxLiCb/b9O+2eG0cxz0ghyU+mU1QkbsOwERMYlWQ==}
|
||||
dompurify@3.3.1:
|
||||
resolution: {integrity: sha512-qkdCKzLNtrgPFP1Vo+98FRzJnBRGe4ffyCea9IwHB1fyxPOeNTHpLKYGd4Uk9xvNoH0ZoOjwZxNptyMwqrId1Q==}
|
||||
|
||||
electron-to-chromium@1.5.250:
|
||||
resolution: {integrity: sha512-/5UMj9IiGDMOFBnN4i7/Ry5onJrAGSbOGo3s9FEKmwobGq6xw832ccET0CE3CkkMBZ8GJSlUIesZofpyurqDXw==}
|
||||
@@ -2436,11 +2436,11 @@ packages:
|
||||
videojs-vtt.js@0.15.5:
|
||||
resolution: {integrity: sha512-yZbBxvA7QMYn15Lr/ZfhhLPrNpI/RmCSCqgIff57GC2gIrV5YfyzLfLyZMj0NnZSAz8syB4N0nHXpZg9MyrMOQ==}
|
||||
|
||||
vite-plugin-compression2@2.3.1:
|
||||
resolution: {integrity: sha512-bnhLTsurtvOiiP6EMISIKVsOMCeTAjE6FJbyqQus3W4mtAxF7pCuC4puUIAiCgNs98tOCpqo6GIXJXTLufzIaw==}
|
||||
vite-plugin-compression2@2.4.0:
|
||||
resolution: {integrity: sha512-8J4CBF1+dM1I06azba/eXJuJHinLF0Am7lUvRH8AZpu0otJoBaDEnxrIEr5iPZJSwH0AEglJGYCveh7pN52jCg==}
|
||||
|
||||
vite@7.2.6:
|
||||
resolution: {integrity: sha512-tI2l/nFHC5rLh7+5+o7QjKjSR04ivXDF4jcgV0f/bTQ+OJiITy5S6gaynVsEM+7RqzufMnVbIon6Sr5x1SDYaQ==}
|
||||
vite@7.2.7:
|
||||
resolution: {integrity: sha512-ITcnkFeR3+fI8P1wMgItjGrR10170d8auB4EpMLPqmx6uxElH3a/hHGQabSHKdqd4FXWO1nFIp9rRn7JQ34ACQ==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
hasBin: true
|
||||
peerDependencies:
|
||||
@@ -2518,8 +2518,8 @@ packages:
|
||||
peerDependencies:
|
||||
vue: ^3.0.2
|
||||
|
||||
vue-tsc@3.1.5:
|
||||
resolution: {integrity: sha512-L/G9IUjOWhBU0yun89rv8fKqmKC+T0HfhrFjlIml71WpfBv9eb4E9Bev8FMbyueBIU9vxQqbd+oOsVcDa5amGw==}
|
||||
vue-tsc@3.1.8:
|
||||
resolution: {integrity: sha512-deKgwx6exIHeZwF601P1ktZKNF0bepaSN4jBU3AsbldPx9gylUc1JDxYppl82yxgkAgaz0Y0LCLOi+cXe9HMYA==}
|
||||
hasBin: true
|
||||
peerDependencies:
|
||||
typescript: '>=5.0.0'
|
||||
@@ -3550,7 +3550,7 @@ snapshots:
|
||||
|
||||
'@types/lodash@4.17.13': {}
|
||||
|
||||
'@types/node@24.10.1':
|
||||
'@types/node@24.10.2':
|
||||
dependencies:
|
||||
undici-types: 7.16.0
|
||||
|
||||
@@ -3576,16 +3576,15 @@ snapshots:
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
'@typescript-eslint/eslint-plugin@8.48.1(@typescript-eslint/parser@8.37.0(eslint@9.39.1)(typescript@5.9.3))(eslint@9.39.1)(typescript@5.9.3)':
|
||||
'@typescript-eslint/eslint-plugin@8.49.0(@typescript-eslint/parser@8.37.0(eslint@9.39.1)(typescript@5.9.3))(eslint@9.39.1)(typescript@5.9.3)':
|
||||
dependencies:
|
||||
'@eslint-community/regexpp': 4.12.2
|
||||
'@typescript-eslint/parser': 8.37.0(eslint@9.39.1)(typescript@5.9.3)
|
||||
'@typescript-eslint/scope-manager': 8.48.1
|
||||
'@typescript-eslint/type-utils': 8.48.1(eslint@9.39.1)(typescript@5.9.3)
|
||||
'@typescript-eslint/utils': 8.48.1(eslint@9.39.1)(typescript@5.9.3)
|
||||
'@typescript-eslint/visitor-keys': 8.48.1
|
||||
'@typescript-eslint/scope-manager': 8.49.0
|
||||
'@typescript-eslint/type-utils': 8.49.0(eslint@9.39.1)(typescript@5.9.3)
|
||||
'@typescript-eslint/utils': 8.49.0(eslint@9.39.1)(typescript@5.9.3)
|
||||
'@typescript-eslint/visitor-keys': 8.49.0
|
||||
eslint: 9.39.1
|
||||
graphemer: 1.4.0
|
||||
ignore: 7.0.5
|
||||
natural-compare: 1.4.0
|
||||
ts-api-utils: 2.1.0(typescript@5.9.3)
|
||||
@@ -3623,10 +3622,10 @@ snapshots:
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
'@typescript-eslint/project-service@8.48.1(typescript@5.9.3)':
|
||||
'@typescript-eslint/project-service@8.49.0(typescript@5.9.3)':
|
||||
dependencies:
|
||||
'@typescript-eslint/tsconfig-utils': 8.48.1(typescript@5.9.3)
|
||||
'@typescript-eslint/types': 8.48.1
|
||||
'@typescript-eslint/tsconfig-utils': 8.49.0(typescript@5.9.3)
|
||||
'@typescript-eslint/types': 8.49.0
|
||||
debug: 4.4.3
|
||||
typescript: 5.9.3
|
||||
transitivePeerDependencies:
|
||||
@@ -3642,10 +3641,10 @@ snapshots:
|
||||
'@typescript-eslint/types': 8.46.4
|
||||
'@typescript-eslint/visitor-keys': 8.46.4
|
||||
|
||||
'@typescript-eslint/scope-manager@8.48.1':
|
||||
'@typescript-eslint/scope-manager@8.49.0':
|
||||
dependencies:
|
||||
'@typescript-eslint/types': 8.48.1
|
||||
'@typescript-eslint/visitor-keys': 8.48.1
|
||||
'@typescript-eslint/types': 8.49.0
|
||||
'@typescript-eslint/visitor-keys': 8.49.0
|
||||
|
||||
'@typescript-eslint/tsconfig-utils@8.37.0(typescript@5.9.3)':
|
||||
dependencies:
|
||||
@@ -3655,7 +3654,7 @@ snapshots:
|
||||
dependencies:
|
||||
typescript: 5.9.3
|
||||
|
||||
'@typescript-eslint/tsconfig-utils@8.48.1(typescript@5.9.3)':
|
||||
'@typescript-eslint/tsconfig-utils@8.49.0(typescript@5.9.3)':
|
||||
dependencies:
|
||||
typescript: 5.9.3
|
||||
|
||||
@@ -3671,11 +3670,11 @@ snapshots:
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
'@typescript-eslint/type-utils@8.48.1(eslint@9.39.1)(typescript@5.9.3)':
|
||||
'@typescript-eslint/type-utils@8.49.0(eslint@9.39.1)(typescript@5.9.3)':
|
||||
dependencies:
|
||||
'@typescript-eslint/types': 8.48.1
|
||||
'@typescript-eslint/typescript-estree': 8.48.1(typescript@5.9.3)
|
||||
'@typescript-eslint/utils': 8.48.1(eslint@9.39.1)(typescript@5.9.3)
|
||||
'@typescript-eslint/types': 8.49.0
|
||||
'@typescript-eslint/typescript-estree': 8.49.0(typescript@5.9.3)
|
||||
'@typescript-eslint/utils': 8.49.0(eslint@9.39.1)(typescript@5.9.3)
|
||||
debug: 4.4.3
|
||||
eslint: 9.39.1
|
||||
ts-api-utils: 2.1.0(typescript@5.9.3)
|
||||
@@ -3687,7 +3686,7 @@ snapshots:
|
||||
|
||||
'@typescript-eslint/types@8.46.4': {}
|
||||
|
||||
'@typescript-eslint/types@8.48.1': {}
|
||||
'@typescript-eslint/types@8.49.0': {}
|
||||
|
||||
'@typescript-eslint/typescript-estree@8.37.0(typescript@5.9.3)':
|
||||
dependencies:
|
||||
@@ -3721,12 +3720,12 @@ snapshots:
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
'@typescript-eslint/typescript-estree@8.48.1(typescript@5.9.3)':
|
||||
'@typescript-eslint/typescript-estree@8.49.0(typescript@5.9.3)':
|
||||
dependencies:
|
||||
'@typescript-eslint/project-service': 8.48.1(typescript@5.9.3)
|
||||
'@typescript-eslint/tsconfig-utils': 8.48.1(typescript@5.9.3)
|
||||
'@typescript-eslint/types': 8.48.1
|
||||
'@typescript-eslint/visitor-keys': 8.48.1
|
||||
'@typescript-eslint/project-service': 8.49.0(typescript@5.9.3)
|
||||
'@typescript-eslint/tsconfig-utils': 8.49.0(typescript@5.9.3)
|
||||
'@typescript-eslint/types': 8.49.0
|
||||
'@typescript-eslint/visitor-keys': 8.49.0
|
||||
debug: 4.4.3
|
||||
minimatch: 9.0.5
|
||||
semver: 7.7.3
|
||||
@@ -3747,12 +3746,12 @@ snapshots:
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
'@typescript-eslint/utils@8.48.1(eslint@9.39.1)(typescript@5.9.3)':
|
||||
'@typescript-eslint/utils@8.49.0(eslint@9.39.1)(typescript@5.9.3)':
|
||||
dependencies:
|
||||
'@eslint-community/eslint-utils': 4.9.0(eslint@9.39.1)
|
||||
'@typescript-eslint/scope-manager': 8.48.1
|
||||
'@typescript-eslint/types': 8.48.1
|
||||
'@typescript-eslint/typescript-estree': 8.48.1(typescript@5.9.3)
|
||||
'@typescript-eslint/scope-manager': 8.49.0
|
||||
'@typescript-eslint/types': 8.49.0
|
||||
'@typescript-eslint/typescript-estree': 8.49.0(typescript@5.9.3)
|
||||
eslint: 9.39.1
|
||||
typescript: 5.9.3
|
||||
transitivePeerDependencies:
|
||||
@@ -3768,9 +3767,9 @@ snapshots:
|
||||
'@typescript-eslint/types': 8.46.4
|
||||
eslint-visitor-keys: 4.2.1
|
||||
|
||||
'@typescript-eslint/visitor-keys@8.48.1':
|
||||
'@typescript-eslint/visitor-keys@8.49.0':
|
||||
dependencies:
|
||||
'@typescript-eslint/types': 8.48.1
|
||||
'@typescript-eslint/types': 8.49.0
|
||||
eslint-visitor-keys: 4.2.1
|
||||
|
||||
'@videojs/http-streaming@3.17.2(video.js@8.23.4)':
|
||||
@@ -3795,7 +3794,7 @@ snapshots:
|
||||
global: 4.4.0
|
||||
is-function: 1.0.2
|
||||
|
||||
'@vitejs/plugin-legacy@7.2.1(terser@5.44.1)(vite@7.2.6(@types/node@24.10.1)(terser@5.44.1)(yaml@2.7.0))':
|
||||
'@vitejs/plugin-legacy@7.2.1(terser@5.44.1)(vite@7.2.7(@types/node@24.10.2)(terser@5.44.1)(yaml@2.7.0))':
|
||||
dependencies:
|
||||
'@babel/core': 7.28.5
|
||||
'@babel/plugin-transform-dynamic-import': 7.27.1(@babel/core@7.28.5)
|
||||
@@ -3810,25 +3809,25 @@ snapshots:
|
||||
regenerator-runtime: 0.14.1
|
||||
systemjs: 6.15.1
|
||||
terser: 5.44.1
|
||||
vite: 7.2.6(@types/node@24.10.1)(terser@5.44.1)(yaml@2.7.0)
|
||||
vite: 7.2.7(@types/node@24.10.2)(terser@5.44.1)(yaml@2.7.0)
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
'@vitejs/plugin-vue@6.0.2(vite@7.2.6(@types/node@24.10.1)(terser@5.44.1)(yaml@2.7.0))(vue@3.5.25(typescript@5.9.3))':
|
||||
'@vitejs/plugin-vue@6.0.2(vite@7.2.7(@types/node@24.10.2)(terser@5.44.1)(yaml@2.7.0))(vue@3.5.25(typescript@5.9.3))':
|
||||
dependencies:
|
||||
'@rolldown/pluginutils': 1.0.0-beta.50
|
||||
vite: 7.2.6(@types/node@24.10.1)(terser@5.44.1)(yaml@2.7.0)
|
||||
vite: 7.2.7(@types/node@24.10.2)(terser@5.44.1)(yaml@2.7.0)
|
||||
vue: 3.5.25(typescript@5.9.3)
|
||||
|
||||
'@volar/language-core@2.4.23':
|
||||
'@volar/language-core@2.4.26':
|
||||
dependencies:
|
||||
'@volar/source-map': 2.4.23
|
||||
'@volar/source-map': 2.4.26
|
||||
|
||||
'@volar/source-map@2.4.23': {}
|
||||
'@volar/source-map@2.4.26': {}
|
||||
|
||||
'@volar/typescript@2.4.23':
|
||||
'@volar/typescript@2.4.26':
|
||||
dependencies:
|
||||
'@volar/language-core': 2.4.23
|
||||
'@volar/language-core': 2.4.26
|
||||
path-browserify: 1.0.1
|
||||
vscode-uri: 3.1.0
|
||||
|
||||
@@ -3904,12 +3903,12 @@ snapshots:
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
'@vue/language-core@3.1.5(typescript@5.9.3)':
|
||||
'@vue/language-core@3.1.8(typescript@5.9.3)':
|
||||
dependencies:
|
||||
'@volar/language-core': 2.4.23
|
||||
'@volar/language-core': 2.4.26
|
||||
'@vue/compiler-dom': 3.5.25
|
||||
'@vue/shared': 3.5.25
|
||||
alien-signals: 3.1.0
|
||||
alien-signals: 3.1.1
|
||||
muggle-string: 0.4.1
|
||||
path-browserify: 1.0.1
|
||||
picomatch: 4.0.3
|
||||
@@ -3993,7 +3992,7 @@ snapshots:
|
||||
json-schema-traverse: 0.4.1
|
||||
uri-js: 4.4.1
|
||||
|
||||
alien-signals@3.1.0: {}
|
||||
alien-signals@3.1.1: {}
|
||||
|
||||
ansi-styles@4.3.0:
|
||||
dependencies:
|
||||
@@ -4136,7 +4135,7 @@ snapshots:
|
||||
|
||||
dom-walk@0.1.2: {}
|
||||
|
||||
dompurify@3.3.0:
|
||||
dompurify@3.3.1:
|
||||
optionalDependencies:
|
||||
'@types/trusted-types': 2.0.7
|
||||
|
||||
@@ -4978,14 +4977,14 @@ snapshots:
|
||||
dependencies:
|
||||
global: 4.4.0
|
||||
|
||||
vite-plugin-compression2@2.3.1(rollup@4.53.3):
|
||||
vite-plugin-compression2@2.4.0(rollup@4.53.3):
|
||||
dependencies:
|
||||
'@rollup/pluginutils': 5.3.0(rollup@4.53.3)
|
||||
tar-mini: 0.2.0
|
||||
transitivePeerDependencies:
|
||||
- rollup
|
||||
|
||||
vite@7.2.6(@types/node@24.10.1)(terser@5.44.1)(yaml@2.7.0):
|
||||
vite@7.2.7(@types/node@24.10.2)(terser@5.44.1)(yaml@2.7.0):
|
||||
dependencies:
|
||||
esbuild: 0.25.12
|
||||
fdir: 6.5.0(picomatch@4.0.3)
|
||||
@@ -4994,7 +4993,7 @@ snapshots:
|
||||
rollup: 4.53.3
|
||||
tinyglobby: 0.2.15
|
||||
optionalDependencies:
|
||||
'@types/node': 24.10.1
|
||||
'@types/node': 24.10.2
|
||||
fsevents: 2.3.3
|
||||
terser: 5.44.1
|
||||
yaml: 2.7.0
|
||||
@@ -5042,10 +5041,10 @@ snapshots:
|
||||
dependencies:
|
||||
vue: 3.5.25(typescript@5.9.3)
|
||||
|
||||
vue-tsc@3.1.5(typescript@5.9.3):
|
||||
vue-tsc@3.1.8(typescript@5.9.3):
|
||||
dependencies:
|
||||
'@volar/typescript': 2.4.23
|
||||
'@vue/language-core': 3.1.5(typescript@5.9.3)
|
||||
'@volar/typescript': 2.4.26
|
||||
'@vue/language-core': 3.1.8(typescript@5.9.3)
|
||||
typescript: 5.9.3
|
||||
|
||||
vue@3.5.25(typescript@5.9.3):
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, computed, watch, nextTick, defineProps } from "vue";
|
||||
import { ref, computed, watch, nextTick } from "vue";
|
||||
import { useRoute } from "vue-router";
|
||||
import { useFileStore } from "@/stores/file";
|
||||
import url from "@/utils/url";
|
||||
|
||||
@@ -44,7 +44,9 @@
|
||||
"openFile": "فتح الملف",
|
||||
"discardChanges": "إلغاء التغييرات",
|
||||
"saveChanges": "Save changes",
|
||||
"editAsText": "Edit as Text"
|
||||
"editAsText": "Edit as Text",
|
||||
"increaseFontSize": "Increase font size",
|
||||
"decreaseFontSize": "Decrease font size"
|
||||
},
|
||||
"download": {
|
||||
"downloadFile": "تحميل الملف",
|
||||
@@ -78,7 +80,14 @@
|
||||
"sortBySize": "الترتيب بالحجم",
|
||||
"noPreview": "لا يوجد عرض مسبق لهذا الملف.",
|
||||
"csvTooLarge": "CSV file is too large for preview (>5MB). Please download to view.",
|
||||
"csvLoadFailed": "Failed to load CSV file."
|
||||
"csvLoadFailed": "Failed to load CSV file.",
|
||||
"showingRows": "Showing {count} row(s)",
|
||||
"columnSeparator": "Column Separator",
|
||||
"csvSeparators": {
|
||||
"comma": "Comma (,)",
|
||||
"semicolon": "Semicolon (;)",
|
||||
"both": "Both (,) and (;)"
|
||||
}
|
||||
},
|
||||
"help": {
|
||||
"click": "حدد الملف أو المجلد",
|
||||
@@ -272,10 +281,5 @@
|
||||
"minutes": "دقائق",
|
||||
"seconds": "ثواني",
|
||||
"unit": "وحدة الوقت"
|
||||
},
|
||||
"available_csv_separators": {
|
||||
"comma": "Comma (,)",
|
||||
"semicolon": "Semicolon (;)",
|
||||
"both": "Both (,) and (;)"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -44,7 +44,9 @@
|
||||
"openFile": "Отвори файл",
|
||||
"discardChanges": "Изчисти",
|
||||
"saveChanges": "Запиши промените",
|
||||
"editAsText": "Edit as Text"
|
||||
"editAsText": "Edit as Text",
|
||||
"increaseFontSize": "Increase font size",
|
||||
"decreaseFontSize": "Decrease font size"
|
||||
},
|
||||
"download": {
|
||||
"downloadFile": "Свали файл",
|
||||
@@ -78,7 +80,14 @@
|
||||
"sortBySize": "Подредба по размер",
|
||||
"noPreview": "За този файл не е наличен преглед.",
|
||||
"csvTooLarge": "CSV file is too large for preview (>5MB). Please download to view.",
|
||||
"csvLoadFailed": "Failed to load CSV file."
|
||||
"csvLoadFailed": "Failed to load CSV file.",
|
||||
"showingRows": "Showing {count} row(s)",
|
||||
"columnSeparator": "Column Separator",
|
||||
"csvSeparators": {
|
||||
"comma": "Comma (,)",
|
||||
"semicolon": "Semicolon (;)",
|
||||
"both": "Both (,) and (;)"
|
||||
}
|
||||
},
|
||||
"help": {
|
||||
"click": "избери файл или директория",
|
||||
@@ -272,10 +281,5 @@
|
||||
"minutes": "Минути",
|
||||
"seconds": "Секунди",
|
||||
"unit": "Единица за време"
|
||||
},
|
||||
"available_csv_separators": {
|
||||
"comma": "Comma (,)",
|
||||
"semicolon": "Semicolon (;)",
|
||||
"both": "Both (,) and (;)"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -44,7 +44,9 @@
|
||||
"openFile": "Obrir fitxer",
|
||||
"discardChanges": "Descartar",
|
||||
"saveChanges": "Save changes",
|
||||
"editAsText": "Edit as Text"
|
||||
"editAsText": "Edit as Text",
|
||||
"increaseFontSize": "Increase font size",
|
||||
"decreaseFontSize": "Decrease font size"
|
||||
},
|
||||
"download": {
|
||||
"downloadFile": "Descarregar fitxer",
|
||||
@@ -78,7 +80,14 @@
|
||||
"sortBySize": "Ordenar per mida",
|
||||
"noPreview": "La vista prèvia no està disponible per a aquest fitxer.",
|
||||
"csvTooLarge": "CSV file is too large for preview (>5MB). Please download to view.",
|
||||
"csvLoadFailed": "Failed to load CSV file."
|
||||
"csvLoadFailed": "Failed to load CSV file.",
|
||||
"showingRows": "Showing {count} row(s)",
|
||||
"columnSeparator": "Column Separator",
|
||||
"csvSeparators": {
|
||||
"comma": "Comma (,)",
|
||||
"semicolon": "Semicolon (;)",
|
||||
"both": "Both (,) and (;)"
|
||||
}
|
||||
},
|
||||
"help": {
|
||||
"click": "seleccionar fitxer o carpeta",
|
||||
@@ -272,10 +281,5 @@
|
||||
"minutes": "Minuts",
|
||||
"seconds": "Segons",
|
||||
"unit": "Unitat"
|
||||
},
|
||||
"available_csv_separators": {
|
||||
"comma": "Comma (,)",
|
||||
"semicolon": "Semicolon (;)",
|
||||
"both": "Both (,) and (;)"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -44,7 +44,9 @@
|
||||
"openFile": "Otevřít soubor",
|
||||
"discardChanges": "Zrušit změny",
|
||||
"saveChanges": "Save changes",
|
||||
"editAsText": "Edit as Text"
|
||||
"editAsText": "Edit as Text",
|
||||
"increaseFontSize": "Increase font size",
|
||||
"decreaseFontSize": "Decrease font size"
|
||||
},
|
||||
"download": {
|
||||
"downloadFile": "Stáhnout soubor",
|
||||
@@ -78,7 +80,14 @@
|
||||
"sortBySize": "Seřadit podle velikosti",
|
||||
"noPreview": "Náhled pro tento soubor není k dispozici.",
|
||||
"csvTooLarge": "CSV file is too large for preview (>5MB). Please download to view.",
|
||||
"csvLoadFailed": "Failed to load CSV file."
|
||||
"csvLoadFailed": "Failed to load CSV file.",
|
||||
"showingRows": "Showing {count} row(s)",
|
||||
"columnSeparator": "Column Separator",
|
||||
"csvSeparators": {
|
||||
"comma": "Comma (,)",
|
||||
"semicolon": "Semicolon (;)",
|
||||
"both": "Both (,) and (;)"
|
||||
}
|
||||
},
|
||||
"help": {
|
||||
"click": "vyberte soubor nebo adresář",
|
||||
@@ -272,10 +281,5 @@
|
||||
"minutes": "Minuty",
|
||||
"seconds": "Sekundy",
|
||||
"unit": "Časová jednotka"
|
||||
},
|
||||
"available_csv_separators": {
|
||||
"comma": "Comma (,)",
|
||||
"semicolon": "Semicolon (;)",
|
||||
"both": "Both (,) and (;)"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -44,7 +44,9 @@
|
||||
"openFile": "Datei öffnen",
|
||||
"discardChanges": "Verwerfen",
|
||||
"saveChanges": "Änderungen speichern",
|
||||
"editAsText": "Als Text bearbeiten"
|
||||
"editAsText": "Als Text bearbeiten",
|
||||
"increaseFontSize": "Increase font size",
|
||||
"decreaseFontSize": "Decrease font size"
|
||||
},
|
||||
"download": {
|
||||
"downloadFile": "Download Datei",
|
||||
@@ -78,7 +80,14 @@
|
||||
"sortBySize": "Nach Größe sortieren",
|
||||
"noPreview": "Für diese Datei ist keine Vorschau verfügbar.",
|
||||
"csvTooLarge": "Die CSV-Datei ist zu groß für die Vorschau (>5 MB). Bitte herunterladen, um sie anzuzeigen.",
|
||||
"csvLoadFailed": "Fehler beim Laden der CSV-Datei."
|
||||
"csvLoadFailed": "Fehler beim Laden der CSV-Datei.",
|
||||
"showingRows": "Showing {count} row(s)",
|
||||
"columnSeparator": "Column Separator",
|
||||
"csvSeparators": {
|
||||
"comma": "Comma (,)",
|
||||
"semicolon": "Semicolon (;)",
|
||||
"both": "Both (,) and (;)"
|
||||
}
|
||||
},
|
||||
"help": {
|
||||
"click": "Wähle Datei oder Ordner",
|
||||
@@ -272,10 +281,5 @@
|
||||
"minutes": "Minuten",
|
||||
"seconds": "Sekunden",
|
||||
"unit": "Zeiteinheit"
|
||||
},
|
||||
"available_csv_separators": {
|
||||
"comma": "Comma (,)",
|
||||
"semicolon": "Semicolon (;)",
|
||||
"both": "Both (,) and (;)"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -44,7 +44,9 @@
|
||||
"openFile": "Άνοιγμα αρχείου",
|
||||
"discardChanges": "Discard",
|
||||
"saveChanges": "Save changes",
|
||||
"editAsText": "Edit as Text"
|
||||
"editAsText": "Edit as Text",
|
||||
"increaseFontSize": "Increase font size",
|
||||
"decreaseFontSize": "Decrease font size"
|
||||
},
|
||||
"download": {
|
||||
"downloadFile": "Λήψη αρχείου",
|
||||
@@ -78,7 +80,14 @@
|
||||
"sortBySize": "Ταξινόμηση κατά μέγεθος",
|
||||
"noPreview": "Η προεπισκόπηση δεν είναι διαθέσιμη για αυτό το αρχείο.",
|
||||
"csvTooLarge": "CSV file is too large for preview (>5MB). Please download to view.",
|
||||
"csvLoadFailed": "Failed to load CSV file."
|
||||
"csvLoadFailed": "Failed to load CSV file.",
|
||||
"showingRows": "Showing {count} row(s)",
|
||||
"columnSeparator": "Column Separator",
|
||||
"csvSeparators": {
|
||||
"comma": "Comma (,)",
|
||||
"semicolon": "Semicolon (;)",
|
||||
"both": "Both (,) and (;)"
|
||||
}
|
||||
},
|
||||
"help": {
|
||||
"click": "επιλέξτε αρχείο ή φάκελο",
|
||||
@@ -272,10 +281,5 @@
|
||||
"minutes": "Λεπτά",
|
||||
"seconds": "Δευτερόλεπτα",
|
||||
"unit": "Μονάδα χρόνου"
|
||||
},
|
||||
"available_csv_separators": {
|
||||
"comma": "Comma (,)",
|
||||
"semicolon": "Semicolon (;)",
|
||||
"both": "Both (,) and (;)"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -44,7 +44,9 @@
|
||||
"openFile": "Abrir archivo",
|
||||
"discardChanges": "Discard",
|
||||
"saveChanges": "Guardar cambios",
|
||||
"editAsText": "Edit as Text"
|
||||
"editAsText": "Edit as Text",
|
||||
"increaseFontSize": "Increase font size",
|
||||
"decreaseFontSize": "Decrease font size"
|
||||
},
|
||||
"download": {
|
||||
"downloadFile": "Descargar fichero",
|
||||
@@ -78,7 +80,14 @@
|
||||
"sortBySize": "Ordenar por tamaño",
|
||||
"noPreview": "La vista previa no está disponible para este archivo.",
|
||||
"csvTooLarge": "CSV file is too large for preview (>5MB). Please download to view.",
|
||||
"csvLoadFailed": "Failed to load CSV file."
|
||||
"csvLoadFailed": "Failed to load CSV file.",
|
||||
"showingRows": "Showing {count} row(s)",
|
||||
"columnSeparator": "Column Separator",
|
||||
"csvSeparators": {
|
||||
"comma": "Comma (,)",
|
||||
"semicolon": "Semicolon (;)",
|
||||
"both": "Both (,) and (;)"
|
||||
}
|
||||
},
|
||||
"help": {
|
||||
"click": "seleccionar archivo o carpeta",
|
||||
@@ -272,10 +281,5 @@
|
||||
"minutes": "Minutos",
|
||||
"seconds": "Segundos",
|
||||
"unit": "Unidad"
|
||||
},
|
||||
"available_csv_separators": {
|
||||
"comma": "Comma (,)",
|
||||
"semicolon": "Semicolon (;)",
|
||||
"both": "Both (,) and (;)"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -44,7 +44,9 @@
|
||||
"openFile": "باز کردن فایل",
|
||||
"discardChanges": "لغو کردن",
|
||||
"saveChanges": "Save changes",
|
||||
"editAsText": "Edit as Text"
|
||||
"editAsText": "Edit as Text",
|
||||
"increaseFontSize": "Increase font size",
|
||||
"decreaseFontSize": "Decrease font size"
|
||||
},
|
||||
"download": {
|
||||
"downloadFile": "دانلود فایل",
|
||||
@@ -78,7 +80,14 @@
|
||||
"sortBySize": "مرتب سازی اندازه",
|
||||
"noPreview": "این فایل قابل نمایش نیست",
|
||||
"csvTooLarge": "CSV file is too large for preview (>5MB). Please download to view.",
|
||||
"csvLoadFailed": "Failed to load CSV file."
|
||||
"csvLoadFailed": "Failed to load CSV file.",
|
||||
"showingRows": "Showing {count} row(s)",
|
||||
"columnSeparator": "Column Separator",
|
||||
"csvSeparators": {
|
||||
"comma": "Comma (,)",
|
||||
"semicolon": "Semicolon (;)",
|
||||
"both": "Both (,) and (;)"
|
||||
}
|
||||
},
|
||||
"help": {
|
||||
"click": "انتخاب فایل یا پوشه",
|
||||
@@ -272,10 +281,5 @@
|
||||
"minutes": "دقیقه",
|
||||
"seconds": "ثانیه",
|
||||
"unit": "واحد زمان"
|
||||
},
|
||||
"available_csv_separators": {
|
||||
"comma": "Comma (,)",
|
||||
"semicolon": "Semicolon (;)",
|
||||
"both": "Both (,) and (;)"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -44,7 +44,9 @@
|
||||
"openFile": "Ouvrir le fichier",
|
||||
"discardChanges": "Annuler",
|
||||
"saveChanges": "Save changes",
|
||||
"editAsText": "Edit as Text"
|
||||
"editAsText": "Edit as Text",
|
||||
"increaseFontSize": "Increase font size",
|
||||
"decreaseFontSize": "Decrease font size"
|
||||
},
|
||||
"download": {
|
||||
"downloadFile": "Télécharger le fichier",
|
||||
@@ -78,7 +80,14 @@
|
||||
"sortBySize": "Trier par taille",
|
||||
"noPreview": "L'aperçu n'est pas disponible pour ce fichier.",
|
||||
"csvTooLarge": "CSV file is too large for preview (>5MB). Please download to view.",
|
||||
"csvLoadFailed": "Failed to load CSV file."
|
||||
"csvLoadFailed": "Failed to load CSV file.",
|
||||
"showingRows": "Showing {count} row(s)",
|
||||
"columnSeparator": "Column Separator",
|
||||
"csvSeparators": {
|
||||
"comma": "Comma (,)",
|
||||
"semicolon": "Semicolon (;)",
|
||||
"both": "Both (,) and (;)"
|
||||
}
|
||||
},
|
||||
"help": {
|
||||
"click": "Sélectionner un fichier ou dossier",
|
||||
@@ -272,10 +281,5 @@
|
||||
"minutes": "Minutes",
|
||||
"seconds": "Secondes",
|
||||
"unit": "Unité de temps"
|
||||
},
|
||||
"available_csv_separators": {
|
||||
"comma": "Comma (,)",
|
||||
"semicolon": "Semicolon (;)",
|
||||
"both": "Both (,) and (;)"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -44,7 +44,9 @@
|
||||
"openFile": "פתח קובץ",
|
||||
"discardChanges": "זריקת השינויים",
|
||||
"saveChanges": "Save changes",
|
||||
"editAsText": "Edit as Text"
|
||||
"editAsText": "Edit as Text",
|
||||
"increaseFontSize": "Increase font size",
|
||||
"decreaseFontSize": "Decrease font size"
|
||||
},
|
||||
"download": {
|
||||
"downloadFile": "הורד קובץ",
|
||||
@@ -78,7 +80,14 @@
|
||||
"sortBySize": "מיין לפי גודל",
|
||||
"noPreview": "לא זמינה תצוגה מקדימה לקובץ זה",
|
||||
"csvTooLarge": "CSV file is too large for preview (>5MB). Please download to view.",
|
||||
"csvLoadFailed": "Failed to load CSV file."
|
||||
"csvLoadFailed": "Failed to load CSV file.",
|
||||
"showingRows": "Showing {count} row(s)",
|
||||
"columnSeparator": "Column Separator",
|
||||
"csvSeparators": {
|
||||
"comma": "Comma (,)",
|
||||
"semicolon": "Semicolon (;)",
|
||||
"both": "Both (,) and (;)"
|
||||
}
|
||||
},
|
||||
"help": {
|
||||
"click": "בחר קובץ או תיקייה",
|
||||
@@ -272,10 +281,5 @@
|
||||
"minutes": "דקות",
|
||||
"seconds": "שניות",
|
||||
"unit": "יחידת זמן"
|
||||
},
|
||||
"available_csv_separators": {
|
||||
"comma": "Comma (,)",
|
||||
"semicolon": "Semicolon (;)",
|
||||
"both": "Both (,) and (;)"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -44,7 +44,9 @@
|
||||
"openFile": "Otvori datoteku",
|
||||
"discardChanges": "Odbaci",
|
||||
"saveChanges": "Spremi promjene",
|
||||
"editAsText": "Edit as Text"
|
||||
"editAsText": "Edit as Text",
|
||||
"increaseFontSize": "Increase font size",
|
||||
"decreaseFontSize": "Decrease font size"
|
||||
},
|
||||
"download": {
|
||||
"downloadFile": "Preuzmi Datoteku",
|
||||
@@ -78,7 +80,14 @@
|
||||
"sortBySize": "Sortiraj po veličini",
|
||||
"noPreview": "Pregled nije dostupan za ovu datoteku.",
|
||||
"csvTooLarge": "CSV file is too large for preview (>5MB). Please download to view.",
|
||||
"csvLoadFailed": "Failed to load CSV file."
|
||||
"csvLoadFailed": "Failed to load CSV file.",
|
||||
"showingRows": "Showing {count} row(s)",
|
||||
"columnSeparator": "Column Separator",
|
||||
"csvSeparators": {
|
||||
"comma": "Comma (,)",
|
||||
"semicolon": "Semicolon (;)",
|
||||
"both": "Both (,) and (;)"
|
||||
}
|
||||
},
|
||||
"help": {
|
||||
"click": "odaberi datoteku ili mapu",
|
||||
@@ -272,10 +281,5 @@
|
||||
"minutes": "Minute",
|
||||
"seconds": "Sekunde",
|
||||
"unit": "Jedinica vremena"
|
||||
},
|
||||
"available_csv_separators": {
|
||||
"comma": "Comma (,)",
|
||||
"semicolon": "Semicolon (;)",
|
||||
"both": "Both (,) and (;)"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -44,7 +44,9 @@
|
||||
"openFile": "Fájl megnyitása",
|
||||
"discardChanges": "Discard",
|
||||
"saveChanges": "Save changes",
|
||||
"editAsText": "Edit as Text"
|
||||
"editAsText": "Edit as Text",
|
||||
"increaseFontSize": "Increase font size",
|
||||
"decreaseFontSize": "Decrease font size"
|
||||
},
|
||||
"download": {
|
||||
"downloadFile": "Fájl letöltése",
|
||||
@@ -78,7 +80,14 @@
|
||||
"sortBySize": "Rendezés méret szerint",
|
||||
"noPreview": "Ehhez a fájlhoz nincs előnézet.",
|
||||
"csvTooLarge": "CSV file is too large for preview (>5MB). Please download to view.",
|
||||
"csvLoadFailed": "Failed to load CSV file."
|
||||
"csvLoadFailed": "Failed to load CSV file.",
|
||||
"showingRows": "Showing {count} row(s)",
|
||||
"columnSeparator": "Column Separator",
|
||||
"csvSeparators": {
|
||||
"comma": "Comma (,)",
|
||||
"semicolon": "Semicolon (;)",
|
||||
"both": "Both (,) and (;)"
|
||||
}
|
||||
},
|
||||
"help": {
|
||||
"click": "mappa vagy fájl kijelölése",
|
||||
@@ -272,10 +281,5 @@
|
||||
"minutes": "Perc",
|
||||
"seconds": "Másodperc",
|
||||
"unit": "Időegység"
|
||||
},
|
||||
"available_csv_separators": {
|
||||
"comma": "Comma (,)",
|
||||
"semicolon": "Semicolon (;)",
|
||||
"both": "Both (,) and (;)"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -44,7 +44,9 @@
|
||||
"openFile": "Open file",
|
||||
"discardChanges": "Discard",
|
||||
"saveChanges": "Save changes",
|
||||
"editAsText": "Edit as Text"
|
||||
"editAsText": "Edit as Text",
|
||||
"increaseFontSize": "Increase font size",
|
||||
"decreaseFontSize": "Decrease font size"
|
||||
},
|
||||
"download": {
|
||||
"downloadFile": "Sækja skjal",
|
||||
@@ -78,7 +80,14 @@
|
||||
"sortBySize": "Flokka eftir stærð",
|
||||
"noPreview": "Preview is not available for this file.",
|
||||
"csvTooLarge": "CSV file is too large for preview (>5MB). Please download to view.",
|
||||
"csvLoadFailed": "Failed to load CSV file."
|
||||
"csvLoadFailed": "Failed to load CSV file.",
|
||||
"showingRows": "Showing {count} row(s)",
|
||||
"columnSeparator": "Column Separator",
|
||||
"csvSeparators": {
|
||||
"comma": "Comma (,)",
|
||||
"semicolon": "Semicolon (;)",
|
||||
"both": "Both (,) and (;)"
|
||||
}
|
||||
},
|
||||
"help": {
|
||||
"click": "velja skjal eða möppu",
|
||||
@@ -272,10 +281,5 @@
|
||||
"minutes": "Mínútur",
|
||||
"seconds": "Sekúndur",
|
||||
"unit": "Tímastilling"
|
||||
},
|
||||
"available_csv_separators": {
|
||||
"comma": "Comma (,)",
|
||||
"semicolon": "Semicolon (;)",
|
||||
"both": "Both (,) and (;)"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -44,7 +44,9 @@
|
||||
"openFile": "Apri file",
|
||||
"discardChanges": "Ignora",
|
||||
"saveChanges": "Save changes",
|
||||
"editAsText": "Edit as Text"
|
||||
"editAsText": "Edit as Text",
|
||||
"increaseFontSize": "Increase font size",
|
||||
"decreaseFontSize": "Decrease font size"
|
||||
},
|
||||
"download": {
|
||||
"downloadFile": "Scarica file",
|
||||
@@ -78,7 +80,14 @@
|
||||
"sortBySize": "Ordina per dimensione",
|
||||
"noPreview": "L'anteprima non è disponibile per questo file.",
|
||||
"csvTooLarge": "CSV file is too large for preview (>5MB). Please download to view.",
|
||||
"csvLoadFailed": "Failed to load CSV file."
|
||||
"csvLoadFailed": "Failed to load CSV file.",
|
||||
"showingRows": "Showing {count} row(s)",
|
||||
"columnSeparator": "Column Separator",
|
||||
"csvSeparators": {
|
||||
"comma": "Comma (,)",
|
||||
"semicolon": "Semicolon (;)",
|
||||
"both": "Both (,) and (;)"
|
||||
}
|
||||
},
|
||||
"help": {
|
||||
"click": "seleziona un file o una cartella",
|
||||
@@ -272,10 +281,5 @@
|
||||
"minutes": "Minuti",
|
||||
"seconds": "Secondi",
|
||||
"unit": "Unità di tempo"
|
||||
},
|
||||
"available_csv_separators": {
|
||||
"comma": "Comma (,)",
|
||||
"semicolon": "Semicolon (;)",
|
||||
"both": "Both (,) and (;)"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -44,7 +44,9 @@
|
||||
"openFile": "ファイルを開く",
|
||||
"discardChanges": "Discard",
|
||||
"saveChanges": "Save changes",
|
||||
"editAsText": "Edit as Text"
|
||||
"editAsText": "Edit as Text",
|
||||
"increaseFontSize": "Increase font size",
|
||||
"decreaseFontSize": "Decrease font size"
|
||||
},
|
||||
"download": {
|
||||
"downloadFile": "ファイルのダウンロード",
|
||||
@@ -78,7 +80,14 @@
|
||||
"sortBySize": "サイズで並べ替え",
|
||||
"noPreview": "プレビューはこのファイルでは利用できません",
|
||||
"csvTooLarge": "CSV file is too large for preview (>5MB). Please download to view.",
|
||||
"csvLoadFailed": "Failed to load CSV file."
|
||||
"csvLoadFailed": "Failed to load CSV file.",
|
||||
"showingRows": "Showing {count} row(s)",
|
||||
"columnSeparator": "Column Separator",
|
||||
"csvSeparators": {
|
||||
"comma": "Comma (,)",
|
||||
"semicolon": "Semicolon (;)",
|
||||
"both": "Both (,) and (;)"
|
||||
}
|
||||
},
|
||||
"help": {
|
||||
"click": "ファイルやフォルダーを選択",
|
||||
@@ -272,10 +281,5 @@
|
||||
"minutes": "分",
|
||||
"seconds": "秒",
|
||||
"unit": "時間の単位"
|
||||
},
|
||||
"available_csv_separators": {
|
||||
"comma": "Comma (,)",
|
||||
"semicolon": "Semicolon (;)",
|
||||
"both": "Both (,) and (;)"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -44,7 +44,9 @@
|
||||
"openFile": "파일 열기",
|
||||
"discardChanges": "변경 사항 취소",
|
||||
"saveChanges": "변경사항 저장",
|
||||
"editAsText": "Edit as Text"
|
||||
"editAsText": "Edit as Text",
|
||||
"increaseFontSize": "Increase font size",
|
||||
"decreaseFontSize": "Decrease font size"
|
||||
},
|
||||
"download": {
|
||||
"downloadFile": "파일 다운로드",
|
||||
@@ -78,7 +80,14 @@
|
||||
"sortBySize": "크기순",
|
||||
"noPreview": "미리 보기가 지원되지 않는 파일 유형입니다.",
|
||||
"csvTooLarge": "CSV file is too large for preview (>5MB). Please download to view.",
|
||||
"csvLoadFailed": "Failed to load CSV file."
|
||||
"csvLoadFailed": "Failed to load CSV file.",
|
||||
"showingRows": "Showing {count} row(s)",
|
||||
"columnSeparator": "Column Separator",
|
||||
"csvSeparators": {
|
||||
"comma": "Comma (,)",
|
||||
"semicolon": "Semicolon (;)",
|
||||
"both": "Both (,) and (;)"
|
||||
}
|
||||
},
|
||||
"help": {
|
||||
"click": "파일이나 디렉토리를 선택해주세요.",
|
||||
@@ -272,10 +281,5 @@
|
||||
"minutes": "분",
|
||||
"seconds": "초",
|
||||
"unit": "Time Unit"
|
||||
},
|
||||
"available_csv_separators": {
|
||||
"comma": "Comma (,)",
|
||||
"semicolon": "Semicolon (;)",
|
||||
"both": "Both (,) and (;)"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -44,7 +44,9 @@
|
||||
"openFile": "Open file",
|
||||
"discardChanges": "Discard",
|
||||
"saveChanges": "Save changes",
|
||||
"editAsText": "Edit as Text"
|
||||
"editAsText": "Edit as Text",
|
||||
"increaseFontSize": "Increase font size",
|
||||
"decreaseFontSize": "Decrease font size"
|
||||
},
|
||||
"download": {
|
||||
"downloadFile": "Bestand downloaden",
|
||||
@@ -78,7 +80,14 @@
|
||||
"sortBySize": "Sorteren op grootte",
|
||||
"noPreview": "Preview is not available for this file.",
|
||||
"csvTooLarge": "CSV file is too large for preview (>5MB). Please download to view.",
|
||||
"csvLoadFailed": "Failed to load CSV file."
|
||||
"csvLoadFailed": "Failed to load CSV file.",
|
||||
"showingRows": "Showing {count} row(s)",
|
||||
"columnSeparator": "Column Separator",
|
||||
"csvSeparators": {
|
||||
"comma": "Comma (,)",
|
||||
"semicolon": "Semicolon (;)",
|
||||
"both": "Both (,) and (;)"
|
||||
}
|
||||
},
|
||||
"help": {
|
||||
"click": "selecteer bestand of map",
|
||||
@@ -272,10 +281,5 @@
|
||||
"minutes": "Minuten",
|
||||
"seconds": "Seconden",
|
||||
"unit": "Tijdseenheid"
|
||||
},
|
||||
"available_csv_separators": {
|
||||
"comma": "Comma (,)",
|
||||
"semicolon": "Semicolon (;)",
|
||||
"both": "Both (,) and (;)"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -44,7 +44,9 @@
|
||||
"openFile": "Open file",
|
||||
"discardChanges": "Slett",
|
||||
"saveChanges": "Lagre Endringane ",
|
||||
"editAsText": "Edit as Text"
|
||||
"editAsText": "Edit as Text",
|
||||
"increaseFontSize": "Increase font size",
|
||||
"decreaseFontSize": "Decrease font size"
|
||||
},
|
||||
"download": {
|
||||
"downloadFile": "Nedlast filen",
|
||||
@@ -78,7 +80,14 @@
|
||||
"sortBySize": "Sorter etter størrelse",
|
||||
"noPreview": "Forhåndsvisning er ikkje tilgjengeleg for denne filen.",
|
||||
"csvTooLarge": "CSV file is too large for preview (>5MB). Please download to view.",
|
||||
"csvLoadFailed": "Failed to load CSV file."
|
||||
"csvLoadFailed": "Failed to load CSV file.",
|
||||
"showingRows": "Showing {count} row(s)",
|
||||
"columnSeparator": "Column Separator",
|
||||
"csvSeparators": {
|
||||
"comma": "Comma (,)",
|
||||
"semicolon": "Semicolon (;)",
|
||||
"both": "Both (,) and (;)"
|
||||
}
|
||||
},
|
||||
"help": {
|
||||
"click": "velg fil eller katalog",
|
||||
@@ -272,10 +281,5 @@
|
||||
"minutes": "Minutt",
|
||||
"seconds": "Sekunder",
|
||||
"unit": "Time format"
|
||||
},
|
||||
"available_csv_separators": {
|
||||
"comma": "Comma (,)",
|
||||
"semicolon": "Semicolon (;)",
|
||||
"both": "Both (,) and (;)"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -44,7 +44,9 @@
|
||||
"openFile": "Otwórz plik",
|
||||
"discardChanges": "Odrzuć",
|
||||
"saveChanges": "Zapisz zmiany",
|
||||
"editAsText": "Edytuj jako tekst"
|
||||
"editAsText": "Edytuj jako tekst",
|
||||
"increaseFontSize": "Zwiększ rozmiar czcionki",
|
||||
"decreaseFontSize": "Zmniejsz rozmiar czcionki"
|
||||
},
|
||||
"download": {
|
||||
"downloadFile": "Pobierz plik",
|
||||
@@ -78,7 +80,14 @@
|
||||
"sortBySize": "Sortuj wg rozmiaru",
|
||||
"noPreview": "Podgląd tego pliku jest niedostępny.",
|
||||
"csvTooLarge": "Plik CSV jest za duży do podglądu (>5 MB). Pobierz, aby wyświetlić.",
|
||||
"csvLoadFailed": "Nie udało się załadować pliku CSV."
|
||||
"csvLoadFailed": "Nie udało się załadować pliku CSV.",
|
||||
"showingRows": "Wyświetlanie wierszy: {count}",
|
||||
"columnSeparator": "Separator kolumn",
|
||||
"csvSeparators": {
|
||||
"comma": "Przecinek (,)",
|
||||
"semicolon": "Średnik (;)",
|
||||
"both": "Zarówno (,), jak i (;)"
|
||||
}
|
||||
},
|
||||
"help": {
|
||||
"click": "zaznacz plik lub folder",
|
||||
@@ -272,10 +281,5 @@
|
||||
"minutes": "Minuty",
|
||||
"seconds": "Sekundy",
|
||||
"unit": "Jednostka czasu"
|
||||
},
|
||||
"available_csv_separators": {
|
||||
"comma": "Comma (,)",
|
||||
"semicolon": "Semicolon (;)",
|
||||
"both": "Both (,) and (;)"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -44,7 +44,9 @@
|
||||
"openFile": "Abrir",
|
||||
"discardChanges": "Discard",
|
||||
"saveChanges": "Save changes",
|
||||
"editAsText": "Edit as Text"
|
||||
"editAsText": "Edit as Text",
|
||||
"increaseFontSize": "Increase font size",
|
||||
"decreaseFontSize": "Decrease font size"
|
||||
},
|
||||
"download": {
|
||||
"downloadFile": "Baixar arquivo",
|
||||
@@ -78,7 +80,14 @@
|
||||
"sortBySize": "Ordenar pelo tamanho",
|
||||
"noPreview": "Pré-visualização não disponível para este arquivo.",
|
||||
"csvTooLarge": "CSV file is too large for preview (>5MB). Please download to view.",
|
||||
"csvLoadFailed": "Failed to load CSV file."
|
||||
"csvLoadFailed": "Failed to load CSV file.",
|
||||
"showingRows": "Showing {count} row(s)",
|
||||
"columnSeparator": "Column Separator",
|
||||
"csvSeparators": {
|
||||
"comma": "Comma (,)",
|
||||
"semicolon": "Semicolon (;)",
|
||||
"both": "Both (,) and (;)"
|
||||
}
|
||||
},
|
||||
"help": {
|
||||
"click": "selecionar pasta ou arquivo",
|
||||
@@ -272,10 +281,5 @@
|
||||
"minutes": "Minutos",
|
||||
"seconds": "Segundos",
|
||||
"unit": "Unidades de Tempo"
|
||||
},
|
||||
"available_csv_separators": {
|
||||
"comma": "Comma (,)",
|
||||
"semicolon": "Semicolon (;)",
|
||||
"both": "Both (,) and (;)"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -44,7 +44,9 @@
|
||||
"openFile": "Open file",
|
||||
"discardChanges": "Discard",
|
||||
"saveChanges": "Save changes",
|
||||
"editAsText": "Edit as Text"
|
||||
"editAsText": "Edit as Text",
|
||||
"increaseFontSize": "Increase font size",
|
||||
"decreaseFontSize": "Decrease font size"
|
||||
},
|
||||
"download": {
|
||||
"downloadFile": "Descarregar ficheiro",
|
||||
@@ -78,7 +80,14 @@
|
||||
"sortBySize": "Ordenar pelo tamanho",
|
||||
"noPreview": "Preview is not available for this file.",
|
||||
"csvTooLarge": "CSV file is too large for preview (>5MB). Please download to view.",
|
||||
"csvLoadFailed": "Failed to load CSV file."
|
||||
"csvLoadFailed": "Failed to load CSV file.",
|
||||
"showingRows": "Showing {count} row(s)",
|
||||
"columnSeparator": "Column Separator",
|
||||
"csvSeparators": {
|
||||
"comma": "Comma (,)",
|
||||
"semicolon": "Semicolon (;)",
|
||||
"both": "Both (,) and (;)"
|
||||
}
|
||||
},
|
||||
"help": {
|
||||
"click": "selecionar pasta ou ficheiro",
|
||||
@@ -272,10 +281,5 @@
|
||||
"minutes": "Minutos",
|
||||
"seconds": "Segundos",
|
||||
"unit": "Unidades de tempo"
|
||||
},
|
||||
"available_csv_separators": {
|
||||
"comma": "Comma (,)",
|
||||
"semicolon": "Semicolon (;)",
|
||||
"both": "Both (,) and (;)"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -44,7 +44,9 @@
|
||||
"openFile": "Open file",
|
||||
"discardChanges": "Discard",
|
||||
"saveChanges": "Save changes",
|
||||
"editAsText": "Edit as Text"
|
||||
"editAsText": "Edit as Text",
|
||||
"increaseFontSize": "Increase font size",
|
||||
"decreaseFontSize": "Decrease font size"
|
||||
},
|
||||
"download": {
|
||||
"downloadFile": "Descarcă fișier",
|
||||
@@ -78,7 +80,14 @@
|
||||
"sortBySize": "Ordonează după dimensiune",
|
||||
"noPreview": "Preview is not available for this file.",
|
||||
"csvTooLarge": "CSV file is too large for preview (>5MB). Please download to view.",
|
||||
"csvLoadFailed": "Failed to load CSV file."
|
||||
"csvLoadFailed": "Failed to load CSV file.",
|
||||
"showingRows": "Showing {count} row(s)",
|
||||
"columnSeparator": "Column Separator",
|
||||
"csvSeparators": {
|
||||
"comma": "Comma (,)",
|
||||
"semicolon": "Semicolon (;)",
|
||||
"both": "Both (,) and (;)"
|
||||
}
|
||||
},
|
||||
"help": {
|
||||
"click": "alege fișier sau director",
|
||||
@@ -272,10 +281,5 @@
|
||||
"minutes": "Minute",
|
||||
"seconds": "Secunde",
|
||||
"unit": "Unitate de timp"
|
||||
},
|
||||
"available_csv_separators": {
|
||||
"comma": "Comma (,)",
|
||||
"semicolon": "Semicolon (;)",
|
||||
"both": "Both (,) and (;)"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -44,7 +44,9 @@
|
||||
"openFile": "Открыть файл",
|
||||
"discardChanges": "Отказаться",
|
||||
"saveChanges": "Save changes",
|
||||
"editAsText": "Edit as Text"
|
||||
"editAsText": "Edit as Text",
|
||||
"increaseFontSize": "Increase font size",
|
||||
"decreaseFontSize": "Decrease font size"
|
||||
},
|
||||
"download": {
|
||||
"downloadFile": "Скачать файл",
|
||||
@@ -78,7 +80,14 @@
|
||||
"sortBySize": "Сортировка по размеру",
|
||||
"noPreview": "Предварительный просмотр для этого файла недоступен.",
|
||||
"csvTooLarge": "CSV file is too large for preview (>5MB). Please download to view.",
|
||||
"csvLoadFailed": "Failed to load CSV file."
|
||||
"csvLoadFailed": "Failed to load CSV file.",
|
||||
"showingRows": "Showing {count} row(s)",
|
||||
"columnSeparator": "Column Separator",
|
||||
"csvSeparators": {
|
||||
"comma": "Comma (,)",
|
||||
"semicolon": "Semicolon (;)",
|
||||
"both": "Both (,) and (;)"
|
||||
}
|
||||
},
|
||||
"help": {
|
||||
"click": "выбрать файл или каталог",
|
||||
@@ -272,10 +281,5 @@
|
||||
"minutes": "Минуты",
|
||||
"seconds": "Секунды",
|
||||
"unit": "Единица времени"
|
||||
},
|
||||
"available_csv_separators": {
|
||||
"comma": "Comma (,)",
|
||||
"semicolon": "Semicolon (;)",
|
||||
"both": "Both (,) and (;)"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -44,7 +44,9 @@
|
||||
"openFile": "Otvoriť súbor",
|
||||
"discardChanges": "Zahodiť",
|
||||
"saveChanges": "Uložiť zmeny",
|
||||
"editAsText": "Edit as Text"
|
||||
"editAsText": "Edit as Text",
|
||||
"increaseFontSize": "Increase font size",
|
||||
"decreaseFontSize": "Decrease font size"
|
||||
},
|
||||
"download": {
|
||||
"downloadFile": "Stiahnuť súbor",
|
||||
@@ -78,7 +80,14 @@
|
||||
"sortBySize": "Zoradiť podľa veľkosti",
|
||||
"noPreview": "Pre tento súbor nie je dostupný náhľad.",
|
||||
"csvTooLarge": "CSV file is too large for preview (>5MB). Please download to view.",
|
||||
"csvLoadFailed": "Failed to load CSV file."
|
||||
"csvLoadFailed": "Failed to load CSV file.",
|
||||
"showingRows": "Showing {count} row(s)",
|
||||
"columnSeparator": "Column Separator",
|
||||
"csvSeparators": {
|
||||
"comma": "Comma (,)",
|
||||
"semicolon": "Semicolon (;)",
|
||||
"both": "Both (,) and (;)"
|
||||
}
|
||||
},
|
||||
"help": {
|
||||
"click": "vyberie súbor alebo priečinok",
|
||||
@@ -272,10 +281,5 @@
|
||||
"minutes": "Minúty",
|
||||
"seconds": "Sekundy",
|
||||
"unit": "Jednotka času"
|
||||
},
|
||||
"available_csv_separators": {
|
||||
"comma": "Comma (,)",
|
||||
"semicolon": "Semicolon (;)",
|
||||
"both": "Both (,) and (;)"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -44,7 +44,9 @@
|
||||
"openFile": "Öppna fil",
|
||||
"discardChanges": "Förkasta",
|
||||
"saveChanges": "Spara ändringar",
|
||||
"editAsText": "Edit as Text"
|
||||
"editAsText": "Edit as Text",
|
||||
"increaseFontSize": "Increase font size",
|
||||
"decreaseFontSize": "Decrease font size"
|
||||
},
|
||||
"download": {
|
||||
"downloadFile": "Ladda ner fil",
|
||||
@@ -78,7 +80,14 @@
|
||||
"sortBySize": "Sortera på storlek",
|
||||
"noPreview": "Förhandsvisning är inte tillgänglig för denna fil.",
|
||||
"csvTooLarge": "CSV file is too large for preview (>5MB). Please download to view.",
|
||||
"csvLoadFailed": "Failed to load CSV file."
|
||||
"csvLoadFailed": "Failed to load CSV file.",
|
||||
"showingRows": "Showing {count} row(s)",
|
||||
"columnSeparator": "Column Separator",
|
||||
"csvSeparators": {
|
||||
"comma": "Comma (,)",
|
||||
"semicolon": "Semicolon (;)",
|
||||
"both": "Both (,) and (;)"
|
||||
}
|
||||
},
|
||||
"help": {
|
||||
"click": "välj fil eller mapp",
|
||||
@@ -272,10 +281,5 @@
|
||||
"minutes": "Minuter",
|
||||
"seconds": "Sekunder",
|
||||
"unit": "Tidsenhet"
|
||||
},
|
||||
"available_csv_separators": {
|
||||
"comma": "Comma (,)",
|
||||
"semicolon": "Semicolon (;)",
|
||||
"both": "Both (,) and (;)"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -44,7 +44,9 @@
|
||||
"openFile": "Dosyayı aç",
|
||||
"discardChanges": "Discard",
|
||||
"saveChanges": "Save changes",
|
||||
"editAsText": "Edit as Text"
|
||||
"editAsText": "Edit as Text",
|
||||
"increaseFontSize": "Increase font size",
|
||||
"decreaseFontSize": "Decrease font size"
|
||||
},
|
||||
"download": {
|
||||
"downloadFile": "Dosyayı indir",
|
||||
@@ -78,7 +80,14 @@
|
||||
"sortBySize": "Boyuta göre sırala",
|
||||
"noPreview": "Bu dosya için önizleme aktif değil",
|
||||
"csvTooLarge": "CSV file is too large for preview (>5MB). Please download to view.",
|
||||
"csvLoadFailed": "Failed to load CSV file."
|
||||
"csvLoadFailed": "Failed to load CSV file.",
|
||||
"showingRows": "Showing {count} row(s)",
|
||||
"columnSeparator": "Column Separator",
|
||||
"csvSeparators": {
|
||||
"comma": "Comma (,)",
|
||||
"semicolon": "Semicolon (;)",
|
||||
"both": "Both (,) and (;)"
|
||||
}
|
||||
},
|
||||
"help": {
|
||||
"click": "dosya veya klasör seçin",
|
||||
@@ -272,10 +281,5 @@
|
||||
"minutes": "Dakika",
|
||||
"seconds": "Saniye",
|
||||
"unit": "Zaman birimi"
|
||||
},
|
||||
"available_csv_separators": {
|
||||
"comma": "Comma (,)",
|
||||
"semicolon": "Semicolon (;)",
|
||||
"both": "Both (,) and (;)"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -44,7 +44,9 @@
|
||||
"openFile": "Відкрити файл",
|
||||
"discardChanges": "Скасувати",
|
||||
"saveChanges": "Save changes",
|
||||
"editAsText": "Edit as Text"
|
||||
"editAsText": "Edit as Text",
|
||||
"increaseFontSize": "Increase font size",
|
||||
"decreaseFontSize": "Decrease font size"
|
||||
},
|
||||
"download": {
|
||||
"downloadFile": "Завантажити файл",
|
||||
@@ -78,7 +80,14 @@
|
||||
"sortBySize": "Сортувати за розміром",
|
||||
"noPreview": "Попередній перегляд для цього файлу недоступний.",
|
||||
"csvTooLarge": "CSV file is too large for preview (>5MB). Please download to view.",
|
||||
"csvLoadFailed": "Failed to load CSV file."
|
||||
"csvLoadFailed": "Failed to load CSV file.",
|
||||
"showingRows": "Showing {count} row(s)",
|
||||
"columnSeparator": "Column Separator",
|
||||
"csvSeparators": {
|
||||
"comma": "Comma (,)",
|
||||
"semicolon": "Semicolon (;)",
|
||||
"both": "Both (,) and (;)"
|
||||
}
|
||||
},
|
||||
"help": {
|
||||
"click": "вибрати файл чи каталог",
|
||||
@@ -272,10 +281,5 @@
|
||||
"minutes": "Хвилини",
|
||||
"seconds": "Секунди",
|
||||
"unit": "Одиниця часу"
|
||||
},
|
||||
"available_csv_separators": {
|
||||
"comma": "Comma (,)",
|
||||
"semicolon": "Semicolon (;)",
|
||||
"both": "Both (,) and (;)"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -44,7 +44,9 @@
|
||||
"openFile": "Mở tệp",
|
||||
"discardChanges": "Hủy bỏ thay đổi",
|
||||
"saveChanges": "Save changes",
|
||||
"editAsText": "Edit as Text"
|
||||
"editAsText": "Edit as Text",
|
||||
"increaseFontSize": "Increase font size",
|
||||
"decreaseFontSize": "Decrease font size"
|
||||
},
|
||||
"download": {
|
||||
"downloadFile": "Tải xuống tệp tin",
|
||||
@@ -78,7 +80,14 @@
|
||||
"sortBySize": "Sắp xếp theo kích thước",
|
||||
"noPreview": "Không có bản xem trước cho tập tin này.",
|
||||
"csvTooLarge": "CSV file is too large for preview (>5MB). Please download to view.",
|
||||
"csvLoadFailed": "Failed to load CSV file."
|
||||
"csvLoadFailed": "Failed to load CSV file.",
|
||||
"showingRows": "Showing {count} row(s)",
|
||||
"columnSeparator": "Column Separator",
|
||||
"csvSeparators": {
|
||||
"comma": "Comma (,)",
|
||||
"semicolon": "Semicolon (;)",
|
||||
"both": "Both (,) and (;)"
|
||||
}
|
||||
},
|
||||
"help": {
|
||||
"click": "chọn tập tin hoặc thư mục",
|
||||
@@ -272,10 +281,5 @@
|
||||
"minutes": "Phút",
|
||||
"seconds": "Giây",
|
||||
"unit": "Đơn vị"
|
||||
},
|
||||
"available_csv_separators": {
|
||||
"comma": "Comma (,)",
|
||||
"semicolon": "Semicolon (;)",
|
||||
"both": "Both (,) and (;)"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -44,7 +44,9 @@
|
||||
"openFile": "打开文件",
|
||||
"discardChanges": "放弃更改",
|
||||
"saveChanges": "Save changes",
|
||||
"editAsText": "Edit as Text"
|
||||
"editAsText": "Edit as Text",
|
||||
"increaseFontSize": "Increase font size",
|
||||
"decreaseFontSize": "Decrease font size"
|
||||
},
|
||||
"download": {
|
||||
"downloadFile": "下载文件",
|
||||
@@ -78,7 +80,14 @@
|
||||
"sortBySize": "按大小排序",
|
||||
"noPreview": "此文件无法预览。",
|
||||
"csvTooLarge": "CSV file is too large for preview (>5MB). Please download to view.",
|
||||
"csvLoadFailed": "Failed to load CSV file."
|
||||
"csvLoadFailed": "Failed to load CSV file.",
|
||||
"showingRows": "Showing {count} row(s)",
|
||||
"columnSeparator": "Column Separator",
|
||||
"csvSeparators": {
|
||||
"comma": "Comma (,)",
|
||||
"semicolon": "Semicolon (;)",
|
||||
"both": "Both (,) and (;)"
|
||||
}
|
||||
},
|
||||
"help": {
|
||||
"click": "选择文件或文件夹",
|
||||
@@ -272,10 +281,5 @@
|
||||
"minutes": "分钟",
|
||||
"seconds": "秒",
|
||||
"unit": "时间单位"
|
||||
},
|
||||
"available_csv_separators": {
|
||||
"comma": "Comma (,)",
|
||||
"semicolon": "Semicolon (;)",
|
||||
"both": "Both (,) and (;)"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -44,7 +44,9 @@
|
||||
"openFile": "開啟檔案",
|
||||
"discardChanges": "放棄變更",
|
||||
"saveChanges": "Save changes",
|
||||
"editAsText": "Edit as Text"
|
||||
"editAsText": "Edit as Text",
|
||||
"increaseFontSize": "Increase font size",
|
||||
"decreaseFontSize": "Decrease font size"
|
||||
},
|
||||
"download": {
|
||||
"downloadFile": "下載檔案",
|
||||
@@ -78,7 +80,14 @@
|
||||
"sortBySize": "按大小排序",
|
||||
"noPreview": "此檔案無法預覽。",
|
||||
"csvTooLarge": "CSV file is too large for preview (>5MB). Please download to view.",
|
||||
"csvLoadFailed": "Failed to load CSV file."
|
||||
"csvLoadFailed": "Failed to load CSV file.",
|
||||
"showingRows": "Showing {count} row(s)",
|
||||
"columnSeparator": "Column Separator",
|
||||
"csvSeparators": {
|
||||
"comma": "Comma (,)",
|
||||
"semicolon": "Semicolon (;)",
|
||||
"both": "Both (,) and (;)"
|
||||
}
|
||||
},
|
||||
"help": {
|
||||
"click": "選擇檔案或目錄",
|
||||
@@ -272,10 +281,5 @@
|
||||
"minutes": "分鐘",
|
||||
"seconds": "秒",
|
||||
"unit": "時間單位"
|
||||
},
|
||||
"available_csv_separators": {
|
||||
"comma": "Comma (,)",
|
||||
"semicolon": "Semicolon (;)",
|
||||
"both": "Both (,) and (;)"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,9 +24,9 @@ require (
|
||||
github.com/spf13/viper v1.21.0
|
||||
github.com/stretchr/testify v1.11.1
|
||||
github.com/tomasen/realip v0.0.0-20180522021738-f0c99a92ddce
|
||||
golang.org/x/crypto v0.45.0
|
||||
golang.org/x/image v0.33.0
|
||||
golang.org/x/text v0.31.0
|
||||
golang.org/x/crypto v0.46.0
|
||||
golang.org/x/image v0.34.0
|
||||
golang.org/x/text v0.32.0
|
||||
gopkg.in/natefinch/lumberjack.v2 v2.2.1
|
||||
gopkg.in/yaml.v3 v3.0.1
|
||||
)
|
||||
@@ -74,8 +74,8 @@ require (
|
||||
go.yaml.in/yaml/v3 v3.0.4 // indirect
|
||||
go4.org v0.0.0-20230225012048-214862532bf5 // indirect
|
||||
golang.org/x/net v0.47.0 // indirect
|
||||
golang.org/x/sync v0.18.0 // indirect
|
||||
golang.org/x/sys v0.38.0 // indirect
|
||||
golang.org/x/sync v0.19.0 // indirect
|
||||
golang.org/x/sys v0.39.0 // indirect
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect
|
||||
gopkg.in/yaml.v2 v2.4.0 // indirect
|
||||
)
|
||||
|
||||
@@ -266,8 +266,8 @@ golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8U
|
||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||
golang.org/x/crypto v0.45.0 h1:jMBrvKuj23MTlT0bQEOBcAE0mjg8mK9RXFhRH6nyF3Q=
|
||||
golang.org/x/crypto v0.45.0/go.mod h1:XTGrrkGJve7CYK7J8PEww4aY7gM3qMCElcJQ8n8JdX4=
|
||||
golang.org/x/crypto v0.46.0 h1:cKRW/pmt1pKAfetfu+RCEvjvZkA9RimPbh7bhFjGVBU=
|
||||
golang.org/x/crypto v0.46.0/go.mod h1:Evb/oLKmMraqjZ2iQTwDwvCtJkczlDuTmdJXoZVzqU0=
|
||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
|
||||
@@ -279,8 +279,8 @@ golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EH
|
||||
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
|
||||
golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
|
||||
golang.org/x/image v0.0.0-20191009234506-e7c1f5e7dbb8/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
|
||||
golang.org/x/image v0.33.0 h1:LXRZRnv1+zGd5XBUVRFmYEphyyKJjQjCRiOuAP3sZfQ=
|
||||
golang.org/x/image v0.33.0/go.mod h1:DD3OsTYT9chzuzTQt+zMcOlBHgfoKQb1gry8p76Y1sc=
|
||||
golang.org/x/image v0.34.0 h1:33gCkyw9hmwbZJeZkct8XyR11yH889EQt/QH4VmXMn8=
|
||||
golang.org/x/image v0.34.0/go.mod h1:2RNFBZRB+vnwwFil8GkMdRvrJOFd1AzdZI6vOY+eJVU=
|
||||
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
|
||||
golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||
@@ -333,8 +333,8 @@ golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJ
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.18.0 h1:kr88TuHDroi+UVf+0hZnirlk8o8T+4MrK6mr60WkH/I=
|
||||
golang.org/x/sync v0.18.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI=
|
||||
golang.org/x/sync v0.19.0 h1:vV+1eWNmZ5geRlYjzm2adRgW2/mcpevXNg50YZtPCE4=
|
||||
golang.org/x/sync v0.19.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI=
|
||||
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
@@ -360,8 +360,8 @@ golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBc
|
||||
golang.org/x/sys v0.0.0-20220928140112-f11e5e49a4ec/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.38.0 h1:3yZWxaJjBmCWXqhN1qh02AkOnCQ1poK6oF+a7xWL6Gc=
|
||||
golang.org/x/sys v0.38.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
|
||||
golang.org/x/sys v0.39.0 h1:CvCKL8MeisomCi6qNZ+wbb0DN9E5AATixKsvNtMoMFk=
|
||||
golang.org/x/sys v0.39.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
|
||||
@@ -372,8 +372,8 @@ golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
||||
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
||||
golang.org/x/text v0.31.0 h1:aC8ghyu4JhP8VojJ2lEHBnochRno1sgL6nEi9WGFGMM=
|
||||
golang.org/x/text v0.31.0/go.mod h1:tKRAlv61yKIjGGHX/4tP1LTbc13YSec1pxVEWXzfoeM=
|
||||
golang.org/x/text v0.32.0 h1:ZD01bjUt1FQ9WJ0ClOL5vxgxOI/sVCNgX1YtKwcY0mU=
|
||||
golang.org/x/text v0.32.0/go.mod h1:o/rUWzghvpD5TXrTIBuJU77MTaN0ljMWE47kxGJQ7jY=
|
||||
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
|
||||
@@ -7,34 +7,33 @@ include $(TOPDIR)/rules.mk
|
||||
include $(INCLUDE_DIR)/kernel.mk
|
||||
|
||||
PKG_NAME:=r8152
|
||||
PKG_VERSION:=2.20.1
|
||||
PKG_VERSION:=2.21.4
|
||||
PKG_RELEASE:=1
|
||||
|
||||
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
|
||||
PKG_SOURCE_URL:=https://codeload.github.com/wget/realtek-r8152-linux/tar.gz/v$(PKG_VERSION)?
|
||||
PKG_HASH:=045a1e1d20336d26b61b01d8561216029ff3405894707958b5670a7cd7fa75c1
|
||||
PKG_HASH:=05041e46b0edb75b53bbdac640fc027b1eac22cf493e76c3018ab3b5c1dc1df8
|
||||
PKG_BUILD_DIR:=$(KERNEL_BUILD_DIR)/realtek-$(PKG_NAME)-linux-$(PKG_VERSION)
|
||||
|
||||
PKG_MAINTAINER:=Tianling Shen <cnsztl@immortalwrt.org>
|
||||
|
||||
include $(INCLUDE_DIR)/package.mk
|
||||
|
||||
define KernelPackage/usb-net-rtl8152-vendor
|
||||
VERSION:=$(LINUX_VERSION)+$(PKG_VERSION)-$(BOARD)-$(PKG_RELEASE)
|
||||
TITLE:=Realtek RTL8152/RTL8153/RTL8154/RTL8156/RTL8157 driver
|
||||
SUBMENU:=USB Support
|
||||
DEPENDS:=+kmod-usb-net +LINUX_6_12:kmod-libphy
|
||||
define KernelPackage/r8152
|
||||
SUBMENU:=Network Devices
|
||||
TITLE:=Realtek RTL815X USB Ethernet driver
|
||||
DEPENDS:=+kmod-usb-net +kmod-libphy
|
||||
FILES:=$(PKG_BUILD_DIR)/r8152.ko
|
||||
AUTOLOAD:=$(call AutoProbe,r8152)
|
||||
CONFLICTS:=kmod-usb-net-rtl8152
|
||||
endef
|
||||
|
||||
define KernelPackage/usb-net-rtl8152-vendor/description
|
||||
Kernel module for Realtek Realtek USB 1G / 2.5G / 5G / 10G Ethernet Chipsets
|
||||
define KernelPackage/r8152/description
|
||||
Kernel module for Realtek USB Ethernet Chipsets
|
||||
endef
|
||||
|
||||
define Build/Compile
|
||||
+$(KERNEL_MAKE) M=$(PKG_BUILD_DIR) modules
|
||||
endef
|
||||
|
||||
$(eval $(call KernelPackage,usb-net-rtl8152-vendor))
|
||||
$(eval $(call KernelPackage,r8152))
|
||||
@@ -30,6 +30,7 @@ type SudokuOption struct {
|
||||
TableType string `proxy:"table-type,omitempty"` // "prefer_ascii" or "prefer_entropy"
|
||||
EnablePureDownlink *bool `proxy:"enable-pure-downlink,omitempty"`
|
||||
HTTPMask bool `proxy:"http-mask,omitempty"`
|
||||
CustomTable string `proxy:"custom-table,omitempty"` // optional custom byte layout, e.g. xpxvvpvv
|
||||
}
|
||||
|
||||
// DialContext implements C.ProxyAdapter
|
||||
@@ -178,13 +179,17 @@ func NewSudoku(option SudokuOption) (*Sudoku, error) {
|
||||
ServerAddress: net.JoinHostPort(option.Server, strconv.Itoa(option.Port)),
|
||||
Key: option.Key,
|
||||
AEADMethod: defaultConf.AEADMethod,
|
||||
Table: sudoku.NewTable(sudoku.ClientAEADSeed(option.Key), tableType),
|
||||
PaddingMin: paddingMin,
|
||||
PaddingMax: paddingMax,
|
||||
EnablePureDownlink: enablePureDownlink,
|
||||
HandshakeTimeoutSeconds: defaultConf.HandshakeTimeoutSeconds,
|
||||
DisableHTTPMask: !option.HTTPMask,
|
||||
}
|
||||
table, err := sudoku.NewTableWithCustom(sudoku.ClientAEADSeed(option.Key), tableType, option.CustomTable)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("build table failed: %w", err)
|
||||
}
|
||||
baseConf.Table = table
|
||||
if option.AEADMethod != "" {
|
||||
baseConf.AEADMethod = option.AEADMethod
|
||||
}
|
||||
|
||||
@@ -609,6 +609,13 @@ func (w *WireGuard) ResolveUDP(ctx context.Context, metadata *C.Metadata) error
|
||||
return nil
|
||||
}
|
||||
|
||||
// ProxyInfo implements C.ProxyAdapter
|
||||
func (w *WireGuard) ProxyInfo() C.ProxyInfo {
|
||||
info := w.Base.ProxyInfo()
|
||||
info.DialerProxy = w.option.DialerProxy
|
||||
return info
|
||||
}
|
||||
|
||||
// IsL3Protocol implements C.ProxyAdapter
|
||||
func (w *WireGuard) IsL3Protocol(metadata *C.Metadata) bool {
|
||||
return true
|
||||
|
||||
@@ -8,6 +8,7 @@ import (
|
||||
"reflect"
|
||||
"runtime"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/metacubex/mihomo/adapter"
|
||||
@@ -43,6 +44,7 @@ type providerForApi struct {
|
||||
}
|
||||
|
||||
type baseProvider struct {
|
||||
mutex sync.RWMutex
|
||||
name string
|
||||
proxies []C.Proxy
|
||||
healthCheck *HealthCheck
|
||||
@@ -54,6 +56,8 @@ func (bp *baseProvider) Name() string {
|
||||
}
|
||||
|
||||
func (bp *baseProvider) Version() uint32 {
|
||||
bp.mutex.RLock()
|
||||
defer bp.mutex.RUnlock()
|
||||
return bp.version
|
||||
}
|
||||
|
||||
@@ -73,10 +77,14 @@ func (bp *baseProvider) Type() P.ProviderType {
|
||||
}
|
||||
|
||||
func (bp *baseProvider) Proxies() []C.Proxy {
|
||||
bp.mutex.RLock()
|
||||
defer bp.mutex.RUnlock()
|
||||
return bp.proxies
|
||||
}
|
||||
|
||||
func (bp *baseProvider) Count() int {
|
||||
bp.mutex.RLock()
|
||||
defer bp.mutex.RUnlock()
|
||||
return len(bp.proxies)
|
||||
}
|
||||
|
||||
@@ -93,6 +101,8 @@ func (bp *baseProvider) RegisterHealthCheckTask(url string, expectedStatus utils
|
||||
}
|
||||
|
||||
func (bp *baseProvider) setProxies(proxies []C.Proxy) {
|
||||
bp.mutex.Lock()
|
||||
defer bp.mutex.Unlock()
|
||||
bp.proxies = proxies
|
||||
bp.version += 1
|
||||
bp.healthCheck.setProxies(proxies)
|
||||
|
||||
@@ -1048,8 +1048,9 @@ proxies: # socks5
|
||||
padding-min: 2 # 最小填充字节数
|
||||
padding-max: 7 # 最大填充字节数
|
||||
table-type: prefer_ascii # 可选值:prefer_ascii、prefer_entropy 前者全ascii映射,后者保证熵值(汉明1)低于3
|
||||
# custom-table: xpxvvpvv # 可选,自定义字节布局,必须包含2个x、2个p、4个v,可随意组合。启用此处则无需配置`table-type`
|
||||
http-mask: true # 是否启用http掩码
|
||||
enable-pure-downlink: false # 是否启用混淆下行,false的情况下能在保证数据安全的前提下极大提升下行速度
|
||||
enable-pure-downlink: false # 是否启用混淆下行,false的情况下能在保证数据安全的前提下极大提升下行速度,与服务端端保持相同(如果此处为false,则要求aead不可为none)
|
||||
|
||||
# anytls
|
||||
- name: anytls
|
||||
@@ -1589,8 +1590,9 @@ listeners:
|
||||
padding-min: 1 # 填充最小长度
|
||||
padding-max: 15 # 填充最大长度,均不建议过大
|
||||
table-type: prefer_ascii # 可选值:prefer_ascii、prefer_entropy 前者全ascii映射,后者保证熵值(汉明1)低于3
|
||||
# custom-table: xpxvvpvv # 可选,自定义字节布局,必须包含2个x、2个p、4个v
|
||||
handshake-timeout: 5 # optional
|
||||
enable-pure-downlink: false # 是否启用混淆下行,false的情况下能在保证数据安全的前提下极大提升下行速度,与客户端保持相同
|
||||
enable-pure-downlink: false # 是否启用混淆下行,false的情况下能在保证数据安全的前提下极大提升下行速度,与客户端保持相同(如果此处为false,则要求aead不可为none)
|
||||
|
||||
|
||||
|
||||
@@ -1742,4 +1744,3 @@ listeners:
|
||||
# alpn:
|
||||
# - h3
|
||||
# max-udp-relay-packet-size: 1500
|
||||
|
||||
|
||||
@@ -43,7 +43,7 @@ require (
|
||||
github.com/mroth/weightedrand/v2 v2.1.0
|
||||
github.com/openacid/low v0.1.21
|
||||
github.com/oschwald/maxminddb-golang v1.12.0 // lastest version compatible with golang1.20
|
||||
github.com/saba-futai/sudoku v0.0.2-b
|
||||
github.com/saba-futai/sudoku v0.0.2-c
|
||||
github.com/sagernet/cors v1.2.1
|
||||
github.com/sagernet/netlink v0.0.0-20240612041022-b9a21c07ac6a
|
||||
github.com/samber/lo v1.52.0
|
||||
|
||||
@@ -171,8 +171,8 @@ github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZN
|
||||
github.com/prashantv/gostub v1.1.0 h1:BTyx3RfQjRHnUWaGF9oQos79AlQ5k8WNktv7VGvVH4g=
|
||||
github.com/quic-go/qpack v0.4.0 h1:Cr9BXA1sQS2SmDUWjSofMPNKmvF6IiIfDRmgU0w1ZCo=
|
||||
github.com/quic-go/qpack v0.4.0/go.mod h1:UZVnYIfi5GRk+zI9UMaCPsmZ2xKJP7XBUvVyT1Knj9A=
|
||||
github.com/saba-futai/sudoku v0.0.2-b h1:IbBjgZe1IzzD4xjaCSAdAy8ZNrwOusT14AwCYm77NwI=
|
||||
github.com/saba-futai/sudoku v0.0.2-b/go.mod h1:Rvggsoprp7HQM7bMIZUd1M27bPj8THRsZdY1dGbIAvo=
|
||||
github.com/saba-futai/sudoku v0.0.2-c h1:0CaoCKx4Br8UL97fnIxn8Y7rnQpflBza7kfaIrdg2rI=
|
||||
github.com/saba-futai/sudoku v0.0.2-c/go.mod h1:Rvggsoprp7HQM7bMIZUd1M27bPj8THRsZdY1dGbIAvo=
|
||||
github.com/sagernet/cors v1.2.1 h1:Cv5Z8y9YSD6Gm+qSpNrL3LO4lD3eQVvbFYJSG7JCMHQ=
|
||||
github.com/sagernet/cors v1.2.1/go.mod h1:O64VyOjjhrkLmQIjF4KGRrJO/5dVXFdpEmCW/eISRAI=
|
||||
github.com/sagernet/netlink v0.0.0-20240612041022-b9a21c07ac6a h1:ObwtHN2VpqE0ZNjr6sGeT00J8uU7JF4cNUdb44/Duis=
|
||||
|
||||
@@ -14,6 +14,7 @@ type SudokuServer struct {
|
||||
TableType string `json:"table-type,omitempty"`
|
||||
HandshakeTimeoutSecond *int `json:"handshake-timeout,omitempty"`
|
||||
EnablePureDownlink *bool `json:"enable-pure-downlink,omitempty"`
|
||||
CustomTable string `json:"custom-table,omitempty"`
|
||||
}
|
||||
|
||||
func (s SudokuServer) String() string {
|
||||
|
||||
@@ -20,6 +20,7 @@ type SudokuOption struct {
|
||||
TableType string `inbound:"table-type,omitempty"` // "prefer_ascii" or "prefer_entropy"
|
||||
HandshakeTimeoutSecond *int `inbound:"handshake-timeout,omitempty"`
|
||||
EnablePureDownlink *bool `inbound:"enable-pure-downlink,omitempty"`
|
||||
CustomTable string `inbound:"custom-table,omitempty"` // optional custom byte layout, e.g. xpxvvpvv
|
||||
}
|
||||
|
||||
func (o SudokuOption) Equal(config C.InboundConfig) bool {
|
||||
@@ -52,6 +53,7 @@ func NewSudoku(options *SudokuOption) (*Sudoku, error) {
|
||||
TableType: options.TableType,
|
||||
HandshakeTimeoutSecond: options.HandshakeTimeoutSecond,
|
||||
EnablePureDownlink: options.EnablePureDownlink,
|
||||
CustomTable: options.CustomTable,
|
||||
}
|
||||
|
||||
return &Sudoku{
|
||||
|
||||
@@ -138,3 +138,27 @@ func TestInboundSudoku_PackedDownlink(t *testing.T) {
|
||||
testInboundSudoku(t, inboundOptions, outboundOptions)
|
||||
})
|
||||
}
|
||||
|
||||
func TestInboundSudoku_CustomTable(t *testing.T) {
|
||||
key := "test_key_custom"
|
||||
custom := "xpxvvpvv"
|
||||
inboundOptions := inbound.SudokuOption{
|
||||
Key: key,
|
||||
TableType: "prefer_entropy",
|
||||
CustomTable: custom,
|
||||
}
|
||||
outboundOptions := outbound.SudokuOption{
|
||||
Key: key,
|
||||
TableType: "prefer_entropy",
|
||||
CustomTable: custom,
|
||||
}
|
||||
testInboundSudoku(t, inboundOptions, outboundOptions)
|
||||
|
||||
t.Run("ed25519key", func(t *testing.T) {
|
||||
inboundOptions := inboundOptions
|
||||
outboundOptions := outboundOptions
|
||||
inboundOptions.Key = sudokuPublicKey
|
||||
outboundOptions.Key = sudokuPrivateKey
|
||||
testInboundSudoku(t, inboundOptions, outboundOptions)
|
||||
})
|
||||
}
|
||||
|
||||
@@ -152,6 +152,12 @@ func New(config LC.SudokuServer, tunnel C.Tunnel, additions ...inbound.Addition)
|
||||
enablePureDownlink = *config.EnablePureDownlink
|
||||
}
|
||||
|
||||
table, err := sudoku.NewTableWithCustom(config.Key, tableType, config.CustomTable)
|
||||
if err != nil {
|
||||
_ = l.Close()
|
||||
return nil, err
|
||||
}
|
||||
|
||||
handshakeTimeout := defaultConf.HandshakeTimeoutSeconds
|
||||
if config.HandshakeTimeoutSecond != nil {
|
||||
handshakeTimeout = *config.HandshakeTimeoutSecond
|
||||
@@ -160,7 +166,7 @@ func New(config LC.SudokuServer, tunnel C.Tunnel, additions ...inbound.Addition)
|
||||
protoConf := sudoku.ProtocolConfig{
|
||||
Key: config.Key,
|
||||
AEADMethod: defaultConf.AEADMethod,
|
||||
Table: sudoku.NewTable(config.Key, tableType),
|
||||
Table: table,
|
||||
PaddingMin: paddingMin,
|
||||
PaddingMax: paddingMax,
|
||||
EnablePureDownlink: enablePureDownlink,
|
||||
|
||||
@@ -146,12 +146,23 @@ func buildHandshakePayload(key string) [16]byte {
|
||||
}
|
||||
|
||||
func NewTable(key string, tableType string) *sudoku.Table {
|
||||
start := time.Now()
|
||||
table := sudoku.NewTable(key, tableType)
|
||||
log.Infoln("[Sudoku] Tables initialized (%s) in %v", tableType, time.Since(start))
|
||||
table, err := NewTableWithCustom(key, tableType, "")
|
||||
if err != nil {
|
||||
panic(fmt.Sprintf("[Sudoku] failed to init tables: %v", err))
|
||||
}
|
||||
return table
|
||||
}
|
||||
|
||||
func NewTableWithCustom(key string, tableType string, customTable string) (*sudoku.Table, error) {
|
||||
start := time.Now()
|
||||
table, err := sudoku.NewTableWithCustom(key, tableType, customTable)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
log.Infoln("[Sudoku] Tables initialized (%s, custom=%v) in %v", tableType, customTable != "", time.Since(start))
|
||||
return table, nil
|
||||
}
|
||||
|
||||
func ClientAEADSeed(key string) string {
|
||||
if recovered, err := crypto.RecoverPublicKey(key); err == nil {
|
||||
return crypto.EncodePoint(recovered)
|
||||
|
||||
@@ -228,3 +228,22 @@ func runPackedUoTSession(id int, cfg *apis.ProtocolConfig, errCh chan<- error) {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
func TestCustomTableHandshake(t *testing.T) {
|
||||
table, err := sudokuobfs.NewTableWithCustom("custom-seed", "prefer_entropy", "xpxvvpvv")
|
||||
if err != nil {
|
||||
t.Fatalf("build custom table: %v", err)
|
||||
}
|
||||
cfg := newPackedConfig(table)
|
||||
errCh := make(chan error, 2)
|
||||
|
||||
runPackedTCPSession(42, cfg, errCh)
|
||||
runPackedUoTSession(43, cfg, errCh)
|
||||
|
||||
close(errCh)
|
||||
for err := range errCh {
|
||||
if err != nil {
|
||||
t.Fatalf("custom table handshake failed: %v", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@ jobs:
|
||||
stale:
|
||||
runs-on: ubuntu-22.04
|
||||
steps:
|
||||
- uses: actions/stale@v7.0.0
|
||||
- uses: actions/stale@v10
|
||||
with:
|
||||
stale-issue-message: "Stale Issue"
|
||||
stale-pr-message: "Stale PR"
|
||||
|
||||
@@ -206,9 +206,9 @@ function gen_outbound(flag, node, tag, proxy_table)
|
||||
local first = node.tcp_guise_http_path[1]
|
||||
return (first == "" or not first) and "/" or first
|
||||
end)() or "/",
|
||||
headers = {
|
||||
["User-Agent"] = node.tcp_guise_http_user_agent or nil
|
||||
},
|
||||
headers = node.tcp_guise_http_user_agent and {
|
||||
["User-Agent"] = node.tcp_guise_http_user_agent
|
||||
} or nil,
|
||||
idle_timeout = (node.http_h2_health_check == "1") and node.http_h2_read_idle_timeout or nil,
|
||||
ping_timeout = (node.http_h2_health_check == "1") and node.http_h2_health_check_timeout or nil,
|
||||
}
|
||||
@@ -220,9 +220,9 @@ function gen_outbound(flag, node, tag, proxy_table)
|
||||
type = "http",
|
||||
host = node.http_host or {},
|
||||
path = node.http_path or "/",
|
||||
headers = {
|
||||
["User-Agent"] = node.http_user_agent or nil
|
||||
},
|
||||
headers = node.http_user_agent and {
|
||||
["User-Agent"] = node.http_user_agent
|
||||
} or nil,
|
||||
idle_timeout = (node.http_h2_health_check == "1") and node.http_h2_read_idle_timeout or nil,
|
||||
ping_timeout = (node.http_h2_health_check == "1") and node.http_h2_health_check_timeout or nil,
|
||||
}
|
||||
@@ -233,10 +233,10 @@ function gen_outbound(flag, node, tag, proxy_table)
|
||||
v2ray_transport = {
|
||||
type = "ws",
|
||||
path = node.ws_path or "/",
|
||||
headers = {
|
||||
Host = node.ws_host or nil,
|
||||
["User-Agent"] = node.ws_user_agent or nil
|
||||
},
|
||||
headers = (node.ws_host or node.ws_user_agent) and {
|
||||
Host = node.ws_host,
|
||||
["User-Agent"] = node.ws_user_agent
|
||||
} or nil,
|
||||
max_early_data = tonumber(node.ws_maxEarlyData) or nil,
|
||||
early_data_header_name = (node.ws_earlyDataHeaderName) and node.ws_earlyDataHeaderName or nil --要与 Xray-core 兼容,请将其设置为 Sec-WebSocket-Protocol。它需要与服务器保持一致。
|
||||
}
|
||||
@@ -247,9 +247,9 @@ function gen_outbound(flag, node, tag, proxy_table)
|
||||
type = "httpupgrade",
|
||||
host = node.httpupgrade_host,
|
||||
path = node.httpupgrade_path or "/",
|
||||
headers = {
|
||||
["User-Agent"] = node.httpupgrade_user_agent or nil
|
||||
}
|
||||
headers = node.httpupgrade_user_agent and {
|
||||
["User-Agent"] = node.httpupgrade_user_agent
|
||||
} or nil
|
||||
}
|
||||
end
|
||||
|
||||
|
||||
@@ -178,10 +178,10 @@ function gen_outbound(flag, node, tag, proxy_table)
|
||||
end
|
||||
return r
|
||||
end)() or {"/"},
|
||||
headers = {
|
||||
Host = node.tcp_guise_http_host or {},
|
||||
headers = (node.tcp_guise_http_host or node.tcp_guise_http_user_agent) and {
|
||||
Host = node.tcp_guise_http_host,
|
||||
["User-Agent"] = node.tcp_guise_http_user_agent and {node.tcp_guise_http_user_agent} or nil
|
||||
}
|
||||
} or nil
|
||||
} or nil
|
||||
}
|
||||
} or nil,
|
||||
@@ -201,10 +201,10 @@ function gen_outbound(flag, node, tag, proxy_table)
|
||||
} or nil,
|
||||
wsSettings = (node.transport == "ws") and {
|
||||
path = node.ws_path or "/",
|
||||
headers = {
|
||||
Host = node.ws_host or nil,
|
||||
["User-Agent"] = node.ws_user_agent or nil
|
||||
},
|
||||
headers = (node.ws_host or node.ws_user_agent) and {
|
||||
Host = node.ws_host,
|
||||
["User-Agent"] = node.ws_user_agent
|
||||
} or nil,
|
||||
maxEarlyData = tonumber(node.ws_maxEarlyData) or nil,
|
||||
earlyDataHeaderName = (node.ws_earlyDataHeaderName) and node.ws_earlyDataHeaderName or nil,
|
||||
heartbeatPeriod = tonumber(node.ws_heartbeatPeriod) or nil
|
||||
@@ -220,9 +220,9 @@ function gen_outbound(flag, node, tag, proxy_table)
|
||||
httpupgradeSettings = (node.transport == "httpupgrade") and {
|
||||
path = node.httpupgrade_path or "/",
|
||||
host = node.httpupgrade_host,
|
||||
headers = {
|
||||
["User-Agent"] = node.httpupgrade_user_agent or nil
|
||||
}
|
||||
headers = node.httpupgrade_user_agent and {
|
||||
["User-Agent"] = node.httpupgrade_user_agent
|
||||
} or nil
|
||||
} or nil,
|
||||
xhttpSettings = (node.transport == "xhttp") and {
|
||||
mode = node.xhttp_mode or "auto",
|
||||
|
||||
@@ -1,5 +1,10 @@
|
||||
<%+cbi/valueheader%>
|
||||
<%
|
||||
-- Template Developers:
|
||||
-- - lwb1978
|
||||
-- Copyright: copyright(c)2025–2027
|
||||
-- Description: Passwall(2) UI template
|
||||
|
||||
local cbid = "cbid." .. self.config .. "." .. section .. "." .. self.option
|
||||
|
||||
-- 读取 MultiValue
|
||||
@@ -41,9 +46,62 @@ for _, item in ipairs(values) do
|
||||
end
|
||||
%>
|
||||
|
||||
<div id="<%=cbid%>" class="cbi-input-select" style="display:inline-block;">
|
||||
<!-- 搜索 -->
|
||||
<input type="text" id="<%=cbid%>.search" class="node_search_input cbi-input-text" placeholder="<%:Search nodes...%>"
|
||||
style="width:100%;padding:6px;margin-bottom:8px;border:1px solid #ccc;border-radius:4px;box-sizing:border-box;max-height:36px;" />
|
||||
<!-- 主容器 -->
|
||||
<div style="max-height:300px;overflow:auto;margin-bottom:8px;white-space:nowrap;">
|
||||
<ul class="cbi-multi" id="<%=cbid%>.node_list" style="padding:0 !important;margin:0 !important;width:100%;box-sizing:border-box;">
|
||||
<% for _, gname in ipairs(group_order) do %>
|
||||
<% local items = groups[gname] %>
|
||||
<li class="group-block" data-group="<%=gname%>" style="list-style:none;padding:0;margin:0 0 8px 0;">
|
||||
<!-- 组标题 -->
|
||||
<div class="group-title" style="cursor:pointer;padding:6px;background:#f0f0f0;border-radius:4px;margin-bottom:4px;display:flex;align-items:center;white-space:nowrap;">
|
||||
<span id="arrow-<%=self.option%>-<%=gname%>" class="mv-arrow-down-small"></span>
|
||||
<b style="margin-left:8px;"><%=gname%></b>
|
||||
<span id="group-count-<%=self.option%>-<%=gname%>" style="margin-left:8px;color:#007bff;">
|
||||
(0/<%=#items%>)
|
||||
</span>
|
||||
</div>
|
||||
<!-- 组内容 -->
|
||||
<ul id="group-<%=self.option%>-<%=gname%>" style="margin:0 0 8px 16px;padding:0;list-style:none;">
|
||||
|
||||
<% for _, item in ipairs(items) do %>
|
||||
<li data-node-name="<%=pcdata(item.label):lower()%>" title="<%=pcdata(item.label)%>" style="list-style:none;padding:0;margin:0;white-space:nowrap;text-align:left;">
|
||||
<div style="display:inline-flex;align-items:center;vertical-align:middle;">
|
||||
<input type="checkbox" class="cbi-input-checkbox" style="vertical-align:middle;margin:0;margin-right:6px;"
|
||||
<%= attr("id", cbid .. "." .. item.key) ..
|
||||
attr("name", cbid) ..
|
||||
attr("value", item.key) ..
|
||||
ifattr(selected[item.key], "checked", "checked")
|
||||
%> />
|
||||
<label for="<%=cbid .. "." .. item.key%>" style="vertical-align:middle;margin:0;padding:0;"><%=pcdata(item.label)%></label>
|
||||
</div>
|
||||
</li>
|
||||
<% end %>
|
||||
</ul>
|
||||
</li>
|
||||
<% end %>
|
||||
</ul>
|
||||
</div>
|
||||
<!-- 控制栏 -->
|
||||
<div style="margin-top:4px;display:flex;gap:4px;align-items:center;">
|
||||
<input class="btn cbi-button cbi-button-edit" type="button" onclick="mv_selectAll('<%=cbid%>','<%=self.option%>',true)" value="<%:Select all%>">
|
||||
<input class="btn cbi-button cbi-button-edit" type="button" onclick="mv_selectAll('<%=cbid%>','<%=self.option%>',false)" value="<%:DeSelect all%>">
|
||||
<span id="count-<%=self.option%>" style="color:#666;"></span>
|
||||
</div>
|
||||
</div>
|
||||
<%+cbi/valuefooter%>
|
||||
|
||||
<%
|
||||
-- 公共部分(只加载一次)
|
||||
if not _G.__NODES_MULTIVALUE_CSS_JS__ then
|
||||
_G.__NODES_MULTIVALUE_CSS_JS__ = true
|
||||
%>
|
||||
<style>
|
||||
/* 组标题的右箭头(折叠) */
|
||||
.lv-arrow-right {
|
||||
/* 组标题的右箭头 */
|
||||
.mv-arrow-right {
|
||||
width: 0;
|
||||
height: 0;
|
||||
border-top: 4px solid transparent;
|
||||
@@ -52,9 +110,8 @@ end
|
||||
display: inline-block;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
/* 组标题的下箭头(展开) */
|
||||
.lv-arrow-down-small {
|
||||
/* 组标题的下箭头 */
|
||||
.mv-arrow-down-small {
|
||||
width: 0;
|
||||
height: 0;
|
||||
border-left: 4px solid transparent;
|
||||
@@ -65,120 +122,67 @@ end
|
||||
}
|
||||
</style>
|
||||
|
||||
<div id="<%=cbid%>" class="cbi-input-select" style="display: inline-block;">
|
||||
<!-- 搜索 -->
|
||||
<input type="text"
|
||||
id="<%=cbid%>.search"
|
||||
class="node-search-input cbi-input-text"
|
||||
placeholder="<%:Search nodes...%>"
|
||||
oninput="filterGroups_<%=self.option%>(this.value)"
|
||||
style="width:100%;padding:6px;margin-bottom:8px;border:1px solid #ccc;border-radius:4px;box-sizing:border-box;max-height:36px;" />
|
||||
<!-- 主容器 -->
|
||||
<div style="max-height:300px; overflow:auto; margin-bottom:8px; white-space:nowrap;">
|
||||
<ul class="cbi-multi" id="<%=cbid%>.node_list" style="padding:0 !important;margin:0 !important;width:100%;box-sizing:border-box;">
|
||||
<% for _, gname in ipairs(group_order) do %>
|
||||
<% local items = groups[gname] %>
|
||||
<li class="group-block" data-group="<%=gname%>" style="list-style:none; padding:0; margin:0 0 8px 0;">
|
||||
<!-- 组标题 -->
|
||||
<div class="group-title"
|
||||
onclick="toggleGroup_<%=self.option%>('<%=gname%>')"
|
||||
style="cursor:pointer;padding:6px;background:#f0f0f0;border-radius:4px;margin-bottom:4px;display:flex;align-items:center;white-space:nowrap;">
|
||||
<span id="arrow-<%=self.option%>-<%=gname%>" class="lv-arrow-down-small"></span>
|
||||
<b style="margin-left:8px;"><%=gname%></b>
|
||||
<span id="group-count-<%=self.option%>-<%=gname%>" style="margin-left:8px;color:#007bff;">
|
||||
(0/<%=#items%>)
|
||||
</span>
|
||||
</div>
|
||||
<!-- 组内容(可折叠)-->
|
||||
<ul id="group-<%=self.option%>-<%=gname%>" style="margin:0 0 8px 16px; padding:0; list-style:none;">
|
||||
|
||||
<% for _, item in ipairs(items) do %>
|
||||
<li data-node-name="<%=pcdata(item.label):lower()%>" style="list-style:none;padding:0;margin:0;white-space:nowrap;" title="<%=pcdata(item.label)%>">
|
||||
<input
|
||||
type="checkbox"
|
||||
class="cbi-input-checkbox"
|
||||
style="vertical-align: middle; margin-right:6px;"
|
||||
<%= attr("id", cbid .. "." .. item.key) ..
|
||||
attr("name", cbid) ..
|
||||
attr("value", item.key) ..
|
||||
ifattr(selected[item.key], "checked", "checked")
|
||||
%> />
|
||||
<label for="<%=cbid .. "." .. item.key%>"><%=pcdata(item.label)%></label>
|
||||
</li>
|
||||
<% end %>
|
||||
</ul>
|
||||
</li>
|
||||
<% end %>
|
||||
</ul>
|
||||
</div>
|
||||
<!-- 控制栏 -->
|
||||
<div style="margin-top:4px;display:flex;gap:4px;align-items:center;">
|
||||
<input class="btn cbi-button cbi-button-edit" type="button" onclick="selectAll_<%=self.option%>(true)" value="<%:Select all%>">
|
||||
<input class="btn cbi-button cbi-button-edit" type="button" onclick="selectAll_<%=self.option%>(false)" value="<%:DeSelect all%>">
|
||||
<span id="count-<%=self.option%>" style="color:#666;"></span>
|
||||
</div>
|
||||
</div>
|
||||
<%+cbi/valuefooter%>
|
||||
|
||||
<script type="text/javascript">
|
||||
//<![CDATA[
|
||||
(function(){
|
||||
const cbid = "<%=cbid%>";
|
||||
const opt = "<%=self.option%>";
|
||||
const listId = cbid + ".node_list";
|
||||
|
||||
// 折叠组
|
||||
window["toggleGroup_" + opt] = function(g){
|
||||
const ul = document.getElementById("group-" + opt + "-" + g);
|
||||
const arrow = document.getElementById("arrow-" + opt + "-" + g);
|
||||
function mv_toggleGroup(opt, nodeList, searchInput, g) {
|
||||
const ul = nodeList.querySelector("#group-" + opt + "-" + g);
|
||||
const arrow = nodeList.querySelector("#arrow-" + opt + "-" + g);
|
||||
if (!ul) return;
|
||||
// 判断是否在搜索状态
|
||||
const keyword = document.getElementById(cbid + ".search").value.trim().toLowerCase();
|
||||
const keyword = searchInput.value.trim().toLowerCase();
|
||||
const isSearching = keyword.length > 0;
|
||||
// 搜索状态下,仅切换当前组,不处理其他组
|
||||
if (isSearching) {
|
||||
if (ul.style.display === "none") {
|
||||
ul.style.display = "";
|
||||
if (arrow) arrow.className = "lv-arrow-down-small";
|
||||
} else {
|
||||
ul.style.display = "none";
|
||||
if (arrow) arrow.className = "lv-arrow-right";
|
||||
}
|
||||
if (isSearching){
|
||||
ul.style.display = ul.style.display === "none" ? "block" : "none";
|
||||
if (arrow) arrow.className = ul.style.display === "none" ? "mv-arrow-right" : "mv-arrow-down-small";
|
||||
return;
|
||||
}
|
||||
// 非搜索模式:先折叠其他组
|
||||
const groups = document.querySelectorAll("[id='" + listId + "'] .group-block");
|
||||
groups.forEach(group=>{
|
||||
nodeList.querySelectorAll(".group-block").forEach(group=>{
|
||||
const gname = group.getAttribute("data-group");
|
||||
const gul = document.getElementById("group-" + opt + "-" + gname);
|
||||
const garrow = document.getElementById("arrow-" + opt + "-" + gname);
|
||||
if (gname !== g) {
|
||||
if (gul) gul.style.display = "none";
|
||||
if (garrow) arrow.className = "lv-arrow-right";
|
||||
if (garrow) garrow.className = "mv-arrow-right";
|
||||
}
|
||||
});
|
||||
document.getElementById(listId).parentNode.scrollTop = 0;
|
||||
nodeList.parentNode.scrollTop = 0;
|
||||
// 切换当前组
|
||||
if (ul.style.display === "none") {
|
||||
ul.style.display = "";
|
||||
if (arrow) arrow.className = "lv-arrow-down-small";
|
||||
} else {
|
||||
ul.style.display = "none";
|
||||
if (arrow) arrow.className = "lv-arrow-right";
|
||||
}
|
||||
ul.style.display = ul.style.display === "none" ? "block" : "none";
|
||||
if (arrow) arrow.className = ul.style.display === "none" ? "mv-arrow-right" : "mv-arrow-down-small";
|
||||
};
|
||||
|
||||
// 计数
|
||||
function mv_updateCount(opt, nodeList) {
|
||||
// 当前实例下的所有 checkbox
|
||||
const cbs = nodeList.querySelectorAll("input[type=checkbox]");
|
||||
let checked = 0;
|
||||
cbs.forEach(cb => { if(cb.checked) checked++; });
|
||||
// 更新总计
|
||||
const totalSpan = document.getElementById("count-" + opt);
|
||||
if (totalSpan) {
|
||||
totalSpan.innerHTML = "<%:Selected:%> <span style='color:red;'>" + checked + " / " + cbs.length + "</span>";
|
||||
}
|
||||
// 更新每个组计数
|
||||
nodeList.querySelectorAll(".group-block").forEach(group => {
|
||||
const gname = group.getAttribute("data-group");
|
||||
const groupCbs = group.querySelectorAll("li[data-node-name] input[type=checkbox]");
|
||||
let groupChecked = 0;
|
||||
groupCbs.forEach(cb => { if(cb.checked) groupChecked++; });
|
||||
const span = document.getElementById("group-count-" + opt + "-" + gname);
|
||||
if(span) span.textContent = "(" + groupChecked + "/" + groupCbs.length + ")";
|
||||
});
|
||||
}
|
||||
|
||||
// 搜索
|
||||
window["filterGroups_" + opt] = function(keyword){
|
||||
keyword = keyword.toLowerCase().trim();
|
||||
|
||||
const groups = document.querySelectorAll("[id='" + listId + "'] .group-block");
|
||||
|
||||
groups.forEach(group=>{
|
||||
function mv_filterGroups(keyword, opt, nodeList) {
|
||||
keyword = (keyword || "").toLowerCase().trim();
|
||||
nodeList.querySelectorAll(".group-block").forEach(group => {
|
||||
const items = group.querySelectorAll("li[data-node-name]");
|
||||
let matchCount = 0;
|
||||
|
||||
items.forEach(li=>{
|
||||
items.forEach(li => {
|
||||
const name = li.getAttribute("data-node-name");
|
||||
if (!keyword || name.indexOf(keyword) !== -1) {
|
||||
li.style.display = "";
|
||||
@@ -187,7 +191,7 @@ end
|
||||
li.style.display = "none";
|
||||
}
|
||||
});
|
||||
// 搜索时自动展开所有组
|
||||
// 搜索时自动展开组
|
||||
const gname = group.getAttribute("data-group");
|
||||
const ul = document.getElementById("group-" + opt + "-" + gname);
|
||||
const arrow = document.getElementById("arrow-" + opt + "-" + gname);
|
||||
@@ -196,88 +200,71 @@ end
|
||||
group.style.display = "none";
|
||||
} else {
|
||||
group.style.display = "";
|
||||
if (keyword) {
|
||||
if (keyword && ul && arrow) {
|
||||
ul.style.display = "";
|
||||
arrow.className = "lv-arrow-down-small";
|
||||
arrow.className = "mv-arrow-down-small";
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
updateCount();
|
||||
|
||||
mv_updateCount(opt, nodeList);
|
||||
// 清空搜索后恢复全部折叠
|
||||
if (!keyword) {
|
||||
const groups = document.querySelectorAll("[id='" + listId + "'] .group-block");
|
||||
groups.forEach(group=>{
|
||||
const gname = group.getAttribute("data-group");
|
||||
const ul = document.getElementById("group-" + opt + "-" + gname);
|
||||
const arrow = document.getElementById("arrow-" + opt + "-" + gname);
|
||||
if (ul) ul.style.display = "none";
|
||||
if (arrow) arrow.className = "lv-arrow-right";
|
||||
});
|
||||
mv_collapseAllGroups(opt, nodeList);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// 全选 / 全不选
|
||||
window["selectAll_" + opt] = function(flag){
|
||||
const cbs = document.querySelectorAll("[id='" + listId + "'] input[type=checkbox]");
|
||||
function mv_selectAll(cbid, opt, flag) {
|
||||
const nodeList = document.getElementById(cbid + ".node_list");
|
||||
const cbs = nodeList.querySelectorAll("input[type=checkbox]");
|
||||
cbs.forEach(cb=>{
|
||||
if (cb.offsetParent !== null) cb.checked = flag;
|
||||
});
|
||||
updateCount();
|
||||
mv_updateCount(opt, nodeList);
|
||||
};
|
||||
|
||||
// 计数
|
||||
function updateCount(){
|
||||
const cbs = document.querySelectorAll("[id='" + listId + "'] input[type=checkbox]");
|
||||
let checked = 0;
|
||||
cbs.forEach(cb=>{ if (cb.checked) checked++; });
|
||||
// 更新总计
|
||||
document.getElementById("count-" + opt).innerHTML =
|
||||
"<%:Selected:%> <span style='color:red;'>" + checked + " / " + cbs.length + "</span>";
|
||||
|
||||
// 更新每个组
|
||||
const groups = document.querySelectorAll("[id='" + listId + "'] .group-block");
|
||||
groups.forEach(group=>{
|
||||
const gname = group.getAttribute("data-group");
|
||||
const groupCbs = group.querySelectorAll("li[data-node-name] input[type=checkbox]");
|
||||
let groupChecked = 0;
|
||||
groupCbs.forEach(cb=>{ if(cb.checked) groupChecked++; });
|
||||
const span = document.getElementById("group-count-" + opt + "-" + gname);
|
||||
if(span) span.textContent = "(" + groupChecked + "/" + groupCbs.length + ")";
|
||||
});
|
||||
}
|
||||
|
||||
document.getElementById(listId)?.addEventListener("change", updateCount);
|
||||
|
||||
// 初始化折叠所有组和计数
|
||||
const initObserver = new MutationObserver(() => {
|
||||
const list = document.getElementById(listId);
|
||||
if (!list) return;
|
||||
|
||||
if (list.offsetParent === null) return;
|
||||
|
||||
if (list.dataset.initDone === "1") return;
|
||||
list.dataset.initDone = "1";
|
||||
|
||||
const groups = document.querySelectorAll("[id='" + listId + "'] .group-block");
|
||||
groups.forEach(group => {
|
||||
// 折叠所有组
|
||||
function mv_collapseAllGroups(opt, nodeList) {
|
||||
nodeList.querySelectorAll(".group-block").forEach(group => {
|
||||
const gname = group.getAttribute("data-group");
|
||||
const ul = document.getElementById("group-" + opt + "-" + gname);
|
||||
const arrow = document.getElementById("arrow-" + opt + "-" + gname);
|
||||
if (ul) ul.style.display = "none";
|
||||
if (arrow) arrow.className = "lv-arrow-right";
|
||||
if (arrow) arrow.className = "mv-arrow-right";
|
||||
});
|
||||
}
|
||||
//]]>
|
||||
</script>
|
||||
<% end %>
|
||||
|
||||
updateCount();
|
||||
<script type="text/javascript">
|
||||
//<![CDATA[
|
||||
(function(){
|
||||
const cbid = "<%=cbid%>";
|
||||
const opt = "<%=self.option%>";
|
||||
const searchInput = document.getElementById(cbid + ".search");
|
||||
const nodeList = document.getElementById(cbid + ".node_list");
|
||||
|
||||
nodeList.querySelectorAll(".group-title").forEach(title => {
|
||||
title.addEventListener("click", function() {
|
||||
const g = this.closest(".group-block")?.getAttribute("data-group");
|
||||
if (g) mv_toggleGroup(opt, nodeList, searchInput, g);
|
||||
});
|
||||
});
|
||||
|
||||
initObserver.observe(document.body, {
|
||||
attributes: true,
|
||||
subtree: true,
|
||||
attributeFilter: ["style", "class"]
|
||||
searchInput.addEventListener("input", function() {
|
||||
mv_filterGroups(this.value, opt, nodeList);
|
||||
})
|
||||
|
||||
// checkbox 改变时更新计数
|
||||
nodeList.addEventListener("change", () => {
|
||||
mv_updateCount(opt, nodeList);
|
||||
});
|
||||
|
||||
// 初始化折叠所有组和计数
|
||||
mv_collapseAllGroups(opt, nodeList)
|
||||
mv_updateCount(opt, nodeList);
|
||||
|
||||
})();
|
||||
//]]>
|
||||
</script>
|
||||
|
||||
@@ -7,7 +7,7 @@ jobs:
|
||||
stale:
|
||||
runs-on: ubuntu-22.04
|
||||
steps:
|
||||
- uses: actions/stale@v7.0.0
|
||||
- uses: actions/stale@v10
|
||||
with:
|
||||
stale-issue-message: "Stale Issue"
|
||||
stale-pr-message: "Stale PR"
|
||||
|
||||
216
sing-box/.github/workflows/build.yml
vendored
216
sing-box/.github/workflows/build.yml
vendored
@@ -62,20 +62,22 @@ jobs:
|
||||
echo "version=$version" >> "$GITHUB_OUTPUT"
|
||||
build:
|
||||
name: Build binary
|
||||
if: github.event_name != 'workflow_dispatch' || inputs.build == 'All' || inputs.build == 'Binary'
|
||||
if: false # TODO: temporarily disabled for testing
|
||||
runs-on: ubuntu-latest
|
||||
needs:
|
||||
- calculate_version
|
||||
strategy:
|
||||
matrix:
|
||||
include:
|
||||
- { os: linux, arch: amd64, debian: amd64, rpm: x86_64, pacman: x86_64, openwrt: "x86_64" }
|
||||
- { os: linux, arch: "386", go386: sse2, debian: i386, rpm: i386, openwrt: "i386_pentium4" }
|
||||
# Linux with naive outbound (CGO enabled with Debian Bullseye sysroot)
|
||||
- { os: linux, arch: amd64, naive: true, debian: amd64, rpm: x86_64, pacman: x86_64, openwrt: "x86_64", sysroot_sha: "36a164623d03f525e3dfb783a5e9b8a00e98e1ddd2b5cff4e449bd016dd27e50", cc_target: "x86_64-linux-gnu" }
|
||||
- { os: linux, arch: arm64, naive: true, debian: arm64, rpm: aarch64, pacman: aarch64, openwrt: "aarch64_cortex-a53 aarch64_cortex-a72 aarch64_cortex-a76 aarch64_generic", sysroot_sha: "2f915d821eec27515c0c6d21b69898e23762908d8d7ccc1aa2a8f5f25e8b7e18", cc_target: "aarch64-linux-gnu", cross_pkg: "libc6-dev-arm64-cross" }
|
||||
- { os: linux, arch: "386", naive: true, go386: sse2, debian: i386, rpm: i386, openwrt: "i386_pentium4", sysroot_sha: "63f0e5128b84f7b0421956a4a40affa472be8da0e58caf27e9acbc84072daee7", cc_target: "i686-linux-gnu", cross_pkg: "libc6-dev-i386-cross" }
|
||||
- { os: linux, arch: arm, naive: true, goarm: "7", debian: armhf, rpm: armv7hl, pacman: armv7hl, openwrt: "arm_cortex-a5_vfpv4 arm_cortex-a7_neon-vfpv4 arm_cortex-a7_vfpv4 arm_cortex-a8_vfpv3 arm_cortex-a9_neon arm_cortex-a9_vfpv3-d16 arm_cortex-a15_neon-vfpv4", sysroot_sha: "47b3a0b161ca011b2b33d4fc1ef6ef269b8208a0b7e4c900700c345acdfd1814", cc_target: "arm-linux-gnueabihf", cross_pkg: "libc6-dev-armhf-cross", linker: "bfd" }
|
||||
# Linux without naive outbound (no CGO)
|
||||
- { os: linux, arch: "386", go386: softfloat, openwrt: "i386_pentium-mmx" }
|
||||
- { os: linux, arch: arm64, debian: arm64, rpm: aarch64, pacman: aarch64, openwrt: "aarch64_cortex-a53 aarch64_cortex-a72 aarch64_cortex-a76 aarch64_generic" }
|
||||
- { os: linux, arch: arm, goarm: "5", openwrt: "arm_arm926ej-s arm_cortex-a7 arm_cortex-a9 arm_fa526 arm_xscale" }
|
||||
- { os: linux, arch: arm, goarm: "6", debian: armel, rpm: armv6hl, openwrt: "arm_arm1176jzf-s_vfp" }
|
||||
- { os: linux, arch: arm, goarm: "7", debian: armhf, rpm: armv7hl, pacman: armv7hl, openwrt: "arm_cortex-a5_vfpv4 arm_cortex-a7_neon-vfpv4 arm_cortex-a7_vfpv4 arm_cortex-a8_vfpv3 arm_cortex-a9_neon arm_cortex-a9_vfpv3-d16 arm_cortex-a15_neon-vfpv4" }
|
||||
- { os: linux, arch: mips, gomips: softfloat, openwrt: "mips_24kc mips_4kec mips_mips32" }
|
||||
- { os: linux, arch: mipsle, gomips: hardfloat, debian: mipsel, rpm: mipsel, openwrt: "mipsel_24kc_24kf" }
|
||||
- { os: linux, arch: mipsle, gomips: softfloat, openwrt: "mipsel_24kc mipsel_74kc mipsel_mips32" }
|
||||
@@ -86,13 +88,10 @@ jobs:
|
||||
- { os: linux, arch: ppc64le, debian: ppc64el, rpm: ppc64le }
|
||||
- { os: linux, arch: riscv64, debian: riscv64, rpm: riscv64, openwrt: "riscv64_generic" }
|
||||
- { os: linux, arch: loong64, debian: loongarch64, rpm: loongarch64, openwrt: "loongarch64_generic" }
|
||||
|
||||
- { os: windows, arch: amd64 }
|
||||
# Windows 7 legacy (no naive, no CGO)
|
||||
- { os: windows, arch: amd64, legacy_win7: true, legacy_name: "windows-7" }
|
||||
- { os: windows, arch: "386" }
|
||||
- { os: windows, arch: "386", legacy_win7: true, legacy_name: "windows-7" }
|
||||
- { os: windows, arch: arm64 }
|
||||
|
||||
# Android (naive enabled)
|
||||
- { os: android, arch: arm64, ndk: "aarch64-linux-android21" }
|
||||
- { os: android, arch: arm, ndk: "armv7a-linux-androideabi21" }
|
||||
- { os: android, arch: amd64, ndk: "x86_64-linux-android21" }
|
||||
@@ -135,6 +134,19 @@ jobs:
|
||||
with:
|
||||
ndk-version: r28
|
||||
local-cache: true
|
||||
- name: Download sysroot (Linux naive)
|
||||
if: matrix.naive
|
||||
run: |
|
||||
set -xeuo pipefail
|
||||
wget -q "https://commondatastorage.googleapis.com/chrome-linux-sysroot/${{ matrix.sysroot_sha }}" -O sysroot.tar.xz
|
||||
mkdir -p /tmp/sysroot
|
||||
tar -xf sysroot.tar.xz -C /tmp/sysroot
|
||||
- name: Install cross compiler (Linux naive)
|
||||
if: matrix.naive
|
||||
run: |
|
||||
set -xeuo pipefail
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y clang lld ${{ matrix.cross_pkg }}
|
||||
- name: Set tag
|
||||
run: |-
|
||||
git ls-remote --exit-code --tags origin v${{ needs.calculate_version.outputs.version }} || echo "PUBLISHED=false" >> "$GITHUB_ENV"
|
||||
@@ -143,12 +155,12 @@ jobs:
|
||||
run: |
|
||||
set -xeuo pipefail
|
||||
TAGS='with_gvisor,with_quic,with_dhcp,with_wireguard,with_utls,with_acme,with_clash_api,with_tailscale,with_ccm,badlinkname,tfogo_checklinkname0'
|
||||
if [[ "${{ matrix.os }}" == "android" ]]; then
|
||||
if [[ "${{ matrix.naive }}" == "true" ]] || [[ "${{ matrix.os }}" == "android" ]]; then
|
||||
TAGS="${TAGS},with_naive_outbound"
|
||||
fi
|
||||
echo "BUILD_TAGS=${TAGS}" >> "${GITHUB_ENV}"
|
||||
- name: Build
|
||||
if: matrix.os != 'android'
|
||||
if: matrix.os != 'android' && ! matrix.naive
|
||||
run: |
|
||||
set -xeuo pipefail
|
||||
mkdir -p dist
|
||||
@@ -164,6 +176,24 @@ jobs:
|
||||
GOMIPS: ${{ matrix.gomips }}
|
||||
GOMIPS64: ${{ matrix.gomips }}
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
- name: Build Linux with naive
|
||||
if: matrix.naive
|
||||
run: |
|
||||
set -xeuo pipefail
|
||||
mkdir -p dist
|
||||
go build -v -trimpath -o dist/sing-box -tags "${BUILD_TAGS}" \
|
||||
-ldflags "-s -buildid= -X github.com/sagernet/sing-box/constant.Version=${{ needs.calculate_version.outputs.version }} -checklinkname=0 -linkmode=external -extldflags \"-fuse-ld=${LINKER} --sysroot=/tmp/sysroot\"" \
|
||||
./cmd/sing-box
|
||||
env:
|
||||
CGO_ENABLED: "1"
|
||||
GOOS: linux
|
||||
GOARCH: ${{ matrix.arch }}
|
||||
GO386: ${{ matrix.go386 }}
|
||||
GOARM: ${{ matrix.goarm }}
|
||||
CC: clang --target=${{ matrix.cc_target }} --sysroot=/tmp/sysroot
|
||||
CXX: clang++ --target=${{ matrix.cc_target }} --sysroot=/tmp/sysroot
|
||||
LINKER: ${{ matrix.linker || 'lld' }}
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
- name: Build Android
|
||||
if: matrix.os == 'android'
|
||||
run: |
|
||||
@@ -286,7 +316,7 @@ jobs:
|
||||
path: "dist"
|
||||
build_darwin:
|
||||
name: Build Darwin binaries
|
||||
if: github.event_name != 'workflow_dispatch' || inputs.build == 'All' || inputs.build == 'Binary'
|
||||
if: false # TODO: temporarily disabled for testing
|
||||
runs-on: macos-latest
|
||||
needs:
|
||||
- calculate_version
|
||||
@@ -318,7 +348,10 @@ jobs:
|
||||
- name: Set build tags
|
||||
run: |
|
||||
set -xeuo pipefail
|
||||
TAGS='with_gvisor,with_quic,with_dhcp,with_wireguard,with_utls,with_acme,with_clash_api,with_tailscale,with_ccm,with_naive_outbound,badlinkname,tfogo_checklinkname0'
|
||||
TAGS='with_gvisor,with_quic,with_dhcp,with_wireguard,with_utls,with_acme,with_clash_api,with_tailscale,with_ccm,badlinkname,tfogo_checklinkname0'
|
||||
if [[ "${{ matrix.legacy_go124 }}" != "true" ]]; then
|
||||
TAGS="${TAGS},with_naive_outbound"
|
||||
fi
|
||||
echo "BUILD_TAGS=${TAGS}" >> "${GITHUB_ENV}"
|
||||
- name: Build
|
||||
run: |
|
||||
@@ -355,25 +388,93 @@ jobs:
|
||||
with:
|
||||
name: binary-darwin_${{ matrix.arch }}${{ matrix.legacy_name && format('-legacy-{0}', matrix.legacy_name) }}
|
||||
path: "dist"
|
||||
build_naive_linux:
|
||||
name: Build Linux with naive outbound
|
||||
build_windows:
|
||||
name: Build Windows binaries
|
||||
if: github.event_name != 'workflow_dispatch' || inputs.build == 'All' || inputs.build == 'Binary'
|
||||
runs-on: windows-latest
|
||||
needs:
|
||||
- calculate_version
|
||||
strategy:
|
||||
matrix:
|
||||
include:
|
||||
- { arch: amd64, cc: x86_64-w64-mingw32-clang }
|
||||
- { arch: "386", cc: i686-w64-mingw32-clang }
|
||||
- { arch: arm64, cc: aarch64-w64-mingw32-clang }
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- name: Setup Go
|
||||
uses: actions/setup-go@v5
|
||||
with:
|
||||
go-version: ^1.25.4
|
||||
- name: Cache llvm-mingw
|
||||
id: cache-llvm-mingw
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: ${{ runner.temp }}/llvm-mingw
|
||||
key: llvm-mingw-ucrt-x86_64
|
||||
- name: Setup llvm-mingw
|
||||
if: steps.cache-llvm-mingw.outputs.cache-hit != 'true'
|
||||
run: |
|
||||
$headers = @{ Authorization = "Bearer $env:GITHUB_TOKEN" }
|
||||
$release = Invoke-RestMethod -Uri "https://api.github.com/repos/mstorsjo/llvm-mingw/releases/latest" -Headers $headers
|
||||
$asset = $release.assets | Where-Object { $_.name -like "llvm-mingw-*-ucrt-x86_64.zip" }
|
||||
curl -Lo llvm-mingw.zip $asset.browser_download_url
|
||||
Expand-Archive llvm-mingw.zip -DestinationPath $env:RUNNER_TEMP/llvm-mingw
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
- name: Setup llvm-mingw PATH
|
||||
run: |
|
||||
$extractedDir = Get-ChildItem -Path $env:RUNNER_TEMP/llvm-mingw -Directory | Where-Object { $_.Name -like "llvm-mingw-*" } | Select-Object -First 1
|
||||
echo "$($extractedDir.FullName)\bin" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append
|
||||
- name: Set tag
|
||||
run: |-
|
||||
git ls-remote --exit-code --tags origin v${{ needs.calculate_version.outputs.version }} || echo "PUBLISHED=false" >> "$env:GITHUB_ENV"
|
||||
git tag v${{ needs.calculate_version.outputs.version }} -f
|
||||
- name: Build
|
||||
run: |
|
||||
mkdir -p dist
|
||||
go build -v -trimpath -o dist/sing-box.exe -tags "with_gvisor,with_quic,with_dhcp,with_wireguard,with_utls,with_acme,with_clash_api,with_tailscale,with_ccm,with_naive_outbound,badlinkname,tfogo_checklinkname0" `
|
||||
-ldflags "-s -buildid= -X github.com/sagernet/sing-box/constant.Version=${{ needs.calculate_version.outputs.version }} -checklinkname=0" `
|
||||
./cmd/sing-box
|
||||
env:
|
||||
CGO_ENABLED: "1"
|
||||
CGO_LDFLAGS_ALLOW: "-Wl,-Xlink=.*"
|
||||
GOOS: windows
|
||||
GOARCH: ${{ matrix.arch }}
|
||||
CC: ${{ matrix.cc }}
|
||||
CXX: ${{ matrix.cc }}++
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
- name: Archive
|
||||
run: |
|
||||
$DIR_NAME = "sing-box-${{ needs.calculate_version.outputs.version }}-windows-${{ matrix.arch }}"
|
||||
mkdir "dist/$DIR_NAME"
|
||||
Copy-Item LICENSE "dist/$DIR_NAME"
|
||||
Copy-Item "dist/sing-box.exe" "dist/$DIR_NAME"
|
||||
Compress-Archive -Path "dist/$DIR_NAME" -DestinationPath "dist/$DIR_NAME.zip"
|
||||
Remove-Item -Recurse "dist/$DIR_NAME"
|
||||
- name: Cleanup
|
||||
run: Remove-Item dist/sing-box.exe
|
||||
- name: Upload artifact
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: binary-windows_${{ matrix.arch }}
|
||||
path: "dist"
|
||||
build_linux_musl:
|
||||
name: Build Linux musl static binaries
|
||||
if: false # TODO: temporarily disabled for testing
|
||||
runs-on: ubuntu-latest
|
||||
needs:
|
||||
- calculate_version
|
||||
strategy:
|
||||
matrix:
|
||||
include:
|
||||
# Linux glibc (dynamic linking with Debian Bullseye sysroot)
|
||||
- { arch: amd64, sysroot_arch: amd64, sysroot_sha: "36a164623d03f525e3dfb783a5e9b8a00e98e1ddd2b5cff4e449bd016dd27e50", cc_target: "x86_64-linux-gnu", suffix: "-naive" }
|
||||
- { arch: arm64, sysroot_arch: arm64, sysroot_sha: "2f915d821eec27515c0c6d21b69898e23762908d8d7ccc1aa2a8f5f25e8b7e18", cc_target: "aarch64-linux-gnu", suffix: "-naive" }
|
||||
- { arch: "386", sysroot_arch: i386, sysroot_sha: "63f0e5128b84f7b0421956a4a40affa472be8da0e58caf27e9acbc84072daee7", cc_target: "i686-linux-gnu", suffix: "-naive" }
|
||||
- { arch: arm, goarm: "7", sysroot_arch: armhf, sysroot_sha: "47b3a0b161ca011b2b33d4fc1ef6ef269b8208a0b7e4c900700c345acdfd1814", cc_target: "arm-linux-gnueabihf", suffix: "-naive" }
|
||||
# Linux musl (static linking)
|
||||
- { arch: amd64, musl: true, cc_target: "x86_64-linux-musl", suffix: "-naive-musl" }
|
||||
- { arch: arm64, musl: true, cc_target: "aarch64-linux-musl", suffix: "-naive-musl" }
|
||||
- { arch: "386", musl: true, cc_target: "i686-linux-musl", suffix: "-naive-musl" }
|
||||
- { arch: arm, goarm: "7", musl: true, cc_target: "arm-linux-musleabihf", suffix: "-naive-musl" }
|
||||
- { arch: amd64, cc_target: "x86_64-linux-musl" }
|
||||
- { arch: arm64, cc_target: "aarch64-linux-musl" }
|
||||
- { arch: "386", cc_target: "i686-linux-musl" }
|
||||
- { arch: arm, goarm: "7", cc_target: "arm-linux-musleabihf" }
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5
|
||||
@@ -387,62 +488,16 @@ jobs:
|
||||
run: |-
|
||||
git ls-remote --exit-code --tags origin v${{ needs.calculate_version.outputs.version }} || echo "PUBLISHED=false" >> "$GITHUB_ENV"
|
||||
git tag v${{ needs.calculate_version.outputs.version }} -f
|
||||
- name: Download sysroot (glibc)
|
||||
if: ${{ ! matrix.musl }}
|
||||
run: |
|
||||
set -xeuo pipefail
|
||||
wget -q "https://commondatastorage.googleapis.com/chrome-linux-sysroot/${{ matrix.sysroot_sha }}" -O sysroot.tar.xz
|
||||
mkdir -p /tmp/sysroot
|
||||
tar -xf sysroot.tar.xz -C /tmp/sysroot
|
||||
- name: Install cross compiler (glibc)
|
||||
if: ${{ ! matrix.musl }}
|
||||
run: |
|
||||
set -xeuo pipefail
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y clang lld
|
||||
if [[ "${{ matrix.arch }}" == "arm64" ]]; then
|
||||
sudo apt-get install -y libc6-dev-arm64-cross
|
||||
elif [[ "${{ matrix.arch }}" == "386" ]]; then
|
||||
sudo apt-get install -y libc6-dev-i386-cross
|
||||
elif [[ "${{ matrix.arch }}" == "arm" ]]; then
|
||||
sudo apt-get install -y libc6-dev-armhf-cross
|
||||
fi
|
||||
- name: Install musl cross compiler
|
||||
if: matrix.musl
|
||||
run: |
|
||||
set -xeuo pipefail
|
||||
.github/setup_musl_cross.sh "${{ matrix.cc_target }}"
|
||||
echo "PATH=$HOME/musl-cross/bin:$PATH" >> $GITHUB_ENV
|
||||
- name: Set build tags
|
||||
run: |
|
||||
set -xeuo pipefail
|
||||
TAGS='with_gvisor,with_quic,with_dhcp,with_wireguard,with_utls,with_acme,with_clash_api,with_tailscale,with_ccm,with_naive_outbound,badlinkname,tfogo_checklinkname0'
|
||||
if [[ "${{ matrix.musl }}" == "true" ]]; then
|
||||
TAGS="${TAGS},with_musl"
|
||||
fi
|
||||
echo "BUILD_TAGS=${TAGS}" >> "${GITHUB_ENV}"
|
||||
- name: Build (glibc)
|
||||
if: ${{ ! matrix.musl }}
|
||||
- name: Build
|
||||
run: |
|
||||
set -xeuo pipefail
|
||||
mkdir -p dist
|
||||
go build -v -trimpath -o dist/sing-box -tags "${BUILD_TAGS}" \
|
||||
-ldflags '-s -buildid= -X github.com/sagernet/sing-box/constant.Version=${{ needs.calculate_version.outputs.version }} -checklinkname=0 -linkmode=external -extldflags "-fuse-ld=lld --sysroot=/tmp/sysroot"' \
|
||||
./cmd/sing-box
|
||||
env:
|
||||
CGO_ENABLED: "1"
|
||||
GOOS: linux
|
||||
GOARCH: ${{ matrix.arch }}
|
||||
GOARM: ${{ matrix.goarm }}
|
||||
CC: "clang --target=${{ matrix.cc_target }} --sysroot=/tmp/sysroot"
|
||||
CXX: "clang++ --target=${{ matrix.cc_target }} --sysroot=/tmp/sysroot"
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
- name: Build (musl)
|
||||
if: matrix.musl
|
||||
run: |
|
||||
set -xeuo pipefail
|
||||
mkdir -p dist
|
||||
go build -v -trimpath -o dist/sing-box -tags "${BUILD_TAGS}" \
|
||||
go build -v -trimpath -o dist/sing-box -tags 'with_gvisor,with_quic,with_dhcp,with_wireguard,with_utls,with_acme,with_clash_api,with_tailscale,with_ccm,with_naive_outbound,with_musl,badlinkname,tfogo_checklinkname0' \
|
||||
-ldflags '-s -buildid= -X github.com/sagernet/sing-box/constant.Version=${{ needs.calculate_version.outputs.version }} -checklinkname=0 -linkmode=external -extldflags "-static"' \
|
||||
./cmd/sing-box
|
||||
env:
|
||||
@@ -459,7 +514,7 @@ jobs:
|
||||
if [[ -n "${{ matrix.goarm }}" ]]; then
|
||||
DIR_NAME="${DIR_NAME}v${{ matrix.goarm }}"
|
||||
fi
|
||||
DIR_NAME="${DIR_NAME}${{ matrix.suffix }}"
|
||||
DIR_NAME="${DIR_NAME}-musl"
|
||||
echo "DIR_NAME=${DIR_NAME}" >> "${GITHUB_ENV}"
|
||||
- name: Archive
|
||||
run: |
|
||||
@@ -475,11 +530,11 @@ jobs:
|
||||
- name: Upload artifact
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: binary-linux_${{ matrix.arch }}${{ matrix.goarm && format('v{0}', matrix.goarm) }}${{ matrix.suffix }}
|
||||
name: binary-linux_${{ matrix.arch }}${{ matrix.goarm && format('v{0}', matrix.goarm) }}-musl
|
||||
path: "dist"
|
||||
build_android:
|
||||
name: Build Android
|
||||
if: github.event_name != 'workflow_dispatch' || inputs.build == 'All' || inputs.build == 'Android'
|
||||
if: false # TODO: temporarily disabled for testing
|
||||
runs-on: ubuntu-latest
|
||||
needs:
|
||||
- calculate_version
|
||||
@@ -559,7 +614,7 @@ jobs:
|
||||
path: 'dist'
|
||||
publish_android:
|
||||
name: Publish Android
|
||||
if: github.event_name == 'workflow_dispatch' && inputs.build == 'publish-android'
|
||||
if: false # TODO: temporarily disabled for testing
|
||||
runs-on: ubuntu-latest
|
||||
needs:
|
||||
- calculate_version
|
||||
@@ -806,13 +861,14 @@ jobs:
|
||||
path: 'dist'
|
||||
upload:
|
||||
name: Upload builds
|
||||
if: "!failure() && github.event_name == 'workflow_dispatch' && (inputs.build == 'All' || inputs.build == 'Binary' || inputs.build == 'Android' || inputs.build == 'Apple' || inputs.build == 'macOS-standalone')"
|
||||
if: false # TODO: temporarily disabled for testing
|
||||
runs-on: ubuntu-latest
|
||||
needs:
|
||||
- calculate_version
|
||||
- build
|
||||
- build_darwin
|
||||
- build_naive_linux
|
||||
- build_windows
|
||||
- build_linux_musl
|
||||
- build_android
|
||||
- build_apple
|
||||
steps:
|
||||
|
||||
@@ -25,8 +25,8 @@ require (
|
||||
github.com/sagernet/asc-go v0.0.0-20241217030726-d563060fe4e1
|
||||
github.com/sagernet/bbolt v0.0.0-20231014093535-ea5cb2fe9f0a
|
||||
github.com/sagernet/cors v1.2.1
|
||||
github.com/sagernet/cronet-go v0.0.0-20251209163619-43499a42c286
|
||||
github.com/sagernet/cronet-go/all v0.0.0-20251209163943-9ad85d71d2e3
|
||||
github.com/sagernet/cronet-go v0.0.0-20251210132647-15dd6a9ee4bc
|
||||
github.com/sagernet/cronet-go/all v0.0.0-20251210133029-b0d1058a9fcf
|
||||
github.com/sagernet/fswatch v0.1.1
|
||||
github.com/sagernet/gomobile v0.1.8
|
||||
github.com/sagernet/gvisor v0.0.0-20250811.0-sing-box-mod.1
|
||||
@@ -106,24 +106,24 @@ require (
|
||||
github.com/prometheus-community/pro-bing v0.4.0 // indirect
|
||||
github.com/quic-go/qpack v0.6.0 // indirect
|
||||
github.com/safchain/ethtool v0.3.0 // indirect
|
||||
github.com/sagernet/cronet-go/lib/android_386 v0.0.0-20251209163619-43499a42c286 // indirect
|
||||
github.com/sagernet/cronet-go/lib/android_amd64 v0.0.0-20251209163619-43499a42c286 // indirect
|
||||
github.com/sagernet/cronet-go/lib/android_arm v0.0.0-20251209163619-43499a42c286 // indirect
|
||||
github.com/sagernet/cronet-go/lib/android_arm64 v0.0.0-20251209163619-43499a42c286 // indirect
|
||||
github.com/sagernet/cronet-go/lib/darwin_amd64 v0.0.0-20251209163619-43499a42c286 // indirect
|
||||
github.com/sagernet/cronet-go/lib/darwin_arm64 v0.0.0-20251209163619-43499a42c286 // indirect
|
||||
github.com/sagernet/cronet-go/lib/ios_arm64 v0.0.0-20251209163619-43499a42c286 // indirect
|
||||
github.com/sagernet/cronet-go/lib/linux_386 v0.0.0-20251209163619-43499a42c286 // indirect
|
||||
github.com/sagernet/cronet-go/lib/linux_386_musl v0.0.0-20251209163619-43499a42c286 // indirect
|
||||
github.com/sagernet/cronet-go/lib/linux_amd64 v0.0.0-20251209163619-43499a42c286 // indirect
|
||||
github.com/sagernet/cronet-go/lib/linux_amd64_musl v0.0.0-20251209163619-43499a42c286 // indirect
|
||||
github.com/sagernet/cronet-go/lib/linux_arm v0.0.0-20251209163619-43499a42c286 // indirect
|
||||
github.com/sagernet/cronet-go/lib/linux_arm64 v0.0.0-20251209163619-43499a42c286 // indirect
|
||||
github.com/sagernet/cronet-go/lib/linux_arm64_musl v0.0.0-20251209163619-43499a42c286 // indirect
|
||||
github.com/sagernet/cronet-go/lib/linux_arm_musl v0.0.0-20251209163619-43499a42c286 // indirect
|
||||
github.com/sagernet/cronet-go/lib/windows_386 v0.0.0-20251209163619-43499a42c286 // indirect
|
||||
github.com/sagernet/cronet-go/lib/windows_amd64 v0.0.0-20251209163619-43499a42c286 // indirect
|
||||
github.com/sagernet/cronet-go/lib/windows_arm64 v0.0.0-20251209163619-43499a42c286 // indirect
|
||||
github.com/sagernet/cronet-go/lib/android_386 v0.0.0-20251210132647-15dd6a9ee4bc // indirect
|
||||
github.com/sagernet/cronet-go/lib/android_amd64 v0.0.0-20251210132647-15dd6a9ee4bc // indirect
|
||||
github.com/sagernet/cronet-go/lib/android_arm v0.0.0-20251210132647-15dd6a9ee4bc // indirect
|
||||
github.com/sagernet/cronet-go/lib/android_arm64 v0.0.0-20251210132647-15dd6a9ee4bc // indirect
|
||||
github.com/sagernet/cronet-go/lib/darwin_amd64 v0.0.0-20251210132647-15dd6a9ee4bc // indirect
|
||||
github.com/sagernet/cronet-go/lib/darwin_arm64 v0.0.0-20251210132647-15dd6a9ee4bc // indirect
|
||||
github.com/sagernet/cronet-go/lib/ios_arm64 v0.0.0-20251210132647-15dd6a9ee4bc // indirect
|
||||
github.com/sagernet/cronet-go/lib/linux_386 v0.0.0-20251210132647-15dd6a9ee4bc // indirect
|
||||
github.com/sagernet/cronet-go/lib/linux_386_musl v0.0.0-20251210132647-15dd6a9ee4bc // indirect
|
||||
github.com/sagernet/cronet-go/lib/linux_amd64 v0.0.0-20251210132647-15dd6a9ee4bc // indirect
|
||||
github.com/sagernet/cronet-go/lib/linux_amd64_musl v0.0.0-20251210132647-15dd6a9ee4bc // indirect
|
||||
github.com/sagernet/cronet-go/lib/linux_arm v0.0.0-20251210132647-15dd6a9ee4bc // indirect
|
||||
github.com/sagernet/cronet-go/lib/linux_arm64 v0.0.0-20251210132647-15dd6a9ee4bc // indirect
|
||||
github.com/sagernet/cronet-go/lib/linux_arm64_musl v0.0.0-20251210132647-15dd6a9ee4bc // indirect
|
||||
github.com/sagernet/cronet-go/lib/linux_arm_musl v0.0.0-20251210132647-15dd6a9ee4bc // indirect
|
||||
github.com/sagernet/cronet-go/lib/windows_386 v0.0.0-20251210132647-15dd6a9ee4bc // indirect
|
||||
github.com/sagernet/cronet-go/lib/windows_amd64 v0.0.0-20251210132647-15dd6a9ee4bc // indirect
|
||||
github.com/sagernet/cronet-go/lib/windows_arm64 v0.0.0-20251210132647-15dd6a9ee4bc // indirect
|
||||
github.com/sagernet/netlink v0.0.0-20240612041022-b9a21c07ac6a // indirect
|
||||
github.com/sagernet/nftables v0.3.0-beta.4 // indirect
|
||||
github.com/spf13/pflag v1.0.6 // indirect
|
||||
|
||||
@@ -150,46 +150,46 @@ github.com/sagernet/bbolt v0.0.0-20231014093535-ea5cb2fe9f0a h1:+NkI2670SQpQWvkk
|
||||
github.com/sagernet/bbolt v0.0.0-20231014093535-ea5cb2fe9f0a/go.mod h1:63s7jpZqcDAIpj8oI/1v4Izok+npJOHACFCU6+huCkM=
|
||||
github.com/sagernet/cors v1.2.1 h1:Cv5Z8y9YSD6Gm+qSpNrL3LO4lD3eQVvbFYJSG7JCMHQ=
|
||||
github.com/sagernet/cors v1.2.1/go.mod h1:O64VyOjjhrkLmQIjF4KGRrJO/5dVXFdpEmCW/eISRAI=
|
||||
github.com/sagernet/cronet-go v0.0.0-20251209163619-43499a42c286 h1:T3l7r/FRNyf6AS1ZZfvFMYtTCozKWgm/mNXjmg/HqOw=
|
||||
github.com/sagernet/cronet-go v0.0.0-20251209163619-43499a42c286/go.mod h1:l5IZJLEWpDGJbrF0qBHgxAVBPsAxKOLa1BYDh6B2sdI=
|
||||
github.com/sagernet/cronet-go/all v0.0.0-20251209163943-9ad85d71d2e3 h1:a6/HHQ2bBrX4humT9jSACAD9kj4ucgal5tYWjOpxsXA=
|
||||
github.com/sagernet/cronet-go/all v0.0.0-20251209163943-9ad85d71d2e3/go.mod h1:bq4r/IRzbgNUWfcWxJTyex/jKzI6WCSPfrCK3ns4O3A=
|
||||
github.com/sagernet/cronet-go/lib/android_386 v0.0.0-20251209163619-43499a42c286 h1:sZFASnzhbYtPJoz+7OAx7IC85161iROwEkmHVQcaHS0=
|
||||
github.com/sagernet/cronet-go/lib/android_386 v0.0.0-20251209163619-43499a42c286/go.mod h1:XXDwdjX/T8xftoeJxQmbBoYXZp8MAPFR2CwbFuTpEtw=
|
||||
github.com/sagernet/cronet-go/lib/android_amd64 v0.0.0-20251209163619-43499a42c286 h1:XmPpSRMDde4Oi5XzYBuOqWAvzPQsNjmKQfft98OlvLg=
|
||||
github.com/sagernet/cronet-go/lib/android_amd64 v0.0.0-20251209163619-43499a42c286/go.mod h1:iNiUGoLtnr8/JTuVNj7XJbmpOAp2C6+B81KDrPxwaZM=
|
||||
github.com/sagernet/cronet-go/lib/android_arm v0.0.0-20251209163619-43499a42c286 h1:EEn7N5sCLZwnmlZjYb63Ewt2SjfYKTQwlQqEaC0zyF8=
|
||||
github.com/sagernet/cronet-go/lib/android_arm v0.0.0-20251209163619-43499a42c286/go.mod h1:19ILNUOGIzRdOqa2mq+iY0JoHxuieB7/lnjYeaA2vEc=
|
||||
github.com/sagernet/cronet-go/lib/android_arm64 v0.0.0-20251209163619-43499a42c286 h1:UA4/kKm8qA694fO7Y9EAe9csHecdBgAoKyn5CzUdAig=
|
||||
github.com/sagernet/cronet-go/lib/android_arm64 v0.0.0-20251209163619-43499a42c286/go.mod h1:JxzGyQf94Cr6sBShKqODGDyRUlESfJK/Njcz9Lz6qMQ=
|
||||
github.com/sagernet/cronet-go/lib/darwin_amd64 v0.0.0-20251209163619-43499a42c286 h1:Cz1iXs54Urg23BRtdkikDUzaifE72lNwq3D+DHZTVXE=
|
||||
github.com/sagernet/cronet-go/lib/darwin_amd64 v0.0.0-20251209163619-43499a42c286/go.mod h1:KN+9T9TBycGOLzmKU4QdcHAJEj6Nlx48ifnlTvvHMvs=
|
||||
github.com/sagernet/cronet-go/lib/darwin_arm64 v0.0.0-20251209163619-43499a42c286 h1:9f7dGYztdhJHqnGxAfg6e3pwiQc7gCIFfbnpYUG8+l4=
|
||||
github.com/sagernet/cronet-go/lib/darwin_arm64 v0.0.0-20251209163619-43499a42c286/go.mod h1:kojvtUc29KKnk8hs2QIANynVR59921SnGWA9kXohHc0=
|
||||
github.com/sagernet/cronet-go/lib/ios_arm64 v0.0.0-20251209163619-43499a42c286 h1:cVnXsYi+qvBGxtv5i5qzx05Ol0go4/ZVhEB/nwKdZxE=
|
||||
github.com/sagernet/cronet-go/lib/ios_arm64 v0.0.0-20251209163619-43499a42c286/go.mod h1:tzVJFTOm66UxLxy6K0ZN5Ic2PC79e+sKKnt+V9puEa4=
|
||||
github.com/sagernet/cronet-go/lib/linux_386 v0.0.0-20251209163619-43499a42c286 h1:L/M8nypnkrbv+zSFBEzoU3E2WVYoL/+BiF7W/ZGOkcE=
|
||||
github.com/sagernet/cronet-go/lib/linux_386 v0.0.0-20251209163619-43499a42c286/go.mod h1:cGh5hO6eljCo6KMQ/Cel8Xgq4+etL0awZLRBDVG1EZQ=
|
||||
github.com/sagernet/cronet-go/lib/linux_386_musl v0.0.0-20251209163619-43499a42c286 h1:UcNkxALcHUpo49DBHr2epN00hTRRiijwh4qv1fdXgRQ=
|
||||
github.com/sagernet/cronet-go/lib/linux_386_musl v0.0.0-20251209163619-43499a42c286/go.mod h1:JFE0/cxaKkx0wqPMZU7MgaplQlU0zudv82dROJjClKU=
|
||||
github.com/sagernet/cronet-go/lib/linux_amd64 v0.0.0-20251209163619-43499a42c286 h1:R68J9khidtJRKka3J2dNVKVGrBq0ieevNRS3P8vijMw=
|
||||
github.com/sagernet/cronet-go/lib/linux_amd64 v0.0.0-20251209163619-43499a42c286/go.mod h1:vU8VftFeSt7fURCa3JXD6+k6ss1YAX+idQjPvHmJ2tI=
|
||||
github.com/sagernet/cronet-go/lib/linux_amd64_musl v0.0.0-20251209163619-43499a42c286 h1:aDxXLIVS219vxa56UN1ak9Grju6UWKhX0ULw7RGDIgs=
|
||||
github.com/sagernet/cronet-go/lib/linux_amd64_musl v0.0.0-20251209163619-43499a42c286/go.mod h1:vCe4OUuL+XOUge9v3MyTD45BnuAXiH+DkjN9quDXJzQ=
|
||||
github.com/sagernet/cronet-go/lib/linux_arm v0.0.0-20251209163619-43499a42c286 h1:r4eaHyVT7KWguRhYTudhq+RHsd0pq7HHP/xLn3v/NuI=
|
||||
github.com/sagernet/cronet-go/lib/linux_arm v0.0.0-20251209163619-43499a42c286/go.mod h1:w9amBWrvjtohQzBGCKJ7LCh22LhTIJs4sE7cYaKQzM0=
|
||||
github.com/sagernet/cronet-go/lib/linux_arm64 v0.0.0-20251209163619-43499a42c286 h1:TYxTK8434FqUokQKzg5Qs8xpjU8ws2VVn7J4gfL0jY0=
|
||||
github.com/sagernet/cronet-go/lib/linux_arm64 v0.0.0-20251209163619-43499a42c286/go.mod h1:TqlsFtcYS/etTeck46kHBeT8Le0Igw1Q/AV88UnMS3s=
|
||||
github.com/sagernet/cronet-go/lib/linux_arm64_musl v0.0.0-20251209163619-43499a42c286 h1:2dysrFpUGjR/BePrJYoGyl8UmqlEY67g8ySyI2p1cjA=
|
||||
github.com/sagernet/cronet-go/lib/linux_arm64_musl v0.0.0-20251209163619-43499a42c286/go.mod h1:B6Qd0vys8sv9OKVRN6J9RqDzYRGE938Fb2zrYdBDyTQ=
|
||||
github.com/sagernet/cronet-go/lib/linux_arm_musl v0.0.0-20251209163619-43499a42c286 h1:edRSfV1xEloFgpdiordf0S653D5r0exHN4X85BT06nk=
|
||||
github.com/sagernet/cronet-go/lib/linux_arm_musl v0.0.0-20251209163619-43499a42c286/go.mod h1:3tXMMFY7AHugOVBZ5Al7cL7JKsnFOe5bMVr0hZPk3ow=
|
||||
github.com/sagernet/cronet-go/lib/windows_386 v0.0.0-20251209163619-43499a42c286 h1:CUWmGJ8PslWMJHanzgxF9+CuN4fk4NigKwxw1tjpdRY=
|
||||
github.com/sagernet/cronet-go/lib/windows_386 v0.0.0-20251209163619-43499a42c286/go.mod h1:rnS7D+ULJX2PrP0Cy+05GS0mRZ2PP6+gVSroZKt8fjk=
|
||||
github.com/sagernet/cronet-go/lib/windows_amd64 v0.0.0-20251209163619-43499a42c286 h1:2/fTHNBvTGgxWALqogKGpzKw1zLgc5lSidMRchLcoqk=
|
||||
github.com/sagernet/cronet-go/lib/windows_amd64 v0.0.0-20251209163619-43499a42c286/go.mod h1:lm9w/oCCRyBiUa3G8lDQTT8x/ONUvgVR2iV9fVzUZB8=
|
||||
github.com/sagernet/cronet-go/lib/windows_arm64 v0.0.0-20251209163619-43499a42c286 h1:J1nQYpbALQGlCOuErF0/lI3SnwPd0egy/iUxhgRK76g=
|
||||
github.com/sagernet/cronet-go/lib/windows_arm64 v0.0.0-20251209163619-43499a42c286/go.mod h1:n34YyLgapgjWdKa0IoeczjAFCwD3/dxbsH5sucKw0bw=
|
||||
github.com/sagernet/cronet-go v0.0.0-20251210132647-15dd6a9ee4bc h1:TeUwtjNOirI7QW6RUGmzovZHiImdyysxdXii8tj2pjE=
|
||||
github.com/sagernet/cronet-go v0.0.0-20251210132647-15dd6a9ee4bc/go.mod h1:l5IZJLEWpDGJbrF0qBHgxAVBPsAxKOLa1BYDh6B2sdI=
|
||||
github.com/sagernet/cronet-go/all v0.0.0-20251210133029-b0d1058a9fcf h1:9HfW4vwWSXSOBcxT3s7MAyxGnAxPpcFiRHW/9ImtlFA=
|
||||
github.com/sagernet/cronet-go/all v0.0.0-20251210133029-b0d1058a9fcf/go.mod h1:hljs4OQivwLEGy9ijqAQ7/bKfdfIOnudIuBKVWGpuNU=
|
||||
github.com/sagernet/cronet-go/lib/android_386 v0.0.0-20251210132647-15dd6a9ee4bc h1:7RwE5fT6D/bH8g/Sp/+bFPTTgYEHk8mI3wcP9nfOkfc=
|
||||
github.com/sagernet/cronet-go/lib/android_386 v0.0.0-20251210132647-15dd6a9ee4bc/go.mod h1:XXDwdjX/T8xftoeJxQmbBoYXZp8MAPFR2CwbFuTpEtw=
|
||||
github.com/sagernet/cronet-go/lib/android_amd64 v0.0.0-20251210132647-15dd6a9ee4bc h1:5ABO0dzl0FREp4yOj8tRUil8Rnr+UxAbgHm6/1/GaUs=
|
||||
github.com/sagernet/cronet-go/lib/android_amd64 v0.0.0-20251210132647-15dd6a9ee4bc/go.mod h1:iNiUGoLtnr8/JTuVNj7XJbmpOAp2C6+B81KDrPxwaZM=
|
||||
github.com/sagernet/cronet-go/lib/android_arm v0.0.0-20251210132647-15dd6a9ee4bc h1:6RWqk2JxL/JoyxeahfV6nWj0HpRJXKM42hAZAobprLk=
|
||||
github.com/sagernet/cronet-go/lib/android_arm v0.0.0-20251210132647-15dd6a9ee4bc/go.mod h1:19ILNUOGIzRdOqa2mq+iY0JoHxuieB7/lnjYeaA2vEc=
|
||||
github.com/sagernet/cronet-go/lib/android_arm64 v0.0.0-20251210132647-15dd6a9ee4bc h1:GHUnWWlndwxHw4pEvw40ISO7xrMq+h+P+FQ3KrGlghQ=
|
||||
github.com/sagernet/cronet-go/lib/android_arm64 v0.0.0-20251210132647-15dd6a9ee4bc/go.mod h1:JxzGyQf94Cr6sBShKqODGDyRUlESfJK/Njcz9Lz6qMQ=
|
||||
github.com/sagernet/cronet-go/lib/darwin_amd64 v0.0.0-20251210132647-15dd6a9ee4bc h1:urmRC1HxIetnZuyaPkHketyrhWBhwvRr74XXEHmqgLc=
|
||||
github.com/sagernet/cronet-go/lib/darwin_amd64 v0.0.0-20251210132647-15dd6a9ee4bc/go.mod h1:KN+9T9TBycGOLzmKU4QdcHAJEj6Nlx48ifnlTvvHMvs=
|
||||
github.com/sagernet/cronet-go/lib/darwin_arm64 v0.0.0-20251210132647-15dd6a9ee4bc h1:EN57YqGy2cbeQexLBb6vf1IcCEjNmz6sSoMNOik8DJQ=
|
||||
github.com/sagernet/cronet-go/lib/darwin_arm64 v0.0.0-20251210132647-15dd6a9ee4bc/go.mod h1:kojvtUc29KKnk8hs2QIANynVR59921SnGWA9kXohHc0=
|
||||
github.com/sagernet/cronet-go/lib/ios_arm64 v0.0.0-20251210132647-15dd6a9ee4bc h1:aRFCWKVFt5aTbcHQ7rUWLtfpxVtUbB1t1VDEgMm1LdY=
|
||||
github.com/sagernet/cronet-go/lib/ios_arm64 v0.0.0-20251210132647-15dd6a9ee4bc/go.mod h1:tzVJFTOm66UxLxy6K0ZN5Ic2PC79e+sKKnt+V9puEa4=
|
||||
github.com/sagernet/cronet-go/lib/linux_386 v0.0.0-20251210132647-15dd6a9ee4bc h1:txzvlKqPSL3yUVQs0DOx1bc0ONEuiWqIEoaQvMJNqdk=
|
||||
github.com/sagernet/cronet-go/lib/linux_386 v0.0.0-20251210132647-15dd6a9ee4bc/go.mod h1:cGh5hO6eljCo6KMQ/Cel8Xgq4+etL0awZLRBDVG1EZQ=
|
||||
github.com/sagernet/cronet-go/lib/linux_386_musl v0.0.0-20251210132647-15dd6a9ee4bc h1:DdYm5omtBr6/0DyCG5cTS4fK8hXoPXeEWiaBhDdUqac=
|
||||
github.com/sagernet/cronet-go/lib/linux_386_musl v0.0.0-20251210132647-15dd6a9ee4bc/go.mod h1:JFE0/cxaKkx0wqPMZU7MgaplQlU0zudv82dROJjClKU=
|
||||
github.com/sagernet/cronet-go/lib/linux_amd64 v0.0.0-20251210132647-15dd6a9ee4bc h1:qZ5koP16Y5Wbzi89bRA3c2C9vUlZPk7uz5ZLBAd/4h4=
|
||||
github.com/sagernet/cronet-go/lib/linux_amd64 v0.0.0-20251210132647-15dd6a9ee4bc/go.mod h1:vU8VftFeSt7fURCa3JXD6+k6ss1YAX+idQjPvHmJ2tI=
|
||||
github.com/sagernet/cronet-go/lib/linux_amd64_musl v0.0.0-20251210132647-15dd6a9ee4bc h1:nz3DMrICKuhS9ht7Hx1Hc1Al4LtfPADK/SbKrJ/UXKc=
|
||||
github.com/sagernet/cronet-go/lib/linux_amd64_musl v0.0.0-20251210132647-15dd6a9ee4bc/go.mod h1:vCe4OUuL+XOUge9v3MyTD45BnuAXiH+DkjN9quDXJzQ=
|
||||
github.com/sagernet/cronet-go/lib/linux_arm v0.0.0-20251210132647-15dd6a9ee4bc h1:5OLCnge+qhMLS1HBz/KY803Pd3IRC7Q9KP71GZMM+p0=
|
||||
github.com/sagernet/cronet-go/lib/linux_arm v0.0.0-20251210132647-15dd6a9ee4bc/go.mod h1:w9amBWrvjtohQzBGCKJ7LCh22LhTIJs4sE7cYaKQzM0=
|
||||
github.com/sagernet/cronet-go/lib/linux_arm64 v0.0.0-20251210132647-15dd6a9ee4bc h1:pg9jxoJQsiSxRBCTsFHXATGmSLMpsdvdCvVNhpMEdDA=
|
||||
github.com/sagernet/cronet-go/lib/linux_arm64 v0.0.0-20251210132647-15dd6a9ee4bc/go.mod h1:TqlsFtcYS/etTeck46kHBeT8Le0Igw1Q/AV88UnMS3s=
|
||||
github.com/sagernet/cronet-go/lib/linux_arm64_musl v0.0.0-20251210132647-15dd6a9ee4bc h1:gAnasnvsCH8seCtYsfFoWsHeldBZUKPvarSjt9bKIak=
|
||||
github.com/sagernet/cronet-go/lib/linux_arm64_musl v0.0.0-20251210132647-15dd6a9ee4bc/go.mod h1:B6Qd0vys8sv9OKVRN6J9RqDzYRGE938Fb2zrYdBDyTQ=
|
||||
github.com/sagernet/cronet-go/lib/linux_arm_musl v0.0.0-20251210132647-15dd6a9ee4bc h1:YVBUW8D3w/c0F5N3F+5rnXyNPNDODFPVw1NAWfsQv2Q=
|
||||
github.com/sagernet/cronet-go/lib/linux_arm_musl v0.0.0-20251210132647-15dd6a9ee4bc/go.mod h1:3tXMMFY7AHugOVBZ5Al7cL7JKsnFOe5bMVr0hZPk3ow=
|
||||
github.com/sagernet/cronet-go/lib/windows_386 v0.0.0-20251210132647-15dd6a9ee4bc h1:8w1wlyIpIcH3/1LPe6NMxZxLpsTq+00FEoSrMl+o03o=
|
||||
github.com/sagernet/cronet-go/lib/windows_386 v0.0.0-20251210132647-15dd6a9ee4bc/go.mod h1:rnS7D+ULJX2PrP0Cy+05GS0mRZ2PP6+gVSroZKt8fjk=
|
||||
github.com/sagernet/cronet-go/lib/windows_amd64 v0.0.0-20251210132647-15dd6a9ee4bc h1:Qwof0qMpoRXycadI1OWgwj7OTaCZQqoYbwqVAKd4rrs=
|
||||
github.com/sagernet/cronet-go/lib/windows_amd64 v0.0.0-20251210132647-15dd6a9ee4bc/go.mod h1:lm9w/oCCRyBiUa3G8lDQTT8x/ONUvgVR2iV9fVzUZB8=
|
||||
github.com/sagernet/cronet-go/lib/windows_arm64 v0.0.0-20251210132647-15dd6a9ee4bc h1:/2D4fyTJjYwf5NzgnOuTElGpX6fFN2dFAf/x0L0w1pI=
|
||||
github.com/sagernet/cronet-go/lib/windows_arm64 v0.0.0-20251210132647-15dd6a9ee4bc/go.mod h1:n34YyLgapgjWdKa0IoeczjAFCwD3/dxbsH5sucKw0bw=
|
||||
github.com/sagernet/fswatch v0.1.1 h1:YqID+93B7VRfqIH3PArW/XpJv5H4OLEVWDfProGoRQs=
|
||||
github.com/sagernet/fswatch v0.1.1/go.mod h1:nz85laH0mkQqJfaOrqPpkwtU1znMFNVTpT/5oRsVz/o=
|
||||
github.com/sagernet/gomobile v0.1.8 h1:vXgoN0pjsMONAaYCTdsKBX2T1kxuS7sbT/mZ7PElGoo=
|
||||
|
||||
@@ -206,9 +206,9 @@ function gen_outbound(flag, node, tag, proxy_table)
|
||||
local first = node.tcp_guise_http_path[1]
|
||||
return (first == "" or not first) and "/" or first
|
||||
end)() or "/",
|
||||
headers = {
|
||||
["User-Agent"] = node.tcp_guise_http_user_agent or nil
|
||||
},
|
||||
headers = node.tcp_guise_http_user_agent and {
|
||||
["User-Agent"] = node.tcp_guise_http_user_agent
|
||||
} or nil,
|
||||
idle_timeout = (node.http_h2_health_check == "1") and node.http_h2_read_idle_timeout or nil,
|
||||
ping_timeout = (node.http_h2_health_check == "1") and node.http_h2_health_check_timeout or nil,
|
||||
}
|
||||
@@ -220,9 +220,9 @@ function gen_outbound(flag, node, tag, proxy_table)
|
||||
type = "http",
|
||||
host = node.http_host or {},
|
||||
path = node.http_path or "/",
|
||||
headers = {
|
||||
["User-Agent"] = node.http_user_agent or nil
|
||||
},
|
||||
headers = node.http_user_agent and {
|
||||
["User-Agent"] = node.http_user_agent
|
||||
} or nil,
|
||||
idle_timeout = (node.http_h2_health_check == "1") and node.http_h2_read_idle_timeout or nil,
|
||||
ping_timeout = (node.http_h2_health_check == "1") and node.http_h2_health_check_timeout or nil,
|
||||
}
|
||||
@@ -233,10 +233,10 @@ function gen_outbound(flag, node, tag, proxy_table)
|
||||
v2ray_transport = {
|
||||
type = "ws",
|
||||
path = node.ws_path or "/",
|
||||
headers = {
|
||||
Host = node.ws_host or nil,
|
||||
["User-Agent"] = node.ws_user_agent or nil
|
||||
},
|
||||
headers = (node.ws_host or node.ws_user_agent) and {
|
||||
Host = node.ws_host,
|
||||
["User-Agent"] = node.ws_user_agent
|
||||
} or nil,
|
||||
max_early_data = tonumber(node.ws_maxEarlyData) or nil,
|
||||
early_data_header_name = (node.ws_earlyDataHeaderName) and node.ws_earlyDataHeaderName or nil --要与 Xray-core 兼容,请将其设置为 Sec-WebSocket-Protocol。它需要与服务器保持一致。
|
||||
}
|
||||
@@ -247,9 +247,9 @@ function gen_outbound(flag, node, tag, proxy_table)
|
||||
type = "httpupgrade",
|
||||
host = node.httpupgrade_host,
|
||||
path = node.httpupgrade_path or "/",
|
||||
headers = {
|
||||
["User-Agent"] = node.httpupgrade_user_agent or nil
|
||||
}
|
||||
headers = node.httpupgrade_user_agent and {
|
||||
["User-Agent"] = node.httpupgrade_user_agent
|
||||
} or nil
|
||||
}
|
||||
end
|
||||
|
||||
|
||||
@@ -178,10 +178,10 @@ function gen_outbound(flag, node, tag, proxy_table)
|
||||
end
|
||||
return r
|
||||
end)() or {"/"},
|
||||
headers = {
|
||||
Host = node.tcp_guise_http_host or {},
|
||||
headers = (node.tcp_guise_http_host or node.tcp_guise_http_user_agent) and {
|
||||
Host = node.tcp_guise_http_host,
|
||||
["User-Agent"] = node.tcp_guise_http_user_agent and {node.tcp_guise_http_user_agent} or nil
|
||||
}
|
||||
} or nil
|
||||
} or nil
|
||||
}
|
||||
} or nil,
|
||||
@@ -201,10 +201,10 @@ function gen_outbound(flag, node, tag, proxy_table)
|
||||
} or nil,
|
||||
wsSettings = (node.transport == "ws") and {
|
||||
path = node.ws_path or "/",
|
||||
headers = {
|
||||
Host = node.ws_host or nil,
|
||||
["User-Agent"] = node.ws_user_agent or nil
|
||||
},
|
||||
headers = (node.ws_host or node.ws_user_agent) and {
|
||||
Host = node.ws_host,
|
||||
["User-Agent"] = node.ws_user_agent
|
||||
} or nil,
|
||||
maxEarlyData = tonumber(node.ws_maxEarlyData) or nil,
|
||||
earlyDataHeaderName = (node.ws_earlyDataHeaderName) and node.ws_earlyDataHeaderName or nil,
|
||||
heartbeatPeriod = tonumber(node.ws_heartbeatPeriod) or nil
|
||||
@@ -220,9 +220,9 @@ function gen_outbound(flag, node, tag, proxy_table)
|
||||
httpupgradeSettings = (node.transport == "httpupgrade") and {
|
||||
path = node.httpupgrade_path or "/",
|
||||
host = node.httpupgrade_host,
|
||||
headers = {
|
||||
["User-Agent"] = node.httpupgrade_user_agent or nil
|
||||
}
|
||||
headers = node.httpupgrade_user_agent and {
|
||||
["User-Agent"] = node.httpupgrade_user_agent
|
||||
} or nil
|
||||
} or nil,
|
||||
xhttpSettings = (node.transport == "xhttp") and {
|
||||
mode = node.xhttp_mode or "auto",
|
||||
|
||||
@@ -1636,9 +1636,9 @@ Si un certificat auto-signé est utilisé ou si le système contient une CA non
|
||||
<value>Afficher dans le Dock de macOS (redém. requis)</value>
|
||||
</data>
|
||||
<data name="menuServerList2" xml:space="preserve">
|
||||
<value>Configuration Item 2, Select and add from self-built</value>
|
||||
<value>Élément de config 2 : choisir et ajouter depuis self-hosted</value>
|
||||
</data>
|
||||
<data name="AlpnMustContainHttp11ForWsTls" xml:space="preserve">
|
||||
<value>ALPN must contain 'http/1.1' when using WebSocket with TLS.</value>
|
||||
<value>Avec WebSocket et TLS, l’ALPN doit inclure ‘http/1.1’.</value>
|
||||
</data>
|
||||
</root>
|
||||
@@ -4,7 +4,6 @@ import (
|
||||
"context"
|
||||
"math"
|
||||
"math/big"
|
||||
gonet "net"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
@@ -17,7 +16,7 @@ import (
|
||||
|
||||
type Holder struct {
|
||||
domainToIP cache.Lru
|
||||
ipRange *gonet.IPNet
|
||||
ipRange *net.IPNet
|
||||
mu *sync.Mutex
|
||||
|
||||
config *FakeDnsPool
|
||||
@@ -79,10 +78,10 @@ func (fkdns *Holder) initializeFromConfig() error {
|
||||
}
|
||||
|
||||
func (fkdns *Holder) initialize(ipPoolCidr string, lruSize int) error {
|
||||
var ipRange *gonet.IPNet
|
||||
var ipRange *net.IPNet
|
||||
var err error
|
||||
|
||||
if _, ipRange, err = gonet.ParseCIDR(ipPoolCidr); err != nil {
|
||||
if _, ipRange, err = net.ParseCIDR(ipPoolCidr); err != nil {
|
||||
return errors.New("Unable to parse CIDR for Fake DNS IP assignment").Base(err).AtError()
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package fakedns
|
||||
|
||||
import (
|
||||
gonet "net"
|
||||
"strconv"
|
||||
"testing"
|
||||
|
||||
@@ -155,7 +154,7 @@ func TestFakeDNSMulti(t *testing.T) {
|
||||
assert.True(t, inPool)
|
||||
})
|
||||
t.Run("ipv6", func(t *testing.T) {
|
||||
ip, err := gonet.ResolveIPAddr("ip", "fddd:c5b4:ff5f:f4f0::5")
|
||||
ip, err := net.ResolveIPAddr("ip", "fddd:c5b4:ff5f:f4f0::5")
|
||||
assert.Nil(t, err)
|
||||
inPool := fakeMulti.IsIPInIPPool(net.IPAddress(ip.IP))
|
||||
assert.True(t, inPool)
|
||||
@@ -165,7 +164,7 @@ func TestFakeDNSMulti(t *testing.T) {
|
||||
assert.False(t, inPool)
|
||||
})
|
||||
t.Run("ipv6_inverse", func(t *testing.T) {
|
||||
ip, err := gonet.ResolveIPAddr("ip", "fcdd:c5b4:ff5f:f4f0::5")
|
||||
ip, err := net.ResolveIPAddr("ip", "fcdd:c5b4:ff5f:f4f0::5")
|
||||
assert.Nil(t, err)
|
||||
inPool := fakeMulti.IsIPInIPPool(net.IPAddress(ip.IP))
|
||||
assert.False(t, inPool)
|
||||
|
||||
@@ -2,7 +2,6 @@ package inbound
|
||||
|
||||
import (
|
||||
"context"
|
||||
gonet "net"
|
||||
"sync"
|
||||
"sync/atomic"
|
||||
"time"
|
||||
@@ -565,12 +564,12 @@ func (w *dsWorker) Close() error {
|
||||
}
|
||||
|
||||
func IsLocal(ip net.IP) bool {
|
||||
addrs, err := gonet.InterfaceAddrs()
|
||||
addrs, err := net.InterfaceAddrs()
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
for _, addr := range addrs {
|
||||
if ipnet, ok := addr.(*gonet.IPNet); ok {
|
||||
if ipnet, ok := addr.(*net.IPNet); ok {
|
||||
if ipnet.IP.Equal(ip) {
|
||||
return true
|
||||
}
|
||||
|
||||
@@ -6,7 +6,6 @@ import (
|
||||
goerrors "errors"
|
||||
"io"
|
||||
"math/big"
|
||||
gonet "net"
|
||||
"os"
|
||||
|
||||
"github.com/xtls/xray-core/common/dice"
|
||||
@@ -398,7 +397,7 @@ func (h *Handler) ProxySettings() *serial.TypedMessage {
|
||||
|
||||
func ParseRandomIP(addr net.Address, prefix string) net.Address {
|
||||
|
||||
_, ipnet, _ := gonet.ParseCIDR(addr.IP().String() + "/" + prefix)
|
||||
_, ipnet, _ := net.ParseCIDR(addr.IP().String() + "/" + prefix)
|
||||
|
||||
ones, bits := ipnet.Mask.Size()
|
||||
subnetSize := new(big.Int).Lsh(big.NewInt(1), uint(bits-ones))
|
||||
@@ -412,5 +411,5 @@ func ParseRandomIP(addr net.Address, prefix string) net.Address {
|
||||
padded := make([]byte, len(ipnet.IP))
|
||||
copy(padded[len(padded)-len(rndBytes):], rndBytes)
|
||||
|
||||
return net.ParseAddress(gonet.IP(padded).String())
|
||||
return net.ParseAddress(net.IP(padded).String())
|
||||
}
|
||||
|
||||
@@ -12,6 +12,8 @@ var (
|
||||
|
||||
type ListenConfig = net.ListenConfig
|
||||
|
||||
type KeepAliveConfig = net.KeepAliveConfig
|
||||
|
||||
var (
|
||||
Listen = net.Listen
|
||||
ListenTCP = net.ListenTCP
|
||||
@@ -26,6 +28,12 @@ var FileConn = net.FileConn
|
||||
// ParseIP is an alias of net.ParseIP
|
||||
var ParseIP = net.ParseIP
|
||||
|
||||
var ParseCIDR = net.ParseCIDR
|
||||
|
||||
var ResolveIPAddr = net.ResolveIPAddr
|
||||
|
||||
var InterfaceByName = net.InterfaceByName
|
||||
|
||||
var SplitHostPort = net.SplitHostPort
|
||||
|
||||
var CIDRMask = net.CIDRMask
|
||||
@@ -51,6 +59,8 @@ type (
|
||||
UnixConn = net.UnixConn
|
||||
)
|
||||
|
||||
type IPAddr = net.IPAddr
|
||||
|
||||
// IP is an alias for net.IP.
|
||||
type (
|
||||
IP = net.IP
|
||||
@@ -82,3 +92,11 @@ var (
|
||||
)
|
||||
|
||||
type Resolver = net.Resolver
|
||||
|
||||
var DefaultResolver = net.DefaultResolver
|
||||
|
||||
var JoinHostPort = net.JoinHostPort
|
||||
|
||||
var InterfaceAddrs = net.InterfaceAddrs
|
||||
|
||||
var Interfaces = net.Interfaces
|
||||
|
||||
@@ -21,10 +21,10 @@ require (
|
||||
github.com/vishvananda/netlink v1.3.1
|
||||
github.com/xtls/reality v0.0.0-20251014195629-e4eec4520535
|
||||
go4.org/netipx v0.0.0-20231129151722-fdeea329fbba
|
||||
golang.org/x/crypto v0.44.0
|
||||
golang.org/x/net v0.47.0
|
||||
golang.org/x/sync v0.18.0
|
||||
golang.org/x/sys v0.38.0
|
||||
golang.org/x/crypto v0.46.0
|
||||
golang.org/x/net v0.48.0
|
||||
golang.org/x/sync v0.19.0
|
||||
golang.org/x/sys v0.39.0
|
||||
golang.zx2c4.com/wireguard v0.0.0-20231211153847-12269c276173
|
||||
google.golang.org/grpc v1.77.0
|
||||
google.golang.org/protobuf v1.36.10
|
||||
@@ -46,10 +46,10 @@ require (
|
||||
github.com/quic-go/qpack v0.6.0 // indirect
|
||||
github.com/riobard/go-bloom v0.0.0-20200614022211-cdc8013cb5b3 // indirect
|
||||
github.com/vishvananda/netns v0.0.5 // indirect
|
||||
golang.org/x/mod v0.29.0 // indirect
|
||||
golang.org/x/text v0.31.0 // indirect
|
||||
golang.org/x/mod v0.30.0 // indirect
|
||||
golang.org/x/text v0.32.0 // indirect
|
||||
golang.org/x/time v0.12.0 // indirect
|
||||
golang.org/x/tools v0.38.0 // indirect
|
||||
golang.org/x/tools v0.39.0 // indirect
|
||||
golang.zx2c4.com/wintun v0.0.0-20230126152724-0fa3db229ce2 // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20251022142026-3a174f9686a8 // indirect
|
||||
gopkg.in/yaml.v2 v2.4.0 // indirect
|
||||
|
||||
@@ -95,20 +95,20 @@ go4.org/netipx v0.0.0-20231129151722-fdeea329fbba h1:0b9z3AuHCjxk0x/opv64kcgZLBs
|
||||
go4.org/netipx v0.0.0-20231129151722-fdeea329fbba/go.mod h1:PLyyIXexvUFg3Owu6p/WfdlivPbZJsZdgWZlrGope/Y=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.44.0 h1:A97SsFvM3AIwEEmTBiaxPPTYpDC47w720rdiiUvgoAU=
|
||||
golang.org/x/crypto v0.44.0/go.mod h1:013i+Nw79BMiQiMsOPcVCB5ZIJbYkerPrGnOa00tvmc=
|
||||
golang.org/x/crypto v0.46.0 h1:cKRW/pmt1pKAfetfu+RCEvjvZkA9RimPbh7bhFjGVBU=
|
||||
golang.org/x/crypto v0.46.0/go.mod h1:Evb/oLKmMraqjZ2iQTwDwvCtJkczlDuTmdJXoZVzqU0=
|
||||
golang.org/x/mod v0.5.1/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro=
|
||||
golang.org/x/mod v0.29.0 h1:HV8lRxZC4l2cr3Zq1LvtOsi/ThTgWnUk/y64QSs8GwA=
|
||||
golang.org/x/mod v0.29.0/go.mod h1:NyhrlYXJ2H4eJiRy/WDBO6HMqZQ6q9nk4JzS3NuCK+w=
|
||||
golang.org/x/mod v0.30.0 h1:fDEXFVZ/fmCKProc/yAXXUijritrDzahmwwefnjoPFk=
|
||||
golang.org/x/mod v0.30.0/go.mod h1:lAsf5O2EvJeSFMiBxXDki7sCgAxEUcZHXoXMKT4GJKc=
|
||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.47.0 h1:Mx+4dIFzqraBXUugkia1OOvlD6LemFo1ALMHjrXDOhY=
|
||||
golang.org/x/net v0.47.0/go.mod h1:/jNxtkgq5yWUGYkaZGqo27cfGZ1c5Nen03aYrrKpVRU=
|
||||
golang.org/x/net v0.48.0 h1:zyQRTTrjc33Lhh0fBgT/H3oZq9WuvRR5gPC70xpDiQU=
|
||||
golang.org/x/net v0.48.0/go.mod h1:+ndRgGjkh8FGtu1w1FGbEC31if4VrNVMuKTgcAAnQRY=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.18.0 h1:kr88TuHDroi+UVf+0hZnirlk8o8T+4MrK6mr60WkH/I=
|
||||
golang.org/x/sync v0.18.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI=
|
||||
golang.org/x/sync v0.19.0 h1:vV+1eWNmZ5geRlYjzm2adRgW2/mcpevXNg50YZtPCE4=
|
||||
golang.org/x/sync v0.19.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
@@ -116,21 +116,21 @@ golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7w
|
||||
golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.38.0 h1:3yZWxaJjBmCWXqhN1qh02AkOnCQ1poK6oF+a7xWL6Gc=
|
||||
golang.org/x/sys v0.38.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
|
||||
golang.org/x/sys v0.39.0 h1:CvCKL8MeisomCi6qNZ+wbb0DN9E5AATixKsvNtMoMFk=
|
||||
golang.org/x/sys v0.39.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
||||
golang.org/x/text v0.31.0 h1:aC8ghyu4JhP8VojJ2lEHBnochRno1sgL6nEi9WGFGMM=
|
||||
golang.org/x/text v0.31.0/go.mod h1:tKRAlv61yKIjGGHX/4tP1LTbc13YSec1pxVEWXzfoeM=
|
||||
golang.org/x/text v0.32.0 h1:ZD01bjUt1FQ9WJ0ClOL5vxgxOI/sVCNgX1YtKwcY0mU=
|
||||
golang.org/x/text v0.32.0/go.mod h1:o/rUWzghvpD5TXrTIBuJU77MTaN0ljMWE47kxGJQ7jY=
|
||||
golang.org/x/time v0.12.0 h1:ScB/8o8olJvc+CQPWrK3fPZNfh7qgwCrY0zJmoEQLSE=
|
||||
golang.org/x/time v0.12.0/go.mod h1:CDIdPxbZBQxdj6cxyCIdrNogrJKMJ7pr37NYpMcMDSg=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.1.8/go.mod h1:nABZi5QlRsZVlzPpHl034qft6wpY4eDcsTt5AaioBiU=
|
||||
golang.org/x/tools v0.38.0 h1:Hx2Xv8hISq8Lm16jvBZ2VQf+RLmbd7wVUsALibYI/IQ=
|
||||
golang.org/x/tools v0.38.0/go.mod h1:yEsQ/d/YK8cjh0L6rZlY8tgtlKiBNTL14pGDJPJpYQs=
|
||||
golang.org/x/tools v0.39.0 h1:ik4ho21kwuQln40uelmciQPp9SipgNDdrafrYA4TmQQ=
|
||||
golang.org/x/tools v0.39.0/go.mod h1:JnefbkDPyD8UU2kI5fuf8ZX4/yUeh9W877ZeBONxUqQ=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
|
||||
@@ -3,14 +3,13 @@ package wireguard
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"net"
|
||||
"net/netip"
|
||||
"strconv"
|
||||
"sync"
|
||||
|
||||
"golang.zx2c4.com/wireguard/conn"
|
||||
|
||||
xnet "github.com/xtls/xray-core/common/net"
|
||||
"github.com/xtls/xray-core/common/net"
|
||||
"github.com/xtls/xray-core/features/dns"
|
||||
"github.com/xtls/xray-core/transport/internet"
|
||||
)
|
||||
@@ -51,21 +50,21 @@ func (n *netBind) ParseEndpoint(s string) (conn.Endpoint, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
addr := xnet.ParseAddress(ipStr)
|
||||
if addr.Family() == xnet.AddressFamilyDomain {
|
||||
addr := net.ParseAddress(ipStr)
|
||||
if addr.Family() == net.AddressFamilyDomain {
|
||||
ips, _, err := n.dns.LookupIP(addr.Domain(), n.dnsOption)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
} else if len(ips) == 0 {
|
||||
return nil, dns.ErrEmptyResponse
|
||||
}
|
||||
addr = xnet.IPAddress(ips[0])
|
||||
addr = net.IPAddress(ips[0])
|
||||
}
|
||||
|
||||
dst := xnet.Destination{
|
||||
dst := net.Destination{
|
||||
Address: addr,
|
||||
Port: xnet.Port(portNum),
|
||||
Network: xnet.Network_UDP,
|
||||
Port: net.Port(portNum),
|
||||
Network: net.Network_UDP,
|
||||
}
|
||||
|
||||
return &netEndpoint{
|
||||
@@ -214,7 +213,7 @@ func (bind *netBindServer) Send(buff [][]byte, endpoint conn.Endpoint) error {
|
||||
}
|
||||
|
||||
type netEndpoint struct {
|
||||
dst xnet.Destination
|
||||
dst net.Destination
|
||||
conn net.Conn
|
||||
}
|
||||
|
||||
@@ -247,7 +246,7 @@ func (e netEndpoint) SrcToString() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func toNetIpAddr(addr xnet.Address) netip.Addr {
|
||||
func toNetIpAddr(addr net.Address) netip.Addr {
|
||||
if addr.Family().IsIPv4() {
|
||||
ip := addr.IP()
|
||||
return netip.AddrFrom4([4]byte{ip[0], ip[1], ip[2], ip[3]})
|
||||
|
||||
@@ -3,7 +3,6 @@ package wireguard
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"net"
|
||||
"net/netip"
|
||||
"runtime"
|
||||
"strconv"
|
||||
@@ -13,7 +12,7 @@ import (
|
||||
|
||||
"github.com/xtls/xray-core/common/errors"
|
||||
"github.com/xtls/xray-core/common/log"
|
||||
xnet "github.com/xtls/xray-core/common/net"
|
||||
"github.com/xtls/xray-core/common/net"
|
||||
"github.com/xtls/xray-core/proxy/wireguard/gvisortun"
|
||||
"gvisor.dev/gvisor/pkg/tcpip"
|
||||
"gvisor.dev/gvisor/pkg/tcpip/adapters/gonet"
|
||||
@@ -28,7 +27,7 @@ import (
|
||||
|
||||
type tunCreator func(localAddresses []netip.Addr, mtu int, handler promiscuousModeHandler) (Tunnel, error)
|
||||
|
||||
type promiscuousModeHandler func(dest xnet.Destination, conn net.Conn)
|
||||
type promiscuousModeHandler func(dest net.Destination, conn net.Conn)
|
||||
|
||||
type Tunnel interface {
|
||||
BuildDevice(ipc string, bind conn.Bind) error
|
||||
@@ -169,7 +168,7 @@ func createGVisorTun(localAddresses []netip.Addr, mtu int, handler promiscuousMo
|
||||
ep.SocketOptions().SetKeepAlive(true)
|
||||
|
||||
// local address is actually destination
|
||||
handler(xnet.TCPDestination(xnet.IPAddress(id.LocalAddress.AsSlice()), xnet.Port(id.LocalPort)), gonet.NewTCPConn(&wq, ep))
|
||||
handler(net.TCPDestination(net.IPAddress(id.LocalAddress.AsSlice()), net.Port(id.LocalPort)), gonet.NewTCPConn(&wq, ep))
|
||||
}(r)
|
||||
})
|
||||
stack.SetTransportProtocolHandler(tcp.ProtocolNumber, tcpForwarder.HandlePacket)
|
||||
@@ -194,7 +193,7 @@ func createGVisorTun(localAddresses []netip.Addr, mtu int, handler promiscuousMo
|
||||
Timeout: 15 * time.Second,
|
||||
})
|
||||
|
||||
handler(xnet.UDPDestination(xnet.IPAddress(id.LocalAddress.AsSlice()), xnet.Port(id.LocalPort)), gonet.NewUDPConn(&wq, ep))
|
||||
handler(net.UDPDestination(net.IPAddress(id.LocalAddress.AsSlice()), net.Port(id.LocalPort)), gonet.NewUDPConn(&wq, ep))
|
||||
}(r)
|
||||
})
|
||||
stack.SetTransportProtocolHandler(udp.ProtocolNumber, udpForwarder.HandlePacket)
|
||||
|
||||
@@ -3,7 +3,6 @@ package internet
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
gonet "net"
|
||||
"strings"
|
||||
|
||||
"github.com/xtls/xray-core/common"
|
||||
@@ -183,7 +182,7 @@ func checkAddressPortStrategy(ctx context.Context, dest net.Destination, sockopt
|
||||
if len(parts) != 3 {
|
||||
return nil, errors.New("invalid address format", dest.Address.String())
|
||||
}
|
||||
_, srvRecords, err := gonet.DefaultResolver.LookupSRV(context.Background(), parts[0][1:], parts[1][1:], parts[2])
|
||||
_, srvRecords, err := net.DefaultResolver.LookupSRV(context.Background(), parts[0][1:], parts[1][1:], parts[2])
|
||||
if err != nil {
|
||||
return nil, errors.New("failed to lookup SRV record").Base(err)
|
||||
}
|
||||
@@ -198,7 +197,7 @@ func checkAddressPortStrategy(ctx context.Context, dest net.Destination, sockopt
|
||||
}
|
||||
if OverrideBy == "txt" {
|
||||
errors.LogDebug(ctx, "query TXT record for "+dest.Address.String())
|
||||
txtRecords, err := gonet.DefaultResolver.LookupTXT(ctx, dest.Address.String())
|
||||
txtRecords, err := net.DefaultResolver.LookupTXT(ctx, dest.Address.String())
|
||||
if err != nil {
|
||||
errors.LogError(ctx, "failed to lookup SRV record: "+err.Error())
|
||||
return nil, errors.New("failed to lookup SRV record").Base(err)
|
||||
|
||||
@@ -2,7 +2,6 @@ package grpc
|
||||
|
||||
import (
|
||||
"context"
|
||||
gonet "net"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
@@ -99,7 +98,7 @@ func getGrpcClient(ctx context.Context, dest net.Destination, streamSettings *in
|
||||
},
|
||||
MinConnectTimeout: 5 * time.Second,
|
||||
}),
|
||||
grpc.WithContextDialer(func(gctx context.Context, s string) (gonet.Conn, error) {
|
||||
grpc.WithContextDialer(func(gctx context.Context, s string) (net.Conn, error) {
|
||||
select {
|
||||
case <-gctx.Done():
|
||||
return nil, gctx.Err()
|
||||
@@ -180,7 +179,7 @@ func getGrpcClient(ctx context.Context, dest net.Destination, streamSettings *in
|
||||
}
|
||||
|
||||
conn, err := grpc.Dial(
|
||||
gonet.JoinHostPort(grpcDestHost, dest.Port.String()),
|
||||
net.JoinHostPort(grpcDestHost, dest.Port.String()),
|
||||
dialOptions...,
|
||||
)
|
||||
globalDialerMap[dialerConf{dest, streamSettings}] = conn
|
||||
|
||||
@@ -3,11 +3,10 @@ package encoding
|
||||
import (
|
||||
"context"
|
||||
"io"
|
||||
"net"
|
||||
|
||||
"github.com/xtls/xray-core/common/buf"
|
||||
"github.com/xtls/xray-core/common/errors"
|
||||
xnet "github.com/xtls/xray-core/common/net"
|
||||
"github.com/xtls/xray-core/common/net"
|
||||
"github.com/xtls/xray-core/common/net/cnc"
|
||||
"github.com/xtls/xray-core/common/signal/done"
|
||||
"google.golang.org/grpc/metadata"
|
||||
@@ -55,7 +54,7 @@ func NewHunkConn(hc HunkConn, cancel context.CancelFunc) net.Conn {
|
||||
if ok {
|
||||
header := md.Get("x-real-ip")
|
||||
if len(header) > 0 {
|
||||
realip := xnet.ParseAddress(header[0])
|
||||
realip := net.ParseAddress(header[0])
|
||||
if realip.Family().IsIP() {
|
||||
rAddr = &net.TCPAddr{
|
||||
IP: realip.IP(),
|
||||
|
||||
@@ -2,7 +2,6 @@ package internet
|
||||
|
||||
import (
|
||||
"context"
|
||||
gonet "net"
|
||||
"os"
|
||||
"runtime"
|
||||
"strconv"
|
||||
@@ -135,7 +134,7 @@ func applyOutboundSocketOptions(network string, address string, fd uintptr, conf
|
||||
}
|
||||
|
||||
if config.Interface != "" {
|
||||
iface, err := gonet.InterfaceByName(config.Interface)
|
||||
iface, err := net.InterfaceByName(config.Interface)
|
||||
|
||||
if err != nil {
|
||||
return errors.New("failed to get interface ", config.Interface).Base(err)
|
||||
@@ -226,7 +225,7 @@ func applyInboundSocketOptions(network string, fd uintptr, config *SocketConfig)
|
||||
}
|
||||
|
||||
if config.Interface != "" {
|
||||
iface, err := gonet.InterfaceByName(config.Interface)
|
||||
iface, err := net.InterfaceByName(config.Interface)
|
||||
|
||||
if err != nil {
|
||||
return errors.New("failed to get interface ", config.Interface).Base(err)
|
||||
|
||||
@@ -3,9 +3,9 @@ package splithttp
|
||||
import (
|
||||
"context"
|
||||
"io"
|
||||
gonet "net"
|
||||
|
||||
"github.com/xtls/xray-core/common/errors"
|
||||
"github.com/xtls/xray-core/common/net"
|
||||
"github.com/xtls/xray-core/transport/internet/browser_dialer"
|
||||
"github.com/xtls/xray-core/transport/internet/websocket"
|
||||
)
|
||||
@@ -19,13 +19,13 @@ func (c *BrowserDialerClient) IsClosed() bool {
|
||||
panic("not implemented yet")
|
||||
}
|
||||
|
||||
func (c *BrowserDialerClient) OpenStream(ctx context.Context, url string, body io.Reader, uploadOnly bool) (io.ReadCloser, gonet.Addr, gonet.Addr, error) {
|
||||
func (c *BrowserDialerClient) OpenStream(ctx context.Context, url string, body io.Reader, uploadOnly bool) (io.ReadCloser, net.Addr, net.Addr, error) {
|
||||
if body != nil {
|
||||
return nil, nil, nil, errors.New("bidirectional streaming for browser dialer not implemented yet")
|
||||
}
|
||||
|
||||
conn, err := browser_dialer.DialGet(url, c.transportConfig.GetRequestHeader(url))
|
||||
dummyAddr := &gonet.IPAddr{}
|
||||
dummyAddr := &net.IPAddr{}
|
||||
if err != nil {
|
||||
return nil, dummyAddr, dummyAddr, err
|
||||
}
|
||||
|
||||
@@ -5,7 +5,6 @@ import (
|
||||
"context"
|
||||
"fmt"
|
||||
"io"
|
||||
gonet "net"
|
||||
"net/http"
|
||||
"net/http/httptrace"
|
||||
"sync"
|
||||
@@ -42,7 +41,7 @@ func (c *DefaultDialerClient) IsClosed() bool {
|
||||
return c.closed
|
||||
}
|
||||
|
||||
func (c *DefaultDialerClient) OpenStream(ctx context.Context, url string, body io.Reader, uploadOnly bool) (wrc io.ReadCloser, remoteAddr, localAddr gonet.Addr, err error) {
|
||||
func (c *DefaultDialerClient) OpenStream(ctx context.Context, url string, body io.Reader, uploadOnly bool) (wrc io.ReadCloser, remoteAddr, localAddr net.Addr, err error) {
|
||||
// this is done when the TCP/UDP connection to the server was established,
|
||||
// and we can unblock the Dial function and print correct net addresses in
|
||||
// logs
|
||||
|
||||
@@ -3,7 +3,6 @@ package internet
|
||||
import (
|
||||
"context"
|
||||
"math/rand"
|
||||
gonet "net"
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
@@ -89,7 +88,7 @@ func (d *DefaultSystemDialer) Dial(ctx context.Context, src net.Address, dest ne
|
||||
}, nil
|
||||
}
|
||||
// Chrome defaults
|
||||
keepAliveConfig := gonet.KeepAliveConfig{
|
||||
keepAliveConfig := net.KeepAliveConfig{
|
||||
Enable: true,
|
||||
Idle: 45 * time.Second,
|
||||
Interval: 45 * time.Second,
|
||||
|
||||
@@ -2,7 +2,6 @@ package internet
|
||||
|
||||
import (
|
||||
"context"
|
||||
gonet "net"
|
||||
"os"
|
||||
"runtime"
|
||||
"strconv"
|
||||
@@ -95,7 +94,7 @@ func (dl *DefaultListener) Listen(ctx context.Context, addr net.Addr, sockopt *S
|
||||
if sockopt.TcpKeepAliveIdle*sockopt.TcpKeepAliveInterval < 0 {
|
||||
return nil, errors.New("invalid TcpKeepAliveIdle or TcpKeepAliveInterval value: ", sockopt.TcpKeepAliveIdle, " ", sockopt.TcpKeepAliveInterval)
|
||||
}
|
||||
lc.KeepAliveConfig = gonet.KeepAliveConfig{
|
||||
lc.KeepAliveConfig = net.KeepAliveConfig{
|
||||
Enable: false,
|
||||
Idle: -1,
|
||||
Interval: -1,
|
||||
|
||||
@@ -5,7 +5,6 @@ import (
|
||||
_ "embed"
|
||||
"encoding/base64"
|
||||
"io"
|
||||
gonet "net"
|
||||
"time"
|
||||
|
||||
"github.com/gorilla/websocket"
|
||||
@@ -64,7 +63,7 @@ func dialWebSocket(ctx context.Context, dest net.Destination, streamSettings *in
|
||||
tlsConfig := tConfig.GetTLSConfig(tls.WithDestination(dest), tls.WithNextProto("http/1.1"))
|
||||
dialer.TLSClientConfig = tlsConfig
|
||||
if fingerprint := tls.GetFingerprint(tConfig.Fingerprint); fingerprint != nil {
|
||||
dialer.NetDialTLSContext = func(_ context.Context, _, addr string) (gonet.Conn, error) {
|
||||
dialer.NetDialTLSContext = func(_ context.Context, _, addr string) (net.Conn, error) {
|
||||
// Like the NetDial in the dialer
|
||||
pconn, err := internet.DialSystem(ctx, dest, streamSettings.SocketSettings)
|
||||
if err != nil {
|
||||
|
||||
@@ -279,7 +279,7 @@ class ArchiveOrgIE(InfoExtractor):
|
||||
'url': 'https://archive.org/' + track['file'].lstrip('/'),
|
||||
}
|
||||
|
||||
metadata = self._download_json('http://archive.org/metadata/' + identifier, identifier)
|
||||
metadata = self._download_json(f'https://archive.org/metadata/{identifier}', identifier)
|
||||
m = metadata['metadata']
|
||||
identifier = m['identifier']
|
||||
|
||||
|
||||
Reference in New Issue
Block a user