diff --git a/.DS_Store b/.DS_Store
new file mode 100755
index 000000000..9d6555cde
Binary files /dev/null and b/.DS_Store differ
diff --git a/.github/ISSUE_TEMPLATE/------.md b/.github/ISSUE_TEMPLATE/------.md
old mode 100644
new mode 100755
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
old mode 100644
new mode 100755
diff --git a/.gitignore b/.gitignore
old mode 100644
new mode 100755
index 1b5f0069c..7cc35348a
--- a/.gitignore
+++ b/.gitignore
@@ -8,3 +8,7 @@ x-ui-*.tar.gz
/release.sh
.sync*
main
+.DS_Store
+bin/x-ui
+bin/upload.sh
+.DS_Store
diff --git a/CoCoding.md b/CoCoding.md
new file mode 100755
index 000000000..5a48b88b4
--- /dev/null
+++ b/CoCoding.md
@@ -0,0 +1,39 @@
+# Co-coding 扩展功能
+
+## 本地开发
+> `go get -u` 更新开发包
+- 启动Web服务
+`go run main.go run`
+- 测试
+
+ 打开网址
+ > http://127.0.0.1:54321
+
+- Macbook m1 arm64 开发
+
+ [https://github.com/XTLS/Xray-core/releases](https://github.com/XTLS/Xray-core/releases) 下载xray-core,放在bin目录下,重命名为 `xray-darwin-amd64`
+
+- 升级go1.22.2
+- go mod tidy
+
+
+## 添加功能
+
+- 快捷配置
+
+ > 快捷配置能够配置一些常用参数,例如:入站端口范围、入站TLS证书,以免每次添加入站节点时需要手动输入。
+
+- 节点复制
+
+ > 入站节点操作增加复制功能,可以快速复制节点信息,端口和ID会重新生成,主要复制TLS证书信息。
+
+- 订阅功能
+
+ > 添加订阅,订阅包括多个节点,可设置自动更新,防止端口被墙,可生成订阅链接,可设置有效日期
+
+
+## 安装&升级
+
+```shell
+bash <(curl -Ls https://github.com/icocoding/x-ui/releases/download/tools/install-v1.0.sh)
+```
diff --git a/Dockerfile b/Dockerfile
old mode 100644
new mode 100755
diff --git a/LICENSE b/LICENSE
old mode 100644
new mode 100755
diff --git a/README.md b/README.md
old mode 100644
new mode 100755
diff --git a/config/config.go b/config/config.go
old mode 100644
new mode 100755
diff --git a/config/name b/config/name
old mode 100644
new mode 100755
diff --git a/config/version b/config/version
old mode 100644
new mode 100755
index 9fc80f937..53b61ecf7
--- a/config/version
+++ b/config/version
@@ -1 +1 @@
-0.3.2
\ No newline at end of file
+0.3.6
\ No newline at end of file
diff --git a/database/db.go b/database/db.go
old mode 100644
new mode 100755
index 3273874ad..8a12b951e
--- a/database/db.go
+++ b/database/db.go
@@ -1,14 +1,16 @@
package database
import (
- "gorm.io/driver/sqlite"
- "gorm.io/gorm"
- "gorm.io/gorm/logger"
+ "github.com/glebarez/sqlite"
+ // "github.com/glebarez/sqlite"
"io/fs"
"os"
"path"
"x-ui/config"
"x-ui/database/model"
+
+ "gorm.io/gorm"
+ "gorm.io/gorm/logger"
)
var db *gorm.DB
@@ -41,6 +43,10 @@ func initSetting() error {
return db.AutoMigrate(&model.Setting{})
}
+func initSubscription() error {
+ return db.AutoMigrate(&model.Subscription{})
+}
+
func InitDB(dbPath string) error {
dir := path.Dir(dbPath)
err := os.MkdirAll(dir, fs.ModeDir)
@@ -76,6 +82,10 @@ func InitDB(dbPath string) error {
if err != nil {
return err
}
+ err = initSubscription()
+ if err != nil {
+ return err
+ }
return nil
}
diff --git a/database/model/model.go b/database/model/model.go
old mode 100644
new mode 100755
index bc1944459..8957bb3d7
--- a/database/model/model.go
+++ b/database/model/model.go
@@ -64,3 +64,20 @@ type Setting struct {
Key string `json:"key" form:"key"`
Value string `json:"value" form:"value"`
}
+
+
+type Subscription struct {
+ Id int `json:"id" form:"id" gorm:"primaryKey;autoIncrement"`
+ UserId int `json:"-"`
+ Token string `json:"token" form:"token" gorm:"unique"`
+ Remark string `json:"remark" form:"remark"`
+ Enable bool `json:"enable" form:"enable"`
+ ExpiryTime int64 `json:"expiryTime" form:"expiryTime"`
+
+ // Inbound Config
+ SampleId int `json:"sampleId" form:"sampleId"`
+ AvailableCount int `json:"availableCount" form:"availableCount"`
+ AutoUpdate bool `json:"autoUpdate" form:"autoUpdate"`
+ AutoDelete bool `json:"autoDelete" form:"autoDelete"`
+ InboundIds string `json:"inboundIds" form:"inboundIds"`
+}
diff --git a/go.mod b/go.mod
old mode 100644
new mode 100755
index 44b6570b6..ec0b3c66c
--- a/go.mod
+++ b/go.mod
@@ -1,26 +1,79 @@
module x-ui
-go 1.16
+go 1.22.2
require (
- github.com/BurntSushi/toml v0.3.1
- github.com/StackExchange/wmi v0.0.0-20210224194228-fe8f1750fd46 // indirect
- github.com/Workiva/go-datastructures v1.0.53
- github.com/gin-contrib/sessions v0.0.3
- github.com/gin-gonic/gin v1.7.1
- github.com/go-ole/go-ole v1.2.5 // indirect
+ github.com/BurntSushi/toml v1.3.2
+ github.com/Workiva/go-datastructures v1.1.3
+ github.com/gin-contrib/sessions v1.0.0
+ github.com/gin-gonic/gin v1.9.1
github.com/go-telegram-bot-api/telegram-bot-api/v5 v5.5.1
- github.com/nicksnyder/go-i18n/v2 v2.1.2
+ github.com/nicksnyder/go-i18n/v2 v2.4.0
github.com/op/go-logging v0.0.0-20160315200505-970db520ece7
github.com/robfig/cron/v3 v3.0.1
- github.com/shirou/gopsutil v3.21.3+incompatible
- github.com/tklauser/go-sysconf v0.3.5 // indirect
- github.com/xtls/xray-core v1.4.2
- go.uber.org/atomic v1.7.0
- golang.org/x/sys v0.0.0-20210511113859-b0526f3d8744 // indirect
- golang.org/x/text v0.3.6
- google.golang.org/grpc v1.38.0
- gopkg.in/yaml.v2 v2.4.0 // indirect
- gorm.io/driver/sqlite v1.1.4
- gorm.io/gorm v1.21.9
+ github.com/shirou/gopsutil v3.21.11+incompatible
+ github.com/xtls/xray-core v1.8.10
+ go.uber.org/atomic v1.11.0
+ golang.org/x/text v0.14.0
+ google.golang.org/grpc v1.63.2
+ gorm.io/driver/sqlite v1.5.5
+ gorm.io/gorm v1.25.9
+)
+
+require (
+ github.com/dlclark/regexp2 v1.7.0 // indirect
+ github.com/dustin/go-humanize v1.0.1 // indirect
+ github.com/glebarez/go-sqlite v1.21.2 // indirect
+ github.com/go-sourcemap/sourcemap v2.1.3+incompatible // indirect
+ github.com/google/pprof v0.0.0-20240227163752-401108e1b7e7 // indirect
+ github.com/google/uuid v1.6.0 // indirect
+ github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect
+ gopkg.in/sourcemap.v1 v1.0.5 // indirect
+ modernc.org/libc v1.22.5 // indirect
+ modernc.org/mathutil v1.5.0 // indirect
+ modernc.org/memory v1.5.0 // indirect
+ modernc.org/sqlite v1.23.1 // indirect
+)
+
+require (
+ github.com/bytedance/sonic v1.11.3 // indirect
+ github.com/chenzhuoyu/base64x v0.0.0-20230717121745-296ad89f973d // indirect
+ github.com/chenzhuoyu/iasm v0.9.1 // indirect
+ github.com/dop251/goja v0.0.0-20240220182346-e401ed450204
+ github.com/gabriel-vasile/mimetype v1.4.3 // indirect
+ github.com/gin-contrib/sse v0.1.0 // indirect
+ github.com/glebarez/sqlite v1.11.0
+ github.com/go-ole/go-ole v1.2.6 // indirect
+ github.com/go-playground/locales v0.14.1 // indirect
+ github.com/go-playground/universal-translator v0.18.1 // indirect
+ github.com/go-playground/validator/v10 v10.19.0 // indirect
+ github.com/goccy/go-json v0.10.2 // indirect
+ github.com/gorilla/context v1.1.2 // indirect
+ github.com/gorilla/securecookie v1.1.2 // indirect
+ github.com/gorilla/sessions v1.2.2 // indirect
+ github.com/jinzhu/inflection v1.0.0 // indirect
+ github.com/jinzhu/now v1.1.5 // indirect
+ github.com/json-iterator/go v1.1.12 // indirect
+ github.com/klauspost/cpuid/v2 v2.2.7 // indirect
+ github.com/leodido/go-urn v1.4.0 // indirect
+ github.com/mattn/go-isatty v0.0.20 // indirect
+ github.com/mattn/go-sqlite3 v1.14.17 // indirect
+ github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
+ github.com/modern-go/reflect2 v1.0.2 // indirect
+ github.com/pelletier/go-toml/v2 v2.2.0 // indirect
+ github.com/pires/go-proxyproto v0.7.0 // indirect
+ github.com/robertkrimen/otto v0.4.0
+ github.com/sagernet/sing v0.3.8 // indirect
+ github.com/tklauser/go-sysconf v0.3.13 // indirect
+ github.com/tklauser/numcpus v0.7.0 // indirect
+ github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
+ github.com/ugorji/go/codec v1.2.12 // indirect
+ github.com/yusufpapurcu/wmi v1.2.4 // indirect
+ golang.org/x/arch v0.7.0 // indirect
+ golang.org/x/crypto v0.21.0 // indirect
+ golang.org/x/net v0.22.0 // indirect
+ golang.org/x/sys v0.18.0 // indirect
+ google.golang.org/genproto/googleapis/rpc v0.0.0-20240308144416-29370a3891b7 // indirect
+ google.golang.org/protobuf v1.33.0 // indirect
+ gopkg.in/yaml.v3 v3.0.1 // indirect
)
diff --git a/go.sum b/go.sum
old mode 100644
new mode 100755
index c8ed240f1..236847fa2
--- a/go.sum
+++ b/go.sum
@@ -1,434 +1,303 @@
-cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
-cloud.google.com/go v0.31.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
-cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
-cloud.google.com/go v0.37.0/go.mod h1:TS1dMSSfndXH133OKGwekG838Om/cQT0BUHV3HcBgoo=
-dmitri.shuralyov.com/app/changes v0.0.0-20180602232624-0a106ad413e3/go.mod h1:Yl+fi1br7+Rr3LqpNJf1/uxUdtRUV+Tnj0o93V2B9MU=
-dmitri.shuralyov.com/html/belt v0.0.0-20180602232347-f7d459c86be0/go.mod h1:JLBrvjyP0v+ecvNYvCpyZgu5/xkfAUhi6wJj28eUfSU=
-dmitri.shuralyov.com/service/change v0.0.0-20181023043359-a85b471d5412/go.mod h1:a1inKt/atXimZ4Mv927x+r7UpyzRUf4emIoiiSC2TN4=
-dmitri.shuralyov.com/state v0.0.0-20180228185332-28bcc343414c/go.mod h1:0PRwlb0D6DFvNNtx+9ybjezNCa8XF0xaYcETyp6rHWU=
-git.apache.org/thrift.git v0.0.0-20180902110319-2566ecd5d999/go.mod h1:fPE2ZNJGynbRyZ4dJvy6G277gSllfV2HJqblrnkyeyg=
-github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
-github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
-github.com/StackExchange/wmi v0.0.0-20210224194228-fe8f1750fd46 h1:5sXbqlSomvdjlRbWyNqkPsJ3Fg+tQZCbgeX1VGljbQY=
-github.com/StackExchange/wmi v0.0.0-20210224194228-fe8f1750fd46/go.mod h1:3eOhrUMpNV+6aFIbp5/iudMxNCF27Vw2OZgy4xEx0Fg=
-github.com/Workiva/go-datastructures v1.0.53 h1:J6Y/52yX10Xc5JjXmGtWoSSxs3mZnGSaq37xZZh7Yig=
-github.com/Workiva/go-datastructures v1.0.53/go.mod h1:1yZL+zfsztete+ePzZz/Zb1/t5BnDuE2Ya2MMGhzP6A=
-github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c=
-github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
-github.com/boj/redistore v0.0.0-20180917114910-cd5dcc76aeff/go.mod h1:+RTT1BOk5P97fT2CiHkbFQwkK3mjsFAP6zCYV2aXtjw=
-github.com/bradfitz/go-smtpd v0.0.0-20170404230938-deb6d6237625/go.mod h1:HYsPBTaaSFSlLx/70C2HPIMNZpVV8+vt/A+FMnYP11g=
-github.com/bradfitz/gomemcache v0.0.0-20190329173943-551aad21a668/go.mod h1:H0wQNHz2YrLsuXOZozoeDmnHXkNCRmMW0gwFWDfEZDA=
-github.com/bradleypeabody/gorilla-sessions-memcache v0.0.0-20181103040241-659414f458e1/go.mod h1:dkChI7Tbtx7H1Tj7TqGSZMOeGpMP5gLHtjroHd4agiI=
-github.com/buger/jsonparser v0.0.0-20181115193947-bf1c66bbce23/go.mod h1:bbYlZJ7hK1yFx9hf58LP0zeX7UjIGs20ufpu3evjr+s=
-github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
-github.com/cheekybits/genny v1.0.0 h1:uGGa4nei+j20rOSeDeP5Of12XVm7TGUd4dJA9RDitfE=
-github.com/cheekybits/genny v1.0.0/go.mod h1:+tQajlRqAUrPI7DOSpB0XAqZYtQakVtB7wXkRAgjxjQ=
-github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
-github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
-github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
-github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
-github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
-github.com/coreos/go-systemd v0.0.0-20181012123002-c6f51f82210d/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
+github.com/BurntSushi/toml v1.3.2 h1:o7IhLm0Msx3BaB+n3Ag7L8EVlByGnpq14C4YWiu/gL8=
+github.com/BurntSushi/toml v1.3.2/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=
+github.com/Workiva/go-datastructures v1.1.3 h1:LRdRrug9tEuKk7TGfz/sct5gjVj44G9pfqDt4qm7ghw=
+github.com/Workiva/go-datastructures v1.1.3/go.mod h1:1yZL+zfsztete+ePzZz/Zb1/t5BnDuE2Ya2MMGhzP6A=
+github.com/andybalholm/brotli v1.1.0 h1:eLKJA0d02Lf0mVpIDgYnqXcUn0GqVmEFny3VuID1U3M=
+github.com/andybalholm/brotli v1.1.0/go.mod h1:sms7XGricyQI9K10gOSf56VKKWS4oLer58Q+mhRPtnY=
+github.com/bytedance/sonic v1.5.0/go.mod h1:ED5hyg4y6t3/9Ku1R6dU/4KyJ48DZ4jPhfY1O2AihPM=
+github.com/bytedance/sonic v1.10.0-rc/go.mod h1:ElCzW+ufi8qKqNW0FY314xriJhyJhuoJ3gFZdAHF7NM=
+github.com/bytedance/sonic v1.11.3 h1:jRN+yEjakWh8aK5FzrciUHG8OFXK+4/KrAX/ysEtHAA=
+github.com/bytedance/sonic v1.11.3/go.mod h1:iZcSUejdk5aukTND/Eu/ivjQuEL0Cu9/rf50Hi0u/g4=
+github.com/chenzhuoyu/base64x v0.0.0-20211019084208-fb5309c8db06/go.mod h1:DH46F32mSOjUmXrMHnKwZdA8wcEefY7UVqBKYGjpdQY=
+github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311/go.mod h1:b583jCggY9gE99b6G5LEC39OIiVsWj+R97kbl5odCEk=
+github.com/chenzhuoyu/base64x v0.0.0-20230717121745-296ad89f973d h1:77cEq6EriyTZ0g/qfRdp61a3Uu/AWrgIq2s0ClJV1g0=
+github.com/chenzhuoyu/base64x v0.0.0-20230717121745-296ad89f973d/go.mod h1:8EPpVsBuRksnlj1mLy4AWzRNQYxauNi62uWcE3to6eA=
+github.com/chenzhuoyu/iasm v0.9.0/go.mod h1:Xjy2NpN3h7aUqeqM+woSuuvxmIe6+DDsiNLIrkAmYog=
+github.com/chenzhuoyu/iasm v0.9.1 h1:tUHQJXo3NhBqw6s33wkGn9SP3bvrWLdlVIJ3hQBL7P0=
+github.com/chenzhuoyu/iasm v0.9.1/go.mod h1:Xjy2NpN3h7aUqeqM+woSuuvxmIe6+DDsiNLIrkAmYog=
+github.com/chzyer/logex v1.2.0/go.mod h1:9+9sk7u7pGNWYMkh0hdiL++6OeibzJccyQU4p4MedaY=
+github.com/chzyer/readline v1.5.0/go.mod h1:x22KAscuvRqlLoK9CsoYsmxoXZMMFVyOl86cAH8qUic=
+github.com/chzyer/test v0.0.0-20210722231415-061457976a23/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
+github.com/cloudflare/circl v1.3.7 h1:qlCDlTPz2n9fu58M0Nh1J/JzcFpfgkFHHX3O35r5vcU=
+github.com/cloudflare/circl v1.3.7/go.mod h1:sRTcRWXGLrKw6yIGJ+l7amYJFfAXbZG0kBSc8r4zxgA=
+github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
-github.com/dgryski/go-metro v0.0.0-20200812162917-85c65e2d0165 h1:BS21ZUJ/B5X2UVUbczfmdWH7GapPWAhxcMsDnjJTU1E=
-github.com/dgryski/go-metro v0.0.0-20200812162917-85c65e2d0165/go.mod h1:c9O8+fpSOX1DM8cPNSkX/qsBWdkD4yd2dpciOWQjpBw=
-github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
-github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
-github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
-github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=
-github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=
-github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
-github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc=
+github.com/dgryski/go-metro v0.0.0-20211217172704-adc40b04c140 h1:y7y0Oa6UawqTFPCDw9JG6pdKt4F9pAhHv0B7FMGaGD0=
+github.com/dgryski/go-metro v0.0.0-20211217172704-adc40b04c140/go.mod h1:c9O8+fpSOX1DM8cPNSkX/qsBWdkD4yd2dpciOWQjpBw=
+github.com/dlclark/regexp2 v1.4.1-0.20201116162257-a2a8dda75c91/go.mod h1:2pZnwuY/m+8K6iRw6wQdMtk+rH5tNGR1i55kozfMjCc=
+github.com/dlclark/regexp2 v1.7.0 h1:7lJfhqlPssTb1WQx4yvTHN0uElPEv52sbaECrAQxjAo=
+github.com/dlclark/regexp2 v1.7.0/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8=
+github.com/dop251/goja v0.0.0-20211022113120-dc8c55024d06/go.mod h1:R9ET47fwRVRPZnOGvHxxhuZcbrMCuiqOz3Rlrh4KSnk=
+github.com/dop251/goja v0.0.0-20240220182346-e401ed450204 h1:O7I1iuzEA7SG+dK8ocOBSlYAA9jBUmCYl/Qa7ey7JAM=
+github.com/dop251/goja v0.0.0-20240220182346-e401ed450204/go.mod h1:QMWlm50DNe14hD7t24KEqZuUdC9sOTy8W6XbCU1mlw4=
+github.com/dop251/goja_nodejs v0.0.0-20210225215109-d91c329300e7/go.mod h1:hn7BA7c8pLvoGndExHudxTDKZ84Pyvv+90pbBjbTz0Y=
+github.com/dop251/goja_nodejs v0.0.0-20211022123610-8dd9abb0616d/go.mod h1:DngW8aVqWbuLRMHItjPUyqdj+HWPvnQe8V8y1nDpIbM=
+github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY=
+github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto=
+github.com/francoispqt/gojay v1.2.13 h1:d2m3sFjloqoIUQU3TsHBgj6qg/BVGlTBeHDUmyJnXKk=
github.com/francoispqt/gojay v1.2.13/go.mod h1:ehT5mTG4ua4581f1++1WLG0vPdaA9HaiDsoyrBGkyDY=
-github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
-github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4=
-github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
-github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
-github.com/ghodss/yaml v1.0.1-0.20190212211648-25d852aebe32 h1:Mn26/9ZMNWSw9C9ERFA1PUxfmGpolnw2v0bKOREu5ew=
-github.com/ghodss/yaml v1.0.1-0.20190212211648-25d852aebe32/go.mod h1:GIjDIg/heH5DOkXY3YJ/wNhfHsQHoXGjl8G8amsYQ1I=
-github.com/gin-contrib/sessions v0.0.3 h1:PoBXki+44XdJdlgDqDrY5nDVe3Wk7wDV/UCOuLP6fBI=
-github.com/gin-contrib/sessions v0.0.3/go.mod h1:8C/J6cad3Il1mWYYgtw0w+hqasmpvy25mPkXdOgeB9I=
+github.com/gabriel-vasile/mimetype v1.4.3 h1:in2uUcidCuFcDKtdcBxlR0rJ1+fsokWf+uqxgUFjbI0=
+github.com/gabriel-vasile/mimetype v1.4.3/go.mod h1:d8uq/6HKRL6CGdk+aubisF/M5GcPfT7nKyLpA0lbSSk=
+github.com/ghodss/yaml v1.0.1-0.20220118164431-d8423dcdf344 h1:Arcl6UOIS/kgO2nW3A65HN+7CMjSDP/gofXL4CZt1V4=
+github.com/ghodss/yaml v1.0.1-0.20220118164431-d8423dcdf344/go.mod h1:GIjDIg/heH5DOkXY3YJ/wNhfHsQHoXGjl8G8amsYQ1I=
+github.com/gin-contrib/sessions v1.0.0 h1:r5GLta4Oy5xo9rAwMHx8B4wLpeRGHMdz9NafzJAdP8Y=
+github.com/gin-contrib/sessions v1.0.0/go.mod h1:DN0f4bvpqMQElDdi+gNGScrP2QEI04IErRyMFyorUOI=
github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE=
github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI=
-github.com/gin-gonic/gin v1.5.0/go.mod h1:Nd6IXA8m5kNZdNEHMBd93KT+mdY3+bewLgRvmCsR2Do=
-github.com/gin-gonic/gin v1.7.1 h1:qC89GU3p8TvKWMAVhEpmpB2CIb1hnqt2UdKZaP93mS8=
-github.com/gin-gonic/gin v1.7.1/go.mod h1:jD2toBW3GZUr5UMcdrwQA10I7RuaFOl/SGeDjXkfUtY=
-github.com/gliderlabs/ssh v0.1.1/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0=
-github.com/globalsign/mgo v0.0.0-20181015135952-eeefdecb41b8/go.mod h1:xkRDCp4j0OGD1HRkm4kmhM+pmpv3AKq5SU7GMg4oO/Q=
-github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q=
-github.com/go-ole/go-ole v1.2.5 h1:t4MGB5xEDZvXI+0rMjjsfBsD7yAgp/s9ZDkL1JndXwY=
-github.com/go-ole/go-ole v1.2.5/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0=
-github.com/go-playground/assert/v2 v2.0.1 h1:MsBgLAaY856+nPRTKrp3/OZK38U/wa0CcBYNjji3q3A=
-github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
-github.com/go-playground/locales v0.12.1/go.mod h1:IUMDtCfWo/w/mtMfIE/IG2K+Ey3ygWanZIBtBW0W2TM=
-github.com/go-playground/locales v0.13.0 h1:HyWk6mgj5qFqCT5fjGBuRArbVDfE4hi8+e8ceBS/t7Q=
-github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8=
-github.com/go-playground/universal-translator v0.16.0/go.mod h1:1AnU7NaIRDWWzGEKwgtJRd2xk99HeFyHw3yid4rvQIY=
-github.com/go-playground/universal-translator v0.17.0 h1:icxd5fm+REJzpZx7ZfpaD876Lmtgy7VtROAbHHXk8no=
-github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA=
-github.com/go-playground/validator/v10 v10.4.1 h1:pH2c5ADXtd66mxoE0Zm9SUhxE20r7aM3F26W0hOn+GE=
-github.com/go-playground/validator/v10 v10.4.1/go.mod h1:nlOn6nFhuKACm19sB/8EGNn9GlaMV7XkbRSipzJ0Ii4=
+github.com/gin-gonic/gin v1.9.1 h1:4idEAncQnU5cB7BeOkPtxjfCSye0AAm1R0RVIqJ+Jmg=
+github.com/gin-gonic/gin v1.9.1/go.mod h1:hPrL7YrpYKXt5YId3A/Tnip5kqbEAP+KLuI3SUcPTeU=
+github.com/glebarez/go-sqlite v1.21.2 h1:3a6LFC4sKahUunAmynQKLZceZCOzUthkRkEAl9gAXWo=
+github.com/glebarez/go-sqlite v1.21.2/go.mod h1:sfxdZyhQjTM2Wry3gVYWaW072Ri1WMdWJi0k6+3382k=
+github.com/glebarez/sqlite v1.11.0 h1:wSG0irqzP6VurnMEpFGer5Li19RpIRi2qvQz++w0GMw=
+github.com/glebarez/sqlite v1.11.0/go.mod h1:h8/o8j5wiAsqSPoWELDUdJXhjAhsVliSn7bWZjOhrgQ=
+github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY=
+github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0=
+github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s=
+github.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
+github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA=
+github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY=
+github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY=
+github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY=
+github.com/go-playground/validator/v10 v10.19.0 h1:ol+5Fu+cSq9JD7SoSqe04GMI92cbn0+wvQ3bZ8b/AU4=
+github.com/go-playground/validator/v10 v10.19.0/go.mod h1:dbuPbCMFw/DrkbEynArYaCwl3amGuJotoKCe95atGMM=
+github.com/go-sourcemap/sourcemap v2.1.3+incompatible h1:W1iEw64niKVGogNgBN3ePyLFfuisuzeidWPMPWmECqU=
+github.com/go-sourcemap/sourcemap v2.1.3+incompatible/go.mod h1:F8jJfvm2KbVjc5NqelyYJmf/v5J0dwNLS2mL4sNA1Jg=
+github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI=
+github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls=
github.com/go-telegram-bot-api/telegram-bot-api/v5 v5.5.1 h1:wG8n/XJQ07TmjbITcGiUaOtXxdrINDz1b0J1w0SzqDc=
github.com/go-telegram-bot-api/telegram-bot-api/v5 v5.5.1/go.mod h1:A2S0CWkNylc2phvKXWBBdD3K0iGnDBGbzRpISP2zBl8=
-github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
-github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
-github.com/golang/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:tluoj9z5200jBnyusfRPU2LqT6J+DAorxEvtC7LHB+E=
-github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
-github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
-github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4=
-github.com/golang/mock v1.5.0 h1:jlYHihg//f7RRwuPfptm04yp4s7O6Kw8EZiVYIGcH0g=
-github.com/golang/mock v1.5.0/go.mod h1:CWnOUgYIOo4TcNZ0wHX3YZCqsaM1I1Jvs6v3mP3KVu8=
-github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
-github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
-github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
-github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
-github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
-github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=
-github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs=
-github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w=
-github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
-github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8=
-github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
-github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
-github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw=
-github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
-github.com/gomodule/redigo v2.0.0+incompatible/go.mod h1:B4C85qUVwatsJoIUNIfCRsp7qO0iAmpGFZ4EELWSbC4=
-github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
-github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
-github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
-github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
-github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
-github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
-github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
-github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU=
-github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
-github.com/google/go-github v17.0.0+incompatible/go.mod h1:zLgOLi98H3fifZn+44m+umXrS52loVEgC2AApnigrVQ=
-github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck=
+github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU=
+github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
+github.com/golang/mock v1.7.0-rc.1 h1:YojYx61/OLFsiv6Rw1Z96LpldJIy31o+UHmwAUMJ6/U=
+github.com/golang/mock v1.7.0-rc.1/go.mod h1:s42URUywIqd+OcERslBJvOjepvNymP31m3q8d/GkuRs=
+github.com/google/btree v1.1.2 h1:xf4v41cLI2Z6FxbKm+8Bu+m8ifhj15JuZ9sa0jZCMUU=
+github.com/google/btree v1.1.2/go.mod h1:qOPhT0dTNdNzV6Z/lhRX0YXUafgPLFUh+gZMl761Gm4=
+github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
+github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
-github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
-github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
-github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
-github.com/googleapis/gax-go v2.0.0+incompatible/go.mod h1:SFVmujtThgffbyetf+mdk2eWhX2bMyUtNHzFKcPA9HY=
-github.com/googleapis/gax-go/v2 v2.0.3/go.mod h1:LLvjysVCY1JZeum8Z6l8qUty8fiNwE08qbEPm1M08qg=
-github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
-github.com/gorilla/context v1.1.1 h1:AWwleXJkX/nhcU9bZSnZoi3h/qGYqQAGhq6zZe/aQW8=
-github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg=
-github.com/gorilla/securecookie v1.1.1 h1:miw7JPhV+b/lAHSXz4qd/nN9jRiAFV5FwjeKyCS8BvQ=
-github.com/gorilla/securecookie v1.1.1/go.mod h1:ra0sb63/xPlUeL+yeDciTfxMRAA+MP+HVt/4epWDjd4=
-github.com/gorilla/sessions v1.1.1/go.mod h1:8KCfur6+4Mqcc6S0FEfKuN15Vl5MgXW92AE8ovaJD0w=
-github.com/gorilla/sessions v1.1.3 h1:uXoZdcdA5XdXF3QzuSlheVRUvjl+1rKY7zBXL68L9RU=
-github.com/gorilla/sessions v1.1.3/go.mod h1:8KCfur6+4Mqcc6S0FEfKuN15Vl5MgXW92AE8ovaJD0w=
-github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc=
-github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
-github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA=
-github.com/grpc-ecosystem/grpc-gateway v1.5.0/go.mod h1:RSKVYQBd5MCa4OVpNdGskqpgL2+G+NZTnrVHpWWfpdw=
-github.com/h12w/go-socks5 v0.0.0-20200522160539-76189e178364/go.mod h1:eDJQioIyy4Yn3MVivT7rv/39gAJTrA7lgmYr8EW950c=
-github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
-github.com/jellevandenhooff/dkim v0.0.0-20150330215556-f50fe3d243e1/go.mod h1:E0B/fFc00Y+Rasa88328GlI/XbtyysCtTHZS8h7IrBU=
+github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0=
+github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
+github.com/google/pprof v0.0.0-20230207041349-798e818bf904/go.mod h1:uglQLonpP8qtYCYyzA+8c/9qtqgA3qsXGYqCPKARAFg=
+github.com/google/pprof v0.0.0-20240227163752-401108e1b7e7 h1:y3N7Bm7Y9/CtpiVkw/ZWj6lSlDF3F74SfKwfTCer72Q=
+github.com/google/pprof v0.0.0-20240227163752-401108e1b7e7/go.mod h1:czg5+yv1E0ZGTi6S6vVK1mke0fV+FaUhNGcd6VRS9Ik=
+github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
+github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
+github.com/gorilla/context v1.1.2 h1:WRkNAv2uoa03QNIc1A6u4O7DAGMUVoopZhkiXWA2V1o=
+github.com/gorilla/context v1.1.2/go.mod h1:KDPwT9i/MeWHiLl90fuTgrt4/wPcv75vFAZLaOOcbxM=
+github.com/gorilla/securecookie v1.1.2 h1:YCIWL56dvtr73r6715mJs5ZvhtnY73hBvEF8kXD8ePA=
+github.com/gorilla/securecookie v1.1.2/go.mod h1:NfCASbcHqRSY+3a8tlWJwsQap2VX5pwzwo4h3eOamfo=
+github.com/gorilla/sessions v1.2.2 h1:lqzMYz6bOfvn2WriPUjNByzeXIlVzURcPmgMczkmTjY=
+github.com/gorilla/sessions v1.2.2/go.mod h1:ePLdVu+jbEgHH+KWw8I1z2wqd0BAdAQh/8LRvBeoNcQ=
+github.com/gorilla/websocket v1.5.1 h1:gmztn0JnHVt9JZquRuzLw3g4wouNVzKL15iLr/zn/QY=
+github.com/gorilla/websocket v1.5.1/go.mod h1:x3kM2JMyaluk02fnUJpQuwD2dCS5NDG2ZHL0uE0tcaY=
+github.com/ianlancetaylor/demangle v0.0.0-20220319035150-800ac71e25c2/go.mod h1:aYm2/VgdVmcIU8iMfdMvDMsRAQjcfZSKFby6HOFvi/w=
github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E=
github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc=
-github.com/jinzhu/now v1.1.1/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
-github.com/jinzhu/now v1.1.2 h1:eVKgfIdy9b6zbWBMgFpfDPoAMifwSZagU9HmEU6zgiI=
-github.com/jinzhu/now v1.1.2/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
-github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
-github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
-github.com/json-iterator/go v1.1.9 h1:9yzud/Ht36ygwatGx56VwCZtlI/2AD15T1X2sjSuGns=
-github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
-github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
-github.com/kidstuff/mongostore v0.0.0-20181113001930-e650cd85ee4b/go.mod h1:g2nVr8KZVXJSS97Jo8pJ0jgq29P6H7dG0oplUA86MQw=
-github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
-github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
+github.com/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ=
+github.com/jinzhu/now v1.1.5/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
+github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
+github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
+github.com/klauspost/compress v1.17.7 h1:ehO88t2UGzQK66LMdE8tibEd1ErmzZjNEqWkjLAKQQg=
+github.com/klauspost/compress v1.17.7/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw=
+github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
+github.com/klauspost/cpuid/v2 v2.2.7 h1:ZWSB3igEs+d0qvnxR/ZBzXVmxkgt8DdzP6m9pfuVLDM=
+github.com/klauspost/cpuid/v2 v2.2.7/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws=
+github.com/knz/go-libedit v1.10.1/go.mod h1:MZTVkCWyz0oBc7JOWP3wNAzd002ZbM/5hgShxwh4x8M=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
+github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
+github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
-github.com/kr/pty v1.1.3/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
-github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
-github.com/leodido/go-urn v1.1.0/go.mod h1:+cyI34gQWZcE1eQU7NVgKkkzdXDQHr1dBMtdAPozLkw=
-github.com/leodido/go-urn v1.2.0 h1:hpXL4XnriNwQ/ABnpepYM/1vCLWNDfUNts8dX3xTG6Y=
-github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII=
-github.com/lucas-clemente/quic-go v0.20.0 h1:FSU3YN5VnLafHR27Ejs1r1CYMS7XMyIVDzRewkDLNBw=
-github.com/lucas-clemente/quic-go v0.20.0/go.mod h1:fZq/HUDIM+mW6X6wtzORjC0E/WDBMKe5Hf9bgjISwLk=
-github.com/lunixbochs/vtclean v1.0.0/go.mod h1:pHhQNgMf3btfWnGBVipUOjRYhoOsdGqdm/+2c2E2WMI=
-github.com/mailru/easyjson v0.0.0-20190312143242-1de009706dbe/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
-github.com/marten-seemann/qpack v0.2.1/go.mod h1:F7Gl5L1jIgN1D11ucXefiuJS9UMVP2opoCp2jDKb7wc=
-github.com/marten-seemann/qtls-go1-15 v0.1.4 h1:RehYMOyRW8hPVEja1KBVsFVNSm35Jj9Mvs5yNoZZ28A=
-github.com/marten-seemann/qtls-go1-15 v0.1.4/go.mod h1:GyFwywLKkRt+6mfU99csTEY1joMZz5vmB1WNZH3P81I=
-github.com/marten-seemann/qtls-go1-16 v0.1.3 h1:XEZ1xGorVy9u+lJq+WXNE+hiqRYLNvJGYmwfwKQN2gU=
-github.com/marten-seemann/qtls-go1-16 v0.1.3/go.mod h1:gNpI2Ol+lRS3WwSOtIUUtRwZEQMXjYK+dQSBFbethAk=
-github.com/mattn/go-isatty v0.0.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2yME+cCiQ=
-github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY=
-github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
-github.com/mattn/go-sqlite3 v1.14.5 h1:1IdxlwTNazvbKJQSxoJ5/9ECbEeaTTyeU7sEAZ5KKTQ=
-github.com/mattn/go-sqlite3 v1.14.5/go.mod h1:WVKg1VTActs4Qso6iwGbiFih2UIHo0ENGwNd0Lj+XmI=
-github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
-github.com/memcachier/mc v2.0.1+incompatible/go.mod h1:7bkvFE61leUBvXz+yxsOnGBQSZpBSPIMUQSmmSHvuXc=
-github.com/microcosm-cc/bluemonday v1.0.1/go.mod h1:hsXNsILzKxV+sX77C5b8FSuKF00vh2OMYv+xgHpAMF4=
-github.com/miekg/dns v1.1.41 h1:WMszZWJG0XmzbK9FEmzH2TVcqYzFesusSIB41b8KHxY=
-github.com/miekg/dns v1.1.41/go.mod h1:p6aan82bvRIyn+zDIv9xYNUpwa73JcSh9BKwknJysuI=
+github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
+github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ=
+github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI=
+github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
+github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
+github.com/mattn/go-sqlite3 v1.14.17 h1:mCRHCLDUBXgpKAqIKsaAaAsrAlbkeomtRFKXh2L6YIM=
+github.com/mattn/go-sqlite3 v1.14.17/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg=
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
-github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
-github.com/modern-go/reflect2 v1.0.1 h1:9f412s+6RmYXLWZSEzVVgPGK7C2PphHj5RJrvfx9AWI=
-github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
-github.com/neelance/astrewrite v0.0.0-20160511093645-99348263ae86/go.mod h1:kHJEU3ofeGjhHklVoIGuVj85JJwZ6kWPaJwCIxgnFmo=
-github.com/neelance/sourcemap v0.0.0-20151028013722-8c68805598ab/go.mod h1:Qr6/a/Q4r9LP1IltGz7tA7iOK1WonHEYhu1HRBA7ZiM=
-github.com/nicksnyder/go-i18n/v2 v2.1.2 h1:QHYxcUJnGHBaq7XbvgunmZ2Pn0focXFqTD61CkH146c=
-github.com/nicksnyder/go-i18n/v2 v2.1.2/go.mod h1:d++QJC9ZVf7pa48qrsRWhMJ5pSHIPmS3OLqK1niyLxs=
-github.com/nxadm/tail v1.4.4 h1:DQuhQpB1tVlglWS2hLQ5OV6B5r8aGxSrPc5Qo6uTN78=
-github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A=
-github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
-github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk=
-github.com/onsi/ginkgo v1.14.0 h1:2mOpI4JVVPBN+WQRa0WKH2eXR+Ey+uK4n7Zj0aYpIQA=
-github.com/onsi/ginkgo v1.14.0/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY=
-github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
-github.com/onsi/gomega v1.10.1 h1:o0+MgICZLuZ7xjH7Vx6zS/zcu93/BEp1VwkIW1mEXCE=
-github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
+github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
+github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
+github.com/nicksnyder/go-i18n/v2 v2.4.0 h1:3IcvPOAvnCKwNm0TB0dLDTuawWEj+ax/RERNC+diLMM=
+github.com/nicksnyder/go-i18n/v2 v2.4.0/go.mod h1:nxYSZE9M0bf3Y70gPQjN9ha7XNHX7gMc814+6wVyEI4=
+github.com/onsi/ginkgo/v2 v2.16.0 h1:7q1w9frJDzninhXxjZd+Y/x54XNjG/UlRLIYPZafsPM=
+github.com/onsi/ginkgo/v2 v2.16.0/go.mod h1:llBI3WDLL9Z6taip6f33H76YcWtJv+7R3HigUjbIBOs=
github.com/op/go-logging v0.0.0-20160315200505-970db520ece7 h1:lDH9UUVJtmYCjyT0CI4q8xvlXPxeZ0gYCVvWbmPlp88=
github.com/op/go-logging v0.0.0-20160315200505-970db520ece7/go.mod h1:HzydrMdWErDVzsI23lYNej1Htcns9BCg93Dk0bBINWk=
-github.com/openzipkin/zipkin-go v0.1.1/go.mod h1:NtoC/o8u3JlF1lSlyPNswIbeQH9bJTmOf0Erfk+hxe8=
-github.com/pelletier/go-toml v1.8.1 h1:1Nf83orprkJyknT6h7zbuEGUEjcyVlCxSUGTENmNCRM=
-github.com/pelletier/go-toml v1.8.1/go.mod h1:T2/BmBdy8dvIRq1a/8aqjN41wvWlN4lrapLU/GW4pbc=
-github.com/phayes/freeport v0.0.0-20180830031419-95f893ade6f2/go.mod h1:iIss55rKnNBTvrwdmkUpLnDpZoAHvWaiq5+iMmen4AE=
+github.com/pelletier/go-toml v1.9.5 h1:4yBQzkHv+7BHq2PQUZF3Mx0IYxG7LsP222s7Agd3ve8=
+github.com/pelletier/go-toml v1.9.5/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c=
+github.com/pelletier/go-toml/v2 v2.2.0 h1:QLgLl2yMN7N+ruc31VynXs1vhMZa7CeHHejIeBAsoHo=
+github.com/pelletier/go-toml/v2 v2.2.0/go.mod h1:1t835xjRzz80PqgE6HHgN2JOsmgYu/h4qDAS4n929Rs=
github.com/philhofer/fwd v1.1.1/go.mod h1:gk3iGcWd9+svBvR0sR+KPcfE+RNWozjowpeBVG3ZVNU=
-github.com/pires/go-proxyproto v0.5.0 h1:A4Jv4ZCaV3AFJeGh5mGwkz4iuWUYMlQ7IoO/GTuSuLo=
-github.com/pires/go-proxyproto v0.5.0/go.mod h1:Odh9VFOZJCf9G8cLW5o435Xf1J95Jw9Gw5rnCjcwzAY=
-github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
+github.com/pires/go-proxyproto v0.7.0 h1:IukmRewDQFWC7kfnb66CSomk2q/seBuilHBYFwyq0Hs=
+github.com/pires/go-proxyproto v0.7.0/go.mod h1:Vz/1JPY/OACxWGQNIRY2BeyDmpoaWmEP40O9LbuiFR4=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
-github.com/prometheus/client_golang v0.8.0/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
-github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
-github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
-github.com/prometheus/common v0.0.0-20180801064454-c7de2306084e/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro=
-github.com/prometheus/procfs v0.0.0-20180725123919-05ee40e3a273/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
-github.com/quasoft/memstore v0.0.0-20180925164028-84a050167438/go.mod h1:wTPjTepVu7uJBYgZ0SdWHQlIas582j6cn2jgk4DDdlg=
-github.com/refraction-networking/utls v0.0.0-20201210053706-2179f286686b h1:lzo71oHzQEz0fKMSjR0BpVzuh2hOHvJTxnN3Rnikmtg=
-github.com/refraction-networking/utls v0.0.0-20201210053706-2179f286686b/go.mod h1:tz9gX959MEFfFN5whTIocCLUG57WiILqtdVxI8c6Wj0=
+github.com/quic-go/quic-go v0.42.0 h1:uSfdap0eveIl8KXnipv9K7nlwZ5IqLlYOpJ58u5utpM=
+github.com/quic-go/quic-go v0.42.0/go.mod h1:132kz4kL3F9vxhW3CtQJLDVwcFe5wdWeJXXijhsO57M=
+github.com/refraction-networking/utls v1.6.3 h1:MFOfRN35sSx6K5AZNIoESsBuBxS2LCgRilRIdHb6fDc=
+github.com/refraction-networking/utls v1.6.3/go.mod h1:yil9+7qSl+gBwJqztoQseO6Pr3h62pQoY1lXiNR/FPs=
+github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo=
+github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec h1:W09IVJc94icq4NjY3clb7Lk8O1qJ8BdBEF8z0ibU0rE=
+github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo=
+github.com/riobard/go-bloom v0.0.0-20200614022211-cdc8013cb5b3 h1:f/FNXud6gA3MNr8meMVVGxhp+QBTqY91tM8HjEuMjGg=
+github.com/riobard/go-bloom v0.0.0-20200614022211-cdc8013cb5b3/go.mod h1:HgjTstvQsPGkxUsCd2KWxErBblirPizecHcpD3ffK+s=
+github.com/robertkrimen/otto v0.4.0 h1:/c0GRrK1XDPcgIasAsnlpBT5DelIeB9U/Z/JCQsgr7E=
+github.com/robertkrimen/otto v0.4.0/go.mod h1:uW9yN1CYflmUQYvAMS0m+ZiNo3dMzRUDQJX0jWbzgxw=
github.com/robfig/cron/v3 v3.0.1 h1:WdRxkvbJztn8LMz/QEvLN5sBU+xKpSqwwUO1Pjr4qDs=
github.com/robfig/cron/v3 v3.0.1/go.mod h1:eQICP3HwyT7UooqI/z+Ov+PtYAWygg1TEWWzGIFLtro=
-github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g=
-github.com/seiflotfy/cuckoofilter v0.0.0-20201222105146-bc6005554a0c h1:pqy40B3MQWYrza7YZXOXgl0Nf0QGFqrOC0BKae1UNAA=
-github.com/seiflotfy/cuckoofilter v0.0.0-20201222105146-bc6005554a0c/go.mod h1:bR6DqgcAl1zTcOX8/pE2Qkj9XO00eCNqmKb7lXP8EAg=
-github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo=
-github.com/shirou/gopsutil v3.21.3+incompatible h1:uenXGGa8ESCQq+dbgtl916dmg6PSAz2cXov0uORQ9v8=
-github.com/shirou/gopsutil v3.21.3+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA=
-github.com/shurcooL/component v0.0.0-20170202220835-f88ec8f54cc4/go.mod h1:XhFIlyj5a1fBNx5aJTbKoIq0mNaPvOagO+HjB3EtxrY=
-github.com/shurcooL/events v0.0.0-20181021180414-410e4ca65f48/go.mod h1:5u70Mqkb5O5cxEA8nxTsgrgLehJeAw6Oc4Ab1c/P1HM=
-github.com/shurcooL/github_flavored_markdown v0.0.0-20181002035957-2122de532470/go.mod h1:2dOwnU2uBioM+SGy2aZoq1f/Sd1l9OkAeAUvjSyvgU0=
-github.com/shurcooL/go v0.0.0-20180423040247-9e1955d9fb6e/go.mod h1:TDJrrUr11Vxrven61rcy3hJMUqaf/CLWYhHNPmT14Lk=
-github.com/shurcooL/go-goon v0.0.0-20170922171312-37c2f522c041/go.mod h1:N5mDOmsrJOB+vfqUK+7DmDyjhSLIIBnXo9lvZJj3MWQ=
-github.com/shurcooL/gofontwoff v0.0.0-20180329035133-29b52fc0a18d/go.mod h1:05UtEgK5zq39gLST6uB0cf3NEHjETfB4Fgr3Gx5R9Vw=
-github.com/shurcooL/gopherjslib v0.0.0-20160914041154-feb6d3990c2c/go.mod h1:8d3azKNyqcHP1GaQE/c6dDgjkgSx2BZ4IoEi4F1reUI=
-github.com/shurcooL/highlight_diff v0.0.0-20170515013008-09bb4053de1b/go.mod h1:ZpfEhSmds4ytuByIcDnOLkTHGUI6KNqRNPDLHDk+mUU=
-github.com/shurcooL/highlight_go v0.0.0-20181028180052-98c3abbbae20/go.mod h1:UDKB5a1T23gOMUJrI+uSuH0VRDStOiUVSjBTRDVBVag=
-github.com/shurcooL/home v0.0.0-20181020052607-80b7ffcb30f9/go.mod h1:+rgNQw2P9ARFAs37qieuu7ohDNQ3gds9msbT2yn85sg=
-github.com/shurcooL/htmlg v0.0.0-20170918183704-d01228ac9e50/go.mod h1:zPn1wHpTIePGnXSHpsVPWEktKXHr6+SS6x/IKRb7cpw=
-github.com/shurcooL/httperror v0.0.0-20170206035902-86b7830d14cc/go.mod h1:aYMfkZ6DWSJPJ6c4Wwz3QtW22G7mf/PEgaB9k/ik5+Y=
-github.com/shurcooL/httpfs v0.0.0-20171119174359-809beceb2371/go.mod h1:ZY1cvUeJuFPAdZ/B6v7RHavJWZn2YPVFQ1OSXhCGOkg=
-github.com/shurcooL/httpgzip v0.0.0-20180522190206-b1c53ac65af9/go.mod h1:919LwcH0M7/W4fcZ0/jy0qGght1GIhqyS/EgWGH2j5Q=
-github.com/shurcooL/issues v0.0.0-20181008053335-6292fdc1e191/go.mod h1:e2qWDig5bLteJ4fwvDAc2NHzqFEthkqn7aOZAOpj+PQ=
-github.com/shurcooL/issuesapp v0.0.0-20180602232740-048589ce2241/go.mod h1:NPpHK2TI7iSaM0buivtFUc9offApnI0Alt/K8hcHy0I=
-github.com/shurcooL/notifications v0.0.0-20181007000457-627ab5aea122/go.mod h1:b5uSkrEVM1jQUspwbixRBhaIjIzL2xazXp6kntxYle0=
-github.com/shurcooL/octicon v0.0.0-20181028054416-fa4f57f9efb2/go.mod h1:eWdoE5JD4R5UVWDucdOPg1g2fqQRq78IQa9zlOV1vpQ=
-github.com/shurcooL/reactions v0.0.0-20181006231557-f2e0b4ca5b82/go.mod h1:TCR1lToEk4d2s07G3XGfz2QrgHXg4RJBvjrOozvoWfk=
-github.com/shurcooL/sanitized_anchor_name v0.0.0-20170918181015-86672fcb3f95/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
-github.com/shurcooL/users v0.0.0-20180125191416-49c67e49c537/go.mod h1:QJTqeLYEDaXHZDBsXlPCDqdhQuJkuw4NOtaxYe3xii4=
-github.com/shurcooL/webdavfs v0.0.0-20170829043945-18c3829fa133/go.mod h1:hKmq5kWdCj2z2KEozexVbfEZIWiTjhE0+UjmZgPqehw=
-github.com/sourcegraph/annotate v0.0.0-20160123013949-f4cad6c6324d/go.mod h1:UdhH50NIW0fCiwBSr0co2m7BnFLdv4fQTgdqdJTHFeE=
-github.com/sourcegraph/syntaxhighlight v0.0.0-20170531221838-bd320f5d308e/go.mod h1:HuIsMU8RRBOtsCgI77wP899iHVBQpCmg4ErYMZB+2IA=
+github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc=
+github.com/sagernet/sing v0.3.8 h1:gm4JKalPhydMYX2zFOTnnd4TXtM/16WFRqSjMepYQQk=
+github.com/sagernet/sing v0.3.8/go.mod h1:+60H3Cm91RnL9dpVGWDPHt0zTQImO9Vfqt9a4rSambI=
+github.com/sagernet/sing-shadowsocks v0.2.6 h1:xr7ylAS/q1cQYS8oxKKajhuQcchd5VJJ4K4UZrrpp0s=
+github.com/sagernet/sing-shadowsocks v0.2.6/go.mod h1:j2YZBIpWIuElPFL/5sJAj470bcn/3QQ5lxZUNKLDNAM=
+github.com/seiflotfy/cuckoofilter v0.0.0-20220411075957-e3b120b3f5fb h1:XfLJSPIOUX+osiMraVgIrMR27uMXnRJWGm1+GL8/63U=
+github.com/seiflotfy/cuckoofilter v0.0.0-20220411075957-e3b120b3f5fb/go.mod h1:bR6DqgcAl1zTcOX8/pE2Qkj9XO00eCNqmKb7lXP8EAg=
+github.com/shirou/gopsutil v3.21.11+incompatible h1:+1+c1VGhc88SSonWP6foOcLhvnKlUeu/erjjvaPEYiI=
+github.com/shirou/gopsutil v3.21.11+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
-github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
+github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
+github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
+github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
-github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
-github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
-github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
-github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
-github.com/tarm/serial v0.0.0-20180830185346-98f6abe2eb07/go.mod h1:kDXzergiv9cbyO7IOYJZWg1U88JhDg3PB6klq9Hg2pA=
+github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
+github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
+github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
+github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
+github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
+github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/tinylib/msgp v1.1.5/go.mod h1:eQsjooMTnV42mHu917E26IogZ2930nFyBQdofk10Udg=
-github.com/tklauser/go-sysconf v0.3.5 h1:uu3Xl4nkLzQfXNsWn15rPc/HQCJKObbt1dKJeWp3vU4=
-github.com/tklauser/go-sysconf v0.3.5/go.mod h1:MkWzOF4RMCshBAMXuhXJs64Rte09mITnppBXY/rYEFI=
-github.com/tklauser/numcpus v0.2.2 h1:oyhllyrScuYI6g+h/zUvNXNp1wy7x8qQy3t/piefldA=
-github.com/tklauser/numcpus v0.2.2/go.mod h1:x3qojaO3uyYt0i56EW/VUYs7uBvdl2fkfZFu0T9wgjM=
+github.com/tklauser/go-sysconf v0.3.13 h1:GBUpcahXSpR2xN01jhkNAbTLRk2Yzgggk8IM08lq3r4=
+github.com/tklauser/go-sysconf v0.3.13/go.mod h1:zwleP4Q4OehZHGn4CYZDipCgg9usW5IJePewFCGVEa0=
+github.com/tklauser/numcpus v0.7.0 h1:yjuerZP127QG9m5Zh/mSO4wqurYil27tHrqwRoRjpr4=
+github.com/tklauser/numcpus v0.7.0/go.mod h1:bb6dMVcj8A42tSE7i32fsIUCbQNllK5iDguyOZRUzAY=
github.com/ttacon/chalk v0.0.0-20160626202418-22c06c80ed31/go.mod h1:onvgF043R+lC5RZ8IT9rBXDaEDnpnw/Cl+HFiw+v/7Q=
-github.com/ugorji/go v1.1.7 h1:/68gy2h+1mWMrwZFeD1kQialdSzAb432dtpeJ42ovdo=
-github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw=
-github.com/ugorji/go/codec v1.1.7 h1:2SvQaVZ1ouYrrKKwoSk2pzd4A9evlKJb9oTL+OaLUSs=
-github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY=
-github.com/viant/assertly v0.4.8/go.mod h1:aGifi++jvCrUaklKEKT0BU95igDNaqkvz+49uaYMPRU=
-github.com/viant/toolbox v0.24.0/go.mod h1:OxMCG57V0PXuIP2HNQrtJf2CjqdmbrOx5EkMILuUhzM=
-github.com/xtls/go v0.0.0-20201118062508-3632bf3b7499 h1:QHESTXtfgc1ABV+ArlbPVqUx9Ht5I0dDkYhxYoXFxNo=
-github.com/xtls/go v0.0.0-20201118062508-3632bf3b7499/go.mod h1:5TB2+k58gx4A4g2Nf5miSHNDF6CuAzHKpWBooLAshTs=
-github.com/xtls/xray-core v1.4.2 h1:D0Le+Qy9L/eY5LbUQfrk7WJ8wbODpQSW/ZRCg+BRe7c=
-github.com/xtls/xray-core v1.4.2/go.mod h1:DmL/9rOCliev/a6HciWEvSJVEhUF6C0EpD3clW8v0pc=
+github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI=
+github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08=
+github.com/ugorji/go/codec v1.2.12 h1:9LC83zGrHhuUA9l16C9AHXAqEV/2wBQ4nkvumAE65EE=
+github.com/ugorji/go/codec v1.2.12/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg=
+github.com/v2fly/ss-bloomring v0.0.0-20210312155135-28617310f63e h1:5QefA066A1tF8gHIiADmOVOV5LS43gt3ONnlEl3xkwI=
+github.com/v2fly/ss-bloomring v0.0.0-20210312155135-28617310f63e/go.mod h1:5t19P9LBIrNamL6AcMQOncg/r10y3Pc01AbHeMhwlpU=
+github.com/vishvananda/netlink v1.2.1-beta.2.0.20230316163032-ced5aaba43e3 h1:tkMT5pTye+1NlKIXETU78NXw0fyjnaNHmJyyLyzw8+U=
+github.com/vishvananda/netlink v1.2.1-beta.2.0.20230316163032-ced5aaba43e3/go.mod h1:cAAsePK2e15YDAMJNyOpGYEWNe4sIghTY7gpz4cX/Ik=
+github.com/vishvananda/netns v0.0.4 h1:Oeaw1EM2JMxD51g9uhtC0D7erkIjgmj8+JZc26m1YX8=
+github.com/vishvananda/netns v0.0.4/go.mod h1:SpkAiCQRtJ6TvvxPnOSyH3BMl6unz3xZlaprSwhNNJM=
+github.com/xtls/reality v0.0.0-20231112171332-de1173cf2b19 h1:capMfFYRgH9BCLd6A3Er/cH3A9Nz3CU2KwxwOQZIePI=
+github.com/xtls/reality v0.0.0-20231112171332-de1173cf2b19/go.mod h1:dm4y/1QwzjGaK17ofi0Vs6NpKAHegZky8qk6J2JJZAE=
+github.com/xtls/xray-core v1.8.10 h1:qxae6gSteonpPI7EZyOyqw5HmRVRzmU07qs0l1GNqz4=
+github.com/xtls/xray-core v1.8.10/go.mod h1:Mc1t+kLBPE5a1EpsUNKjMLviGz3Y0XywxeEraJZAMlI=
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
-go.opencensus.io v0.18.0/go.mod h1:vKdFvxhtzZ9onBp9VKHK8z/sRpBMnKAsufL7wlDrCOA=
-go.starlark.net v0.0.0-20210312235212-74c10e2c17dc h1:pVkptfeOTFfx+zXZo7HEHN3d5LmhatBFvHdm/f2QnpY=
-go.starlark.net v0.0.0-20210312235212-74c10e2c17dc/go.mod h1:t3mmBBPzAVvK0L0n1drDmrQsJ8FoIx4INCqVMTr/Zo0=
-go.uber.org/atomic v1.7.0 h1:ADUqmZGgLDDfbSL9ZmPxKTybcoEYHgpYfELNoN+7hsw=
-go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
-go4.org v0.0.0-20180809161055-417644f6feb5/go.mod h1:MkTOUMDaeVYJUOUsaDXIhWPZYa1yOyC1qaOBpL57BhE=
-golang.org/x/build v0.0.0-20190111050920-041ab4dc3f9d/go.mod h1:OWs+y06UdEOHN4y+MfF/py+xQ/tYqIWW03b70/CG9Rw=
-golang.org/x/crypto v0.0.0-20181030102418-4d3f4d9ffa16/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
+github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
+github.com/yusufpapurcu/wmi v1.2.4 h1:zFUKzehAFReQwLys1b/iSMl+JQGSCSjtVqQn9bBrPo0=
+github.com/yusufpapurcu/wmi v1.2.4/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0=
+go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE=
+go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0=
+go.uber.org/mock v0.4.0 h1:VcM4ZOtdbR4f6VXfiOpwpVJDL6lCReaZ6mw31wqh7KU=
+go.uber.org/mock v0.4.0/go.mod h1:a6FSlNadKUHUa9IP5Vyt1zh4fC7uAwxMutEAscFbkZc=
+go4.org/netipx v0.0.0-20231129151722-fdeea329fbba h1:0b9z3AuHCjxk0x/opv64kcgZLBseWJUpBw5I82+2U4M=
+go4.org/netipx v0.0.0-20231129151722-fdeea329fbba/go.mod h1:PLyyIXexvUFg3Owu6p/WfdlivPbZJsZdgWZlrGope/Y=
+golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8=
+golang.org/x/arch v0.7.0 h1:pskyeJh/3AmoQ8CPE95vxHLqp1G1GfGNXTmcl9NEKTc=
+golang.org/x/arch v0.7.0/go.mod h1:FEVrYAQjsQXMVJ1nsMoVVXPZg6p2JE2mx8psSWTDQys=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
-golang.org/x/crypto v0.0.0-20190313024323-a1f597ede03a/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
-golang.org/x/crypto v0.0.0-20200221231518-2aa609cf4a9d/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
-golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2 h1:It14KIkyBFYkHkwZ7k45minvA9aorojkyjGk9KJ5B/w=
-golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
-golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
-golang.org/x/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
-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-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
+golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
+golang.org/x/crypto v0.21.0 h1:X31++rzVUdKhX5sWmSOFZxx8UW/ldWx55cbf08iNAMA=
+golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs=
+golang.org/x/exp v0.0.0-20240222234643-814bf88cf225 h1:LfspQV/FYTatPTr/3HzIcmiUFH7PGP+OQ6mgDYo3yuQ=
+golang.org/x/exp v0.0.0-20240222234643-814bf88cf225/go.mod h1:CxmFvTBINI24O/j8iY7H1xHzx2i4OsyguNBmN/uPtqc=
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
-golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
-golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
-golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
-golang.org/x/net v0.0.0-20181029044818-c44066c5c816/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
-golang.org/x/net v0.0.0-20181106065722-10aee1819953/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
-golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
-golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
-golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
-golang.org/x/net v0.0.0-20190313220215-9f648a60d977/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
+golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
+golang.org/x/mod v0.16.0 h1:QX4fJ0Rr5cPQCF7O9lh9Se4pmwfwskqZfq5moyldzic=
+golang.org/x/mod v0.16.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
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-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
-golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
-golang.org/x/net v0.0.0-20210330230544-e57232859fb2 h1:nGCZOty+lVDsc4H2qPFksI5Se296+V+GhMiL/TzmYNk=
-golang.org/x/net v0.0.0-20210330230544-e57232859fb2/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
-golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
-golang.org/x/oauth2 v0.0.0-20181017192945-9dcd33a902f4/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
-golang.org/x/oauth2 v0.0.0-20181203162652-d668ce993890/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
-golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
-golang.org/x/perf v0.0.0-20180704124530-6e6d33e29852/go.mod h1:JLpeXjPJfIyPr5TlbXLkXWLhP8nz10XfvxElABhCtcw=
-golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
-golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
-golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
-golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
+golang.org/x/net v0.22.0 h1:9sGLhx7iRIHEiX0oAJ3MRZMUCElJgy7Br1nO+AMN3Tc=
+golang.org/x/net v0.22.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg=
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-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
-golang.org/x/sync v0.0.0-20210220032951-036812b2e83c h1:5KslGYwFpkhGh+Q16bwMP3cOontH8FOep7tGV86Y7SQ=
-golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
-golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
-golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
-golang.org/x/sys v0.0.0-20181029174526-d69651ed3497/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.6.0 h1:5BMeUDZ7vkXGfEr1x9B4bRcTH4lpkTkpdh0T/J+qjbQ=
+golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
-golang.org/x/sys v0.0.0-20190316082340-a2f829d7f35f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20201231184435-2d18734c6014/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20210303074136-134d130e1a04/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20210316164454-77fc1eacc6aa/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20210511113859-b0526f3d8744 h1:yhBbb4IRs2HS9PPlAg6DMC6mUOKexJBNsLf4Z+6En1Q=
-golang.org/x/sys v0.0.0-20210511113859-b0526f3d8744/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20220310020820-b874c991c1a5/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.18.0 h1:DBdB3niSjOA/O0blCZBqDefyWNYveAYMNF1Wum0DYQ4=
+golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
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/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
-golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
-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.6 h1:aRYxNxv6iGQlyVaZmk6ZgYEDa+Jg18DxebPSrd6bg1M=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
-golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
-golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
-golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
+golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
+golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ=
+golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
+golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
+golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk=
+golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
-golang.org/x/tools v0.0.0-20181030000716-a0a13e073c7b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
-golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
-golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
-golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
-golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
-golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20201022035929-9cf592e881e9/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
+golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
+golang.org/x/tools v0.19.0 h1:tfGCXNR1OsFG+sVdLAitlpjAvD/I6dHDKnYrpEZUHkw=
+golang.org/x/tools v0.19.0/go.mod h1:qoJWxmGSIBmAeriMx19ogtrEPrGtDbPK634QFIcLAhc=
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-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
-golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
-google.golang.org/api v0.0.0-20180910000450-7ca32eb868bf/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0=
-google.golang.org/api v0.0.0-20181030000543-1d582fd0359e/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0=
-google.golang.org/api v0.1.0/go.mod h1:UGEZY7KEX120AnNLIHFMKIo4obdJhkp2tPbaPlQx13Y=
-google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
-google.golang.org/appengine v1.2.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
-google.golang.org/appengine v1.3.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
-google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
-google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
-google.golang.org/genproto v0.0.0-20180831171423-11092d34479b/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
-google.golang.org/genproto v0.0.0-20181029155118-b69ba1387ce2/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
-google.golang.org/genproto v0.0.0-20181202183823-bd91e49a0898/go.mod h1:7Ep/1NZk928CDR8SjdVbjWNpdIf6nzjE3BTgJDr2Atg=
-google.golang.org/genproto v0.0.0-20190306203927-b5d61aea6440/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
-google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
-google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013 h1:+kGHl1aib/qcwaRi1CbqBZ1rk19r85MNUf8HaBghugY=
-google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
-google.golang.org/grpc v1.14.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw=
-google.golang.org/grpc v1.16.0/go.mod h1:0JHn/cJsOMiMfNA9+DeHDlAU7KAAB5GDlYFpa9MZMio=
-google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs=
-google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
-google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
-google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
-google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
-google.golang.org/grpc v1.36.1/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
-google.golang.org/grpc v1.38.0 h1:/9BgsAsa5nWe26HqOlvlgJnqBuktYOLCgjCPqsa56W0=
-google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM=
-google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
-google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
-google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
-google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE=
-google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=
-google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
-google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
-google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
-google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
-google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
-google.golang.org/protobuf v1.26.0 h1:bxAC2xTBsZGibn2RTntX0oH50xLsqy1OxA9tTL3p/lk=
-google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
+golang.zx2c4.com/wintun v0.0.0-20230126152724-0fa3db229ce2 h1:B82qJJgjvYKsXS9jeunTOisW56dUokqW/FOteYJJ/yg=
+golang.zx2c4.com/wintun v0.0.0-20230126152724-0fa3db229ce2/go.mod h1:deeaetjYA+DHMHg+sMSMI58GrEteJUUzzw7en6TJQcI=
+golang.zx2c4.com/wireguard v0.0.0-20231211153847-12269c276173 h1:/jFs0duh4rdb8uIfPMv78iAJGcPKDeqAFnaLBropIC4=
+golang.zx2c4.com/wireguard v0.0.0-20231211153847-12269c276173/go.mod h1:tkCQ4FQXmpAgYVh++1cq16/dH4QJtmvpRv19DWGAHSA=
+google.golang.org/genproto/googleapis/rpc v0.0.0-20240308144416-29370a3891b7 h1:em/y72n4XlYRtayY/cVj6pnVzHa//BDA1BdoO+z9mdE=
+google.golang.org/genproto/googleapis/rpc v0.0.0-20240308144416-29370a3891b7/go.mod h1:UCOku4NytXMJuLQE5VuqA5lX3PcHCBo8pxNyvkf4xBs=
+google.golang.org/grpc v1.63.2 h1:MUeiw1B2maTVZthpU5xvASfTh3LDbxHd6IJ6QQVU+xM=
+google.golang.org/grpc v1.63.2/go.mod h1:WAX/8DgncnokcFUldAxq7GeB5DXHDbMF+lLvDomNkRA=
+google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI=
+google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos=
+gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
-gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
-gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
-gopkg.in/go-playground/assert.v1 v1.2.1/go.mod h1:9RXL0bg/zibRAgZUYszZSwO/z8Y/a8bDuhia5mkpMnE=
-gopkg.in/go-playground/validator.v9 v9.29.1/go.mod h1:+c9/zcJMFNgbLvly1L1V+PpxWdVbfP1avr/N00E2vyQ=
-gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
-gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
-gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
-gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
-gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
-gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
-gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
-gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
+gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
+gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
+gopkg.in/sourcemap.v1 v1.0.5 h1:inv58fC9f9J3TK2Y2R1NPntXEn3/wjWHkonhIUODNTI=
+gopkg.in/sourcemap.v1 v1.0.5/go.mod h1:2RlvNNSMglmRrcvhfuzp4hQHwOtjxlbjX7UPY/GXb78=
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
-gopkg.in/yaml.v3 v3.0.0-20200605160147-a5ece683394c h1:grhR+C34yXImVGp7EzNk+DTIk+323eIUWOmEevy6bDo=
-gopkg.in/yaml.v3 v3.0.0-20200605160147-a5ece683394c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
-gorm.io/driver/sqlite v1.1.4 h1:PDzwYE+sI6De2+mxAneV9Xs11+ZyKV6oxD3wDGkaNvM=
-gorm.io/driver/sqlite v1.1.4/go.mod h1:mJCeTFr7+crvS+TRnWc5Z3UvwxUN1BGBLMrf5LA9DYw=
-gorm.io/gorm v1.20.7/go.mod h1:0HFTzE/SqkGTzK6TlDPPQbAYCluiVvhzoA1+aVyzenw=
-gorm.io/gorm v1.21.9 h1:INieZtn4P2Pw6xPJ8MzT0G4WUOsHq3RhfuDF1M6GW0E=
-gorm.io/gorm v1.21.9/go.mod h1:F+OptMscr0P2F2qU97WT1WimdH9GaQPoDW7AYd5i2Y0=
-grpc.go4.org v0.0.0-20170609214715-11d0a25b4919/go.mod h1:77eQGdRu53HpSqPFJFmuJdjuHRquDANNeA4x7B8WQ9o=
-h12.io/socks v1.0.2/go.mod h1:AIhxy1jOId/XCz9BO+EIgNL2rQiPTBNnOfnVnQ+3Eck=
-honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
-honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
-honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
-honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
-sourcegraph.com/sourcegraph/go-diff v0.5.0/go.mod h1:kuch7UrkMzY0X+p9CRK03kfuPQ2zzQcaEFbx8wA8rck=
-sourcegraph.com/sqs/pbtypes v0.0.0-20180604144634-d3ebe8f20ae4/go.mod h1:ketZ/q3QxT9HOBeFhu6RdvsftgpsbFHBF5Cas6cDKZ0=
+gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
+gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
+gorm.io/driver/sqlite v1.5.5 h1:7MDMtUZhV065SilG62E0MquljeArQZNfJnjd9i9gx3E=
+gorm.io/driver/sqlite v1.5.5/go.mod h1:6NgQ7sQWAIFsPrJJl1lSNSu2TABh0ZZ/zm5fosATavE=
+gorm.io/gorm v1.25.9 h1:wct0gxZIELDk8+ZqF/MVnHLkA1rvYlBWUMv2EdsK1g8=
+gorm.io/gorm v1.25.9/go.mod h1:hbnx/Oo0ChWMn1BIhpy1oYozzpM15i4YPuHDmfYtwg8=
+gvisor.dev/gvisor v0.0.0-20231104011432-48a6d7d5bd0b h1:yqkg3pTifuKukuWanp8spDsL4irJkHF5WI0J47hU87o=
+gvisor.dev/gvisor v0.0.0-20231104011432-48a6d7d5bd0b/go.mod h1:10sU+Uh5KKNv1+2x2A0Gvzt8FjD3ASIhorV3YsauXhk=
+lukechampine.com/blake3 v1.2.1 h1:YuqqRuaqsGV71BV/nm9xlI0MKUv4QC54jQnBChWbGnI=
+lukechampine.com/blake3 v1.2.1/go.mod h1:0OFRp7fBtAylGVCO40o87sbupkyIGgbpv1+M1k1LM6k=
+modernc.org/libc v1.22.5 h1:91BNch/e5B0uPbJFgqbxXuOnxBQjlS//icfQEGmvyjE=
+modernc.org/libc v1.22.5/go.mod h1:jj+Z7dTNX8fBScMVNRAYZ/jF91K8fdT2hYMThc3YjBY=
+modernc.org/mathutil v1.5.0 h1:rV0Ko/6SfM+8G+yKiyI830l3Wuz1zRutdslNoQ0kfiQ=
+modernc.org/mathutil v1.5.0/go.mod h1:mZW8CKdRPY1v87qxC/wUdX5O1qDzXMP5TH3wjfpga6E=
+modernc.org/memory v1.5.0 h1:N+/8c5rE6EqugZwHii4IFsaJ7MUhoWX07J5tC/iI5Ds=
+modernc.org/memory v1.5.0/go.mod h1:PkUhL0Mugw21sHPeskwZW4D6VscE/GQJOnIpCnW6pSU=
+modernc.org/sqlite v1.23.1 h1:nrSBg4aRQQwq59JpvGEQ15tNxoO5pX/kUjcRNwSAGQM=
+modernc.org/sqlite v1.23.1/go.mod h1:OrDj17Mggn6MhE+iPbBNf7RGKODDE9NFT0f3EwDzJqk=
+nullprogram.com/x/optparse v1.0.0/go.mod h1:KdyPE+Igbe0jQUrVfMqDMeJQIJZEuyV7pjYmp6pbG50=
+rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4=
diff --git a/logger/logger.go b/logger/logger.go
old mode 100644
new mode 100755
diff --git a/main.go b/main.go
old mode 100644
new mode 100755
index f5da0704b..5f2175f20
--- a/main.go
+++ b/main.go
@@ -52,12 +52,14 @@ func runWebServer() {
sigCh := make(chan os.Signal, 1)
//信号量捕获处理
- signal.Notify(sigCh, syscall.SIGHUP, syscall.SIGTERM, syscall.SIGKILL)
+ signal.Notify(sigCh, syscall.SIGQUIT, syscall.SIGHUP, syscall.SIGTERM, syscall.SIGKILL)
for {
sig := <-sigCh
switch sig {
case syscall.SIGHUP:
+ case syscall.SIGQUIT:
+ logger.Info("restart server ...")
err := server.Stop()
if err != nil {
logger.Warning("stop server err:", err)
diff --git a/media/2022-04-04_141259.png b/media/2022-04-04_141259.png
old mode 100644
new mode 100755
diff --git a/media/2022-04-17_110907.png b/media/2022-04-17_110907.png
old mode 100644
new mode 100755
diff --git a/media/2022-04-17_111321.png b/media/2022-04-17_111321.png
old mode 100644
new mode 100755
diff --git a/media/2022-04-17_111705.png b/media/2022-04-17_111705.png
old mode 100644
new mode 100755
diff --git a/media/2022-04-17_111910.png b/media/2022-04-17_111910.png
old mode 100644
new mode 100755
diff --git a/media/bda84fbc2ede834deaba1c173a932223.png b/media/bda84fbc2ede834deaba1c173a932223.png
old mode 100644
new mode 100755
diff --git a/media/d13ffd6a73f938d1037d0708e31433bf.png b/media/d13ffd6a73f938d1037d0708e31433bf.png
old mode 100644
new mode 100755
diff --git a/util/common/err.go b/util/common/err.go
old mode 100644
new mode 100755
diff --git a/util/common/format.go b/util/common/format.go
old mode 100644
new mode 100755
diff --git a/util/common/multi_error.go b/util/common/multi_error.go
old mode 100644
new mode 100755
diff --git a/util/common/stringUtil.go b/util/common/stringUtil.go
old mode 100644
new mode 100755
diff --git a/util/context.go b/util/context.go
old mode 100644
new mode 100755
diff --git a/util/json_util/json.go b/util/json_util/json.go
old mode 100644
new mode 100755
diff --git a/util/random/random.go b/util/random/random.go
old mode 100644
new mode 100755
diff --git a/util/reflect_util/reflect.go b/util/reflect_util/reflect.go
old mode 100644
new mode 100755
diff --git a/util/sys/a.s b/util/sys/a.s
old mode 100644
new mode 100755
diff --git a/util/sys/psutil.go b/util/sys/psutil.go
old mode 100644
new mode 100755
diff --git a/util/sys/sys_darwin.go b/util/sys/sys_darwin.go
old mode 100644
new mode 100755
diff --git a/util/sys/sys_linux.go b/util/sys/sys_linux.go
old mode 100644
new mode 100755
diff --git a/v2ui/db.go b/v2ui/db.go
old mode 100644
new mode 100755
index 2745b9de0..4a9f8ffc9
--- a/v2ui/db.go
+++ b/v2ui/db.go
@@ -1,7 +1,7 @@
package v2ui
import (
- "gorm.io/driver/sqlite"
+ "github.com/glebarez/sqlite"
"gorm.io/gorm"
"gorm.io/gorm/logger"
)
diff --git a/v2ui/models.go b/v2ui/models.go
old mode 100644
new mode 100755
diff --git a/v2ui/v2ui.go b/v2ui/v2ui.go
old mode 100644
new mode 100755
diff --git a/web/assets/ant-design-vue@1.7.2/antd-with-locales.min.js b/web/assets/ant-design-vue@1.7.2/antd-with-locales.min.js
old mode 100644
new mode 100755
diff --git a/web/assets/ant-design-vue@1.7.2/antd.less b/web/assets/ant-design-vue@1.7.2/antd.less
old mode 100644
new mode 100755
diff --git a/web/assets/ant-design-vue@1.7.2/antd.min.css b/web/assets/ant-design-vue@1.7.2/antd.min.css
old mode 100644
new mode 100755
diff --git a/web/assets/ant-design-vue@1.7.2/antd.min.js b/web/assets/ant-design-vue@1.7.2/antd.min.js
old mode 100644
new mode 100755
diff --git a/web/assets/axios/axios.min.js b/web/assets/axios/axios.min.js
old mode 100644
new mode 100755
diff --git a/web/assets/base64/base64.min.js b/web/assets/base64/base64.min.js
old mode 100644
new mode 100755
diff --git a/web/assets/clipboard/clipboard.min.js b/web/assets/clipboard/clipboard.min.js
old mode 100644
new mode 100755
diff --git a/web/assets/css/custom.css b/web/assets/css/custom.css
old mode 100644
new mode 100755
diff --git a/web/assets/element-ui@2.15.0/theme-chalk/display.css b/web/assets/element-ui@2.15.0/theme-chalk/display.css
old mode 100644
new mode 100755
diff --git a/web/assets/js/axios-init.js b/web/assets/js/axios-init.js
old mode 100644
new mode 100755
diff --git a/web/assets/js/model/models.js b/web/assets/js/model/models.js
old mode 100644
new mode 100755
index d15afdc67..544fb6ba2
--- a/web/assets/js/model/models.js
+++ b/web/assets/js/model/models.js
@@ -28,6 +28,7 @@ class Msg {
class DBInbound {
constructor(data) {
+
this.id = 0;
this.userId = 0;
this.up = 0;
@@ -84,7 +85,7 @@ class DBInbound {
}
get address() {
- let address = location.hostname;
+ let address = typeof location !== "undefined" ? location.hostname : "";
if (!ObjectUtil.isEmpty(this.listen) && this.listen !== "0.0.0.0") {
address = this.listen;
}
@@ -149,15 +150,21 @@ class DBInbound {
}
}
- genLink() {
+ genLink(allSetting) {
const inbound = this.toInbound();
- return inbound.genLink(this.address, this.remark);
+ return inbound.genLink(this.address, this.remark, allSetting);
}
}
class AllSetting {
constructor(data) {
+ this.configConnectIp = '';
+ this.configPortStart = 50000;
+ this.configPortEnd = 60000;
+ this.configCertDomain = "";
+ this.configCertFile = "";
+ this.configKeyFile = "";
this.webListen = "";
this.webPort = 54321;
this.webCertFile = "";
diff --git a/web/assets/js/model/xray.js b/web/assets/js/model/xray.js
old mode 100644
new mode 100755
index ef5c4995c..a3071d046
--- a/web/assets/js/model/xray.js
+++ b/web/assets/js/model/xray.js
@@ -615,6 +615,7 @@ class Inbound extends XrayCommonClass {
this._protocol = protocol;
this.settings = ObjectUtil.isEmpty(settings) ? Inbound.Settings.getSettings(protocol) : settings;
this.stream = streamSettings;
+
this.tag = tag;
this.sniffing = sniffing;
}
@@ -881,7 +882,7 @@ class Inbound extends XrayCommonClass {
this.sniffing = new Sniffing();
}
- genVmessLink(address='', remark='') {
+ genVmessLink(address='', remark='', allSetting) {
if (this.protocol !== Protocols.VMESS) {
return '';
}
@@ -923,12 +924,21 @@ class Inbound extends XrayCommonClass {
path = this.stream.grpc.serviceName;
}
+ let sni = ''
+
if (this.stream.security === 'tls') {
if (!ObjectUtil.isEmpty(this.stream.tls.server)) {
- address = this.stream.tls.server;
+ // address = this.stream.tls.server;
+ sni = this.stream.tls.server;
+ if (ObjectUtil.isEmpty(address)) {
+ address = this.stream.tls.server;
+ }
}
}
+ if (!ObjectUtil.isEmpty(allSetting)) {
+ address = allSetting.configConnectIp;
+ }
let obj = {
v: '2',
ps: remark,
@@ -940,8 +950,10 @@ class Inbound extends XrayCommonClass {
type: type,
host: host,
path: path,
+ sni: sni,
tls: this.stream.security,
};
+ // console.log('vmess', obj)
return 'vmess://' + base64(JSON.stringify(obj, null, 2));
}
@@ -1036,9 +1048,9 @@ class Inbound extends XrayCommonClass {
return `trojan://${settings.clients[0].password}@${address}:${this.port}#${encodeURIComponent(remark)}`;
}
- genLink(address='', remark='') {
+ genLink(address='', remark='', allSetting) {
switch (this.protocol) {
- case Protocols.VMESS: return this.genVmessLink(address, remark);
+ case Protocols.VMESS: return this.genVmessLink(address, remark, allSetting);
case Protocols.VLESS: return this.genVLESSLink(address, remark);
case Protocols.SHADOWSOCKS: return this.genSSLink(address, remark);
case Protocols.TROJAN: return this.genTrojanLink(address, remark);
diff --git a/web/assets/js/util/common.js b/web/assets/js/util/common.js
old mode 100644
new mode 100755
diff --git a/web/assets/js/util/date-util.js b/web/assets/js/util/date-util.js
old mode 100644
new mode 100755
diff --git a/web/assets/js/util/link-util.js b/web/assets/js/util/link-util.js
new file mode 100755
index 000000000..b98f655ec
--- /dev/null
+++ b/web/assets/js/util/link-util.js
@@ -0,0 +1,11 @@
+// go 调用
+
+function base64(str) {
+ return Base64.encode(str);
+}
+
+function genLink(inbound, allSetting) {
+ const dbInbound = new DBInbound(inbound)
+ const link = dbInbound.genLink(allSetting);
+ return link;
+}
\ No newline at end of file
diff --git a/web/assets/js/util/object-util.js b/web/assets/js/util/object-util.js
new file mode 100755
index 000000000..af06b8da6
--- /dev/null
+++ b/web/assets/js/util/object-util.js
@@ -0,0 +1,151 @@
+class ObjectUtil {
+
+ static getPropIgnoreCase(obj, prop) {
+ for (const name in obj) {
+ if (!obj.hasOwnProperty(name)) {
+ continue;
+ }
+ if (name.toLowerCase() === prop.toLowerCase()) {
+ return obj[name];
+ }
+ }
+ return undefined;
+ }
+
+ static deepSearch(obj, key) {
+ if (obj instanceof Array) {
+ for (let i = 0; i < obj.length; ++i) {
+ if (this.deepSearch(obj[i], key)) {
+ return true;
+ }
+ }
+ } else if (obj instanceof Object) {
+ for (let name in obj) {
+ if (!obj.hasOwnProperty(name)) {
+ continue;
+ }
+ if (this.deepSearch(obj[name], key)) {
+ return true;
+ }
+ }
+ } else {
+ return obj.toString().indexOf(key) >= 0;
+ }
+ return false;
+ }
+
+ static isEmpty(obj) {
+ return obj === null || obj === undefined || obj === '';
+ }
+
+ static isArrEmpty(arr) {
+ return !this.isEmpty(arr) && arr.length === 0;
+ }
+
+ static copyArr(dest, src) {
+ dest.splice(0);
+ for (const item of src) {
+ dest.push(item);
+ }
+ }
+
+ static clone(obj) {
+ let newObj;
+ if (obj instanceof Array) {
+ newObj = [];
+ this.copyArr(newObj, obj);
+ } else if (obj instanceof Object) {
+ newObj = {};
+ for (const key of Object.keys(obj)) {
+ newObj[key] = obj[key];
+ }
+ } else {
+ newObj = obj;
+ }
+ return newObj;
+ }
+
+ static deepClone(obj) {
+ let newObj;
+ if (obj instanceof Array) {
+ newObj = [];
+ for (const item of obj) {
+ newObj.push(this.deepClone(item));
+ }
+ } else if (obj instanceof Object) {
+ newObj = {};
+ for (const key of Object.keys(obj)) {
+ newObj[key] = this.deepClone(obj[key]);
+ }
+ } else {
+ newObj = obj;
+ }
+ return newObj;
+ }
+
+ static cloneProps(dest, src, ...ignoreProps) {
+ if (dest == null || src == null) {
+ return;
+ }
+ const ignoreEmpty = this.isArrEmpty(ignoreProps);
+ for (const key of Object.keys(src)) {
+ if (!src.hasOwnProperty(key)) {
+ continue;
+ } else if (!dest.hasOwnProperty(key)) {
+ continue;
+ } else if (src[key] === undefined) {
+ continue;
+ }
+ if (ignoreEmpty) {
+ dest[key] = src[key];
+ } else {
+ let ignore = false;
+ for (let i = 0; i < ignoreProps.length; ++i) {
+ if (key === ignoreProps[i]) {
+ ignore = true;
+ break;
+ }
+ }
+ if (!ignore) {
+ dest[key] = src[key];
+ }
+ }
+ }
+ }
+
+ static delProps(obj, ...props) {
+ for (const prop of props) {
+ if (prop in obj) {
+ delete obj[prop];
+ }
+ }
+ }
+
+ static execute(func, ...args) {
+ if (!this.isEmpty(func) && typeof func === 'function') {
+ func(...args);
+ }
+ }
+
+ static orDefault(obj, defaultValue) {
+ if (obj == null) {
+ return defaultValue;
+ }
+ return obj;
+ }
+
+ static equals(a, b) {
+ for (const key in a) {
+ if (!a.hasOwnProperty(key)) {
+ continue;
+ }
+ if (!b.hasOwnProperty(key)) {
+ return false;
+ } else if (a[key] !== b[key]) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+}
diff --git a/web/assets/js/util/utils.js b/web/assets/js/util/utils.js
old mode 100644
new mode 100755
diff --git a/web/assets/moment/moment.min.js b/web/assets/moment/moment.min.js
old mode 100644
new mode 100755
diff --git a/web/assets/qrcode/qrious.min.js b/web/assets/qrcode/qrious.min.js
old mode 100644
new mode 100755
diff --git a/web/assets/qs/qs.min.js b/web/assets/qs/qs.min.js
old mode 100644
new mode 100755
diff --git a/web/assets/uri/URI.min.js b/web/assets/uri/URI.min.js
old mode 100644
new mode 100755
diff --git a/web/assets/vue@2.6.12/vue.common.dev.js b/web/assets/vue@2.6.12/vue.common.dev.js
old mode 100644
new mode 100755
diff --git a/web/assets/vue@2.6.12/vue.common.js b/web/assets/vue@2.6.12/vue.common.js
old mode 100644
new mode 100755
diff --git a/web/assets/vue@2.6.12/vue.common.prod.js b/web/assets/vue@2.6.12/vue.common.prod.js
old mode 100644
new mode 100755
diff --git a/web/assets/vue@2.6.12/vue.esm.browser.min.js b/web/assets/vue@2.6.12/vue.esm.browser.min.js
old mode 100644
new mode 100755
diff --git a/web/assets/vue@2.6.12/vue.esm.js b/web/assets/vue@2.6.12/vue.esm.js
old mode 100644
new mode 100755
diff --git a/web/assets/vue@2.6.12/vue.min.js b/web/assets/vue@2.6.12/vue.min.js
old mode 100644
new mode 100755
diff --git a/web/assets/vue@2.6.12/vue.runtime.common.dev.js b/web/assets/vue@2.6.12/vue.runtime.common.dev.js
old mode 100644
new mode 100755
diff --git a/web/assets/vue@2.6.12/vue.runtime.common.js b/web/assets/vue@2.6.12/vue.runtime.common.js
old mode 100644
new mode 100755
diff --git a/web/assets/vue@2.6.12/vue.runtime.common.prod.js b/web/assets/vue@2.6.12/vue.runtime.common.prod.js
old mode 100644
new mode 100755
diff --git a/web/assets/vue@2.6.12/vue.runtime.esm.js b/web/assets/vue@2.6.12/vue.runtime.esm.js
old mode 100644
new mode 100755
diff --git a/web/assets/vue@2.6.12/vue.runtime.js b/web/assets/vue@2.6.12/vue.runtime.js
old mode 100644
new mode 100755
diff --git a/web/assets/vue@2.6.12/vue.runtime.min.js b/web/assets/vue@2.6.12/vue.runtime.min.js
old mode 100644
new mode 100755
diff --git a/web/controller/base.go b/web/controller/base.go
old mode 100644
new mode 100755
index 5d2ccec24..747eeda8b
--- a/web/controller/base.go
+++ b/web/controller/base.go
@@ -1,16 +1,27 @@
package controller
import (
- "github.com/gin-gonic/gin"
+ "fmt"
"net/http"
+ "strings"
"x-ui/web/session"
+
+ "github.com/gin-gonic/gin"
)
type BaseController struct {
}
+func IsFreeAuth(c *gin.Context) bool {
+ free := strings.HasPrefix(c.Request.URL.Path, "/xui/subscription/link/")
+ fmt.Printf("IsFreeAuth: %v %v\n", c.Request.URL.Path, free)
+ return free
+}
+
func (a *BaseController) checkLogin(c *gin.Context) {
- if !session.IsLogin(c) {
+ if IsFreeAuth(c) {
+ c.Next()
+ } else if !session.IsLogin(c) {
if isAjax(c) {
pureJsonMsg(c, false, "登录时效已过,请重新登录")
} else {
diff --git a/web/controller/inbound.go b/web/controller/inbound.go
old mode 100644
new mode 100755
index 3cb3b6b6d..192595022
--- a/web/controller/inbound.go
+++ b/web/controller/inbound.go
@@ -2,13 +2,14 @@ package controller
import (
"fmt"
- "github.com/gin-gonic/gin"
"strconv"
"x-ui/database/model"
"x-ui/logger"
"x-ui/web/global"
"x-ui/web/service"
"x-ui/web/session"
+
+ "github.com/gin-gonic/gin"
)
type InboundController struct {
@@ -30,6 +31,7 @@ func (a *InboundController) initRouter(g *gin.RouterGroup) {
g.POST("/add", a.addInbound)
g.POST("/del/:id", a.delInbound)
g.POST("/update/:id", a.updateInbound)
+ g.POST("/forsub", a.getInboundsForSub)
}
func (a *InboundController) startTask() {
@@ -45,9 +47,9 @@ func (a *InboundController) startTask() {
})
}
-func (a *InboundController) getInbounds(c *gin.Context) {
+func (a *InboundController) getInboundsForSub(c *gin.Context) {
user := session.GetLoginUser(c)
- inbounds, err := a.inboundService.GetInbounds(user.Id)
+ inbounds, err := a.inboundService.GetInboundsForSub(user.Id)
if err != nil {
jsonMsg(c, "获取", err)
return
@@ -55,6 +57,26 @@ func (a *InboundController) getInbounds(c *gin.Context) {
jsonObj(c, inbounds, nil)
}
+func (a *InboundController) getInbounds(c *gin.Context) {
+ user := session.GetLoginUser(c)
+ tag := c.Query("tag")
+ if tag == "" || tag == "all" {
+ inbounds, err := a.inboundService.GetInbounds(user.Id)
+ if err != nil {
+ jsonMsg(c, "获取", err)
+ return
+ }
+ jsonObj(c, inbounds, nil)
+ } else {
+ inbounds, err := a.inboundService.GetInboundsByTag(user.Id, tag)
+ if err != nil {
+ jsonMsg(c, "获取", err)
+ return
+ }
+ jsonObj(c, inbounds, nil)
+ }
+}
+
func (a *InboundController) addInbound(c *gin.Context) {
inbound := &model.Inbound{}
err := c.ShouldBind(inbound)
diff --git a/web/controller/index.go b/web/controller/index.go
old mode 100644
new mode 100755
diff --git a/web/controller/server.go b/web/controller/server.go
old mode 100644
new mode 100755
diff --git a/web/controller/setting.go b/web/controller/setting.go
old mode 100644
new mode 100755
diff --git a/web/controller/subscription.go b/web/controller/subscription.go
new file mode 100755
index 000000000..4fd21f1ab
--- /dev/null
+++ b/web/controller/subscription.go
@@ -0,0 +1,264 @@
+package controller
+
+import (
+ "crypto/md5"
+ "encoding/base64"
+ "encoding/hex"
+ "encoding/json"
+ "fmt"
+ "strconv"
+ "strings"
+ "time"
+ "x-ui/database/model"
+ "x-ui/web/global"
+ "x-ui/web/service"
+ "x-ui/web/session"
+
+ "github.com/gin-gonic/gin"
+
+ "github.com/dop251/goja"
+)
+
+type SubscriptionController struct {
+ subscriptionService service.SubscriptionService
+ inboundService service.InboundService
+ xrayService service.XrayService
+ settingService service.SettingService
+ vm *goja.Runtime
+}
+
+func NewSubscriptionController(g *gin.RouterGroup) *SubscriptionController {
+ a := &SubscriptionController{}
+ a.initRouter(g)
+ // a.startTask()
+
+ a.vm = goja.New()
+ // 读取 JavaScript 文件内容 assets
+ jsXray := "js/model/xray.js"
+ jsModels := "js/model/models.js"
+ jsUtils := "js/util/utils.js"
+ jsLinkUtil := "js/util/link-util.js"
+ jsBase64 := "base64/base64.min.js"
+
+ err := a.initJs(jsUtils)
+ if err != nil {
+ fmt.Printf("执行 jsUtils 文件失败: %v \n", err)
+ return nil
+ }
+ err = a.initJs(jsBase64)
+ if err != nil {
+ fmt.Printf("执行 jsBase64 文件失败: %v \n", err)
+ return nil
+ }
+ err = a.initJs(jsXray)
+ if err != nil {
+ fmt.Printf("执行 jsXray 文件失败: %v \n", err)
+ return nil
+ }
+ err = a.initJs(jsModels)
+ if err != nil {
+ fmt.Printf("执行 jsModels 文件失败: %v \n", err)
+ return nil
+ }
+ err = a.initJs(jsLinkUtil)
+ if err != nil {
+ fmt.Printf("执行 jsLinkUtil 文件失败: %v \n", err)
+ return nil
+ }
+ return a
+}
+
+func (a *SubscriptionController) initJs(jsPath string) error {
+ webServer := global.GetWebServer()
+ jsContent, err := webServer.ReadAssets(jsPath)
+ // var jsContent []byte
+ // _, err = file.Read(jsContent)
+ if err != nil {
+ fmt.Printf("读取 %s 文件失败: %v\n", jsPath, err)
+ return nil
+ }
+ // 在 JavaScript 虚拟机中执行代码
+ _, err = a.vm.RunString(string(jsContent))
+ if err != nil {
+ fmt.Printf("执行 %s 文件失败: %v \n", jsPath, err)
+ return nil
+ }
+ return nil
+}
+func (a *SubscriptionController) initRouter(g *gin.RouterGroup) {
+ g = g.Group("/subscription")
+
+ g.POST("/list", a.getSubscriptions)
+ g.POST("/add", a.addSubscription)
+ g.POST("/del/:id", a.delSubscription)
+ g.POST("/upd/:id", a.updSubscription)
+ g.GET("/link/:token", a.getSubscriptionByToken)
+}
+func (a *SubscriptionController) setOutput(c *gin.Context, status int, data []string) {
+ var output string
+ if len(data) > 0 {
+ output = strings.Join(data, "\r\n")
+ }
+ raw := c.Query("raw")
+ c.Status(status)
+ if raw != "1" {
+ output = base64.StdEncoding.EncodeToString([]byte(output))
+ }
+ c.Writer.WriteString(output)
+}
+func (a *SubscriptionController) getSubscriptionByToken(c *gin.Context) {
+ token := c.Param("token")
+ subList := make([]string, 0)
+
+ subscription, err := a.subscriptionService.GetSubscriptionByToken(token)
+ if err != nil && subscription == nil {
+ a.setOutput(c, 401, subList)
+ return
+ }
+ fmt.Printf("订阅 %d 获取成功\n", subscription.Id)
+ // 判断有效期
+ if !subscription.Enable ||
+ (subscription.ExpiryTime > 0 &&
+ subscription.ExpiryTime < time.Now().Unix()*1000) {
+ fmt.Printf("订阅已禁用or已过期\n")
+ a.setOutput(c, 403, subList)
+ return
+ }
+
+ // 是否自动更新
+ autoUpdate := subscription.AutoUpdate
+ if autoUpdate {
+
+ // 创建新的节点
+ inboundIds, err := a.subscriptionService.AutoUpdateSubscription(subscription)
+ if err != nil {
+ fmt.Printf("创建新的节点 error: %v", err)
+ a.setOutput(c, 500, subList)
+ return
+ }
+ idsStr, err := json.Marshal(inboundIds)
+ if err != nil {
+ fmt.Printf("创建新的节点 error: %v", err)
+ a.setOutput(c, 500, subList)
+ return
+ }
+ subscription.InboundIds = string(idsStr)
+
+ a.xrayService.SetToNeedRestart()
+
+ }
+
+ inboundIds := subscription.InboundIds
+ // 开始获取入站节点
+ var ids []int
+ err = json.Unmarshal([]byte(inboundIds), &ids)
+ if err != nil {
+ fmt.Printf("json.Unmarshal error: %v", err)
+ a.setOutput(c, 500, subList)
+ return
+ }
+ inbounds, err := a.inboundService.GetInboundsByIds(ids)
+ if err != nil {
+ fmt.Printf("获取订阅 inbounds error: %v", err)
+ a.setOutput(c, 500, subList)
+ return
+ }
+ allSetting, _ := a.settingService.GetAllSetting()
+
+ allSettingJson, err := json.Marshal(allSetting)
+ if err != nil {
+ fmt.Printf("Marshal allSetting error: %v", err)
+ return
+ }
+
+ for _, inbound := range inbounds {
+ param, err := json.Marshal(inbound)
+ if err != nil {
+ fmt.Printf("Marshal error: %v", err)
+ continue
+ }
+ link, err := a.vm.RunString(fmt.Sprintf("genLink(%s, %s)", string(param), string(allSettingJson)))
+ if err != nil {
+ fmt.Printf("genLink error: %v", err)
+ continue
+ }
+ subList = append(subList, link.String())
+ }
+ a.setOutput(c, 200, subList)
+}
+
+func (a *SubscriptionController) getSubscriptions(c *gin.Context) {
+ user := session.GetLoginUser(c)
+ subscriptions, err := a.subscriptionService.GetSubscriptions(user.Id)
+ if err != nil {
+ jsonMsg(c, "获取", err)
+ return
+ }
+ jsonObj(c, subscriptions, nil)
+}
+
+func genToken() string {
+ nanoseconds := time.Now().UnixNano()
+
+ // 将纳秒时间戳转换为字符串
+ timestampStr := fmt.Sprintf("%d", nanoseconds)
+
+ // 计算字符串的 MD5 值
+ md5Hash := md5.Sum([]byte(timestampStr))
+
+ // 将 MD5 值转换为字符串
+ md5Str := hex.EncodeToString(md5Hash[:])
+
+ return md5Str
+}
+
+func (a *SubscriptionController) addSubscription(c *gin.Context) {
+ subscription := &model.Subscription{}
+ err := c.ShouldBind(subscription)
+ if err != nil {
+ jsonMsg(c, "添加", err)
+ return
+ }
+ user := session.GetLoginUser(c)
+ subscription.UserId = user.Id
+ subscription.Token = genToken()
+ err = a.subscriptionService.AddSubscription(subscription)
+ jsonMsg(c, "添加", err)
+ if err == nil {
+ a.xrayService.SetToNeedRestart()
+ }
+}
+
+func (a *SubscriptionController) delSubscription(c *gin.Context) {
+ id, err := strconv.Atoi(c.Param("id"))
+ if err != nil {
+ jsonMsg(c, "删除", err)
+ return
+ }
+ err = a.subscriptionService.DelSubscription(id)
+ jsonMsg(c, "删除", err)
+ if err == nil {
+ a.xrayService.SetToNeedRestart()
+ }
+}
+
+func (a *SubscriptionController) updSubscription(c *gin.Context) {
+ id, err := strconv.Atoi(c.Param("id"))
+ if err != nil {
+ jsonMsg(c, "修改", err)
+ return
+ }
+ subscription := &model.Subscription{
+ Id: id,
+ }
+ err = c.ShouldBind(subscription)
+ if err != nil {
+ jsonMsg(c, "修改", err)
+ return
+ }
+ err = a.subscriptionService.UpdateSubscription(subscription)
+ jsonMsg(c, "修改", err)
+ if err == nil {
+ a.xrayService.SetToNeedRestart()
+ }
+}
diff --git a/web/controller/util.go b/web/controller/util.go
old mode 100644
new mode 100755
diff --git a/web/controller/xui.go b/web/controller/xui.go
old mode 100644
new mode 100755
index 9c1626263..58184a32e
--- a/web/controller/xui.go
+++ b/web/controller/xui.go
@@ -9,6 +9,7 @@ type XUIController struct {
inboundController *InboundController
settingController *SettingController
+ subscriptionController *SubscriptionController
}
func NewXUIController(g *gin.RouterGroup) *XUIController {
@@ -23,10 +24,12 @@ func (a *XUIController) initRouter(g *gin.RouterGroup) {
g.GET("/", a.index)
g.GET("/inbounds", a.inbounds)
+ g.GET("/subscriptions", a.subscriptions)
g.GET("/setting", a.setting)
-
+
a.inboundController = NewInboundController(g)
a.settingController = NewSettingController(g)
+ a.subscriptionController = NewSubscriptionController(g)
}
func (a *XUIController) index(c *gin.Context) {
@@ -40,3 +43,6 @@ func (a *XUIController) inbounds(c *gin.Context) {
func (a *XUIController) setting(c *gin.Context) {
html(c, "setting.html", "设置", nil)
}
+func (a *XUIController) subscriptions(c *gin.Context) {
+ html(c, "subscriptions.html", "订阅列表", nil)
+}
\ No newline at end of file
diff --git a/web/entity/entity.go b/web/entity/entity.go
old mode 100644
new mode 100755
index f8572f665..eb4093ab7
--- a/web/entity/entity.go
+++ b/web/entity/entity.go
@@ -27,6 +27,13 @@ type Pager struct {
}
type AllSetting struct {
+ ConfigPortEnd int `json:"configPortEnd" form:"configPortEnd"`
+ ConfigPortStart int `json:"configPortStart" form:"configPortStart"`
+ ConfigConnectIp string `json:"configConnectIp" form:"configConnectIp"`
+ ConfigCertFile string `json:"configCertFile" form:"configCertFile"`
+ ConfigKeyFile string `json:"configKeyFile" form:"configKeyFile"`
+ ConfigCertDomain string `json:"configCertDomain" form:"configCertDomain"`
+
WebListen string `json:"webListen" form:"webListen"`
WebPort int `json:"webPort" form:"webPort"`
WebCertFile string `json:"webCertFile" form:"webCertFile"`
diff --git a/web/global/global.go b/web/global/global.go
old mode 100644
new mode 100755
index 09d0683a3..013565b7a
--- a/web/global/global.go
+++ b/web/global/global.go
@@ -2,8 +2,9 @@ package global
import (
"context"
- "github.com/robfig/cron/v3"
_ "unsafe"
+
+ "github.com/robfig/cron/v3"
)
var webServer WebServer
@@ -11,6 +12,7 @@ var webServer WebServer
type WebServer interface {
GetCron() *cron.Cron
GetCtx() context.Context
+ ReadAssets(path string) ([]byte, error) // open file
}
func SetWebServer(s WebServer) {
diff --git a/web/html/common/head.html b/web/html/common/head.html
old mode 100644
new mode 100755
diff --git a/web/html/common/js.html b/web/html/common/js.html
old mode 100644
new mode 100755
diff --git a/web/html/common/prompt_modal.html b/web/html/common/prompt_modal.html
old mode 100644
new mode 100755
diff --git a/web/html/common/qrcode_modal.html b/web/html/common/qrcode_modal.html
old mode 100644
new mode 100755
diff --git a/web/html/common/text_modal.html b/web/html/common/text_modal.html
old mode 100644
new mode 100755
diff --git a/web/html/login.html b/web/html/login.html
old mode 100644
new mode 100755
diff --git a/web/html/xui/common_sider.html b/web/html/xui/common_sider.html
old mode 100644
new mode 100755
index fd9423126..4880dfa22
--- a/web/html/xui/common_sider.html
+++ b/web/html/xui/common_sider.html
@@ -7,6 +7,10 @@
入站列表
+
+
+ 订阅列表
+
面板设置
@@ -20,7 +24,7 @@
其他
-
+
Github
diff --git a/web/html/xui/component/inbound_info.html b/web/html/xui/component/inbound_info.html
old mode 100644
new mode 100755
diff --git a/web/html/xui/component/setting.html b/web/html/xui/component/setting.html
old mode 100644
new mode 100755
diff --git a/web/html/xui/form/inbound.html b/web/html/xui/form/inbound.html
old mode 100644
new mode 100755
diff --git a/web/html/xui/form/protocol/dokodemo.html b/web/html/xui/form/protocol/dokodemo.html
old mode 100644
new mode 100755
diff --git a/web/html/xui/form/protocol/http.html b/web/html/xui/form/protocol/http.html
old mode 100644
new mode 100755
diff --git a/web/html/xui/form/protocol/shadowsocks.html b/web/html/xui/form/protocol/shadowsocks.html
old mode 100644
new mode 100755
diff --git a/web/html/xui/form/protocol/socks.html b/web/html/xui/form/protocol/socks.html
old mode 100644
new mode 100755
diff --git a/web/html/xui/form/protocol/trojan.html b/web/html/xui/form/protocol/trojan.html
old mode 100644
new mode 100755
diff --git a/web/html/xui/form/protocol/vless.html b/web/html/xui/form/protocol/vless.html
old mode 100644
new mode 100755
diff --git a/web/html/xui/form/protocol/vmess.html b/web/html/xui/form/protocol/vmess.html
old mode 100644
new mode 100755
diff --git a/web/html/xui/form/sniffing.html b/web/html/xui/form/sniffing.html
old mode 100644
new mode 100755
diff --git a/web/html/xui/form/stream/stream_grpc.html b/web/html/xui/form/stream/stream_grpc.html
old mode 100644
new mode 100755
diff --git a/web/html/xui/form/stream/stream_http.html b/web/html/xui/form/stream/stream_http.html
old mode 100644
new mode 100755
diff --git a/web/html/xui/form/stream/stream_kcp.html b/web/html/xui/form/stream/stream_kcp.html
old mode 100644
new mode 100755
diff --git a/web/html/xui/form/stream/stream_quic.html b/web/html/xui/form/stream/stream_quic.html
old mode 100644
new mode 100755
diff --git a/web/html/xui/form/stream/stream_settings.html b/web/html/xui/form/stream/stream_settings.html
old mode 100644
new mode 100755
diff --git a/web/html/xui/form/stream/stream_tcp.html b/web/html/xui/form/stream/stream_tcp.html
old mode 100644
new mode 100755
diff --git a/web/html/xui/form/stream/stream_ws.html b/web/html/xui/form/stream/stream_ws.html
old mode 100644
new mode 100755
diff --git a/web/html/xui/form/subscription.html b/web/html/xui/form/subscription.html
new file mode 100755
index 000000000..96bce88b1
--- /dev/null
+++ b/web/html/xui/form/subscription.html
@@ -0,0 +1,45 @@
+{{define "form/subscription"}}
+
+
+
+
+
+
+
+
+
+
+ 样例节点
+
+
+ 根据样例节点配置自动生成多个节点
+
+
+
+
+
+ [[ p.remark ]]
+
+
+
+
+
+
+
+
+
+
+ 到期时间
+
+
+ 留空则永不到期
+
+
+
+
+
+
+
+
+{{end}}
\ No newline at end of file
diff --git a/web/html/xui/form/tls_settings.html b/web/html/xui/form/tls_settings.html
old mode 100644
new mode 100755
diff --git a/web/html/xui/inbound_info_modal.html b/web/html/xui/inbound_info_modal.html
old mode 100644
new mode 100755
index 3a837ff0d..05c8b0ee9
--- a/web/html/xui/inbound_info_modal.html
+++ b/web/html/xui/inbound_info_modal.html
@@ -18,7 +18,7 @@
style: "",
},
},
- show(dbInbound) {
+ show(dbInbound, allSettings) {
this.inbound = dbInbound.toInbound();
this.dbInbound = new DBInbound(dbInbound);
this.visible = true;
@@ -32,7 +32,7 @@
if (this.clipboard == null) {
infoModalApp.$nextTick(() => {
this.clipboard = new ClipboardJS(`#${this.okBtnPros.attrs.id}`, {
- text: () => this.dbInbound.genLink(),
+ text: () => this.dbInbound.genLink(allSettings),
});
this.clipboard.on('success', () => app.$message.success('复制成功'));
});
diff --git a/web/html/xui/inbound_modal.html b/web/html/xui/inbound_modal.html
old mode 100644
new mode 100755
index 050b4a00c..f58dc7879
--- a/web/html/xui/inbound_modal.html
+++ b/web/html/xui/inbound_modal.html
@@ -17,13 +17,19 @@
ok() {
ObjectUtil.execute(inModal.confirm, inModal.inbound, inModal.dbInbound);
},
- show({ title='', okText='确定', inbound=null, dbInbound=null, confirm=(inbound, dbInbound)=>{} }) {
+ show({ allSettings={}, title='', okText='确定', inbound=null, dbInbound=null, confirm=(inbound, dbInbound)=>{} }) {
this.title = title;
this.okText = okText;
if (inbound) {
this.inbound = Inbound.fromJson(inbound.toJson());
} else {
this.inbound = new Inbound();
+ this.inbound.port=RandomUtil.randomIntRange(allSettings.configPortStart||10000,
+ allSettings.configPortEnd||60000)
+ this.inbound.stream.tls.server = allSettings.configCertDomain||''
+ this.inbound.stream.tls.certs[0].certFile = allSettings.configCertFile||''
+ this.inbound.stream.tls.certs[0].keyFile = allSettings.configKeyFile||''
+
}
if (dbInbound) {
this.dbInbound = new DBInbound(dbInbound);
diff --git a/web/html/xui/inbounds.html b/web/html/xui/inbounds.html
old mode 100644
new mode 100755
index 85321eded..974131180
--- a/web/html/xui/inbounds.html
+++ b/web/html/xui/inbounds.html
@@ -43,9 +43,18 @@
-
-
+
+
编辑
+
+ 复制
+
重置流量
@@ -181,14 +193,27 @@
inbounds: [],
dbInbounds: [],
searchKey: '',
+ allSettings: {},
+ includeSubscriptions: false
},
methods: {
+ switchIncludeSubscriptions(flag) {
+ const that = this
+ this.getDBInbounds()
+ },
loading(spinning=true) {
this.spinning = spinning;
},
+ async getAllSettings() {
+ const res = await HttpUtil.post('/xui/setting/all');
+ if (!res.success) {
+ return;
+ }
+ this.allSettings = res.obj;
+ },
async getDBInbounds() {
this.loading();
- const msg = await HttpUtil.post('/xui/inbound/list');
+ const msg = await HttpUtil.post('/xui/inbound/list?tag='+(this.includeSubscriptions?'all':'inbound'));
this.loading(false);
if (!msg.success) {
return;
@@ -224,6 +249,9 @@
case "edit":
this.openEditInbound(dbInbound);
break;
+ case "copy":
+ this.openCopyInbound(dbInbound);
+ break;
case "resetTraffic":
this.resetTraffic(dbInbound);
break;
@@ -236,6 +264,28 @@
inModal.show({
title: '添加入站',
okText: '添加',
+ allSettings: this.allSettings,
+ confirm: async (inbound, dbInbound) => {
+ inModal.loading();
+ await this.addInbound(inbound, dbInbound);
+ inModal.close();
+ }
+ });
+ },
+ openCopyInbound(dbInbound) {
+ const inbound = dbInbound.toInbound();
+ inbound.id = null
+ inbound.remark = `${inbound.remark}-copy`;
+ const id = RandomUtil.randomUUID()
+ inbound.port = RandomUtil.randomIntRange(this.allSettings.configPortStart||10000, this.allSettings.configPortEnd||60000)
+ inbound.settings[inbound.settings.protocol+'es'][0].id = id
+ inbound.settings.id = id
+ console.log("inbound", inbound)
+ inModal.show({
+ title: '复制入站',
+ okText: '确定',
+ inbound: inbound,
+ dbInbound: dbInbound,
confirm: async (inbound, dbInbound) => {
inModal.loading();
await this.addInbound(inbound, dbInbound);
@@ -317,7 +367,8 @@
});
},
showQrcode(dbInbound) {
- const link = dbInbound.genLink();
+ const link = dbInbound.genLink(this.allSettings);
+ console.log("link: ", link )
qrModal.show('二维码', link);
},
showInfo(dbInbound) {
@@ -339,6 +390,7 @@
}
},
mounted() {
+ this.getAllSettings();
this.getDBInbounds();
},
computed: {
diff --git a/web/html/xui/index.html b/web/html/xui/index.html
old mode 100644
new mode 100755
diff --git a/web/html/xui/setting.html b/web/html/xui/setting.html
old mode 100644
new mode 100755
index 46d77637a..c02d6a3e0
--- a/web/html/xui/setting.html
+++ b/web/html/xui/setting.html
@@ -35,7 +35,17 @@
保存配置
重启面板
-
+
+
+
+
+
+
+
+
+
+
+
@@ -113,6 +123,7 @@
this.loading(true);
const msg = await HttpUtil.post("/xui/setting/all");
this.loading(false);
+ console.log("msg", msg)
if (msg.success) {
this.oldAllSetting = new AllSetting(msg.obj);
this.allSetting = new AllSetting(msg.obj);
diff --git a/web/html/xui/subscription_modal.html b/web/html/xui/subscription_modal.html
new file mode 100755
index 000000000..237f7309a
--- /dev/null
+++ b/web/html/xui/subscription_modal.html
@@ -0,0 +1,63 @@
+{{define "subscriptionModal"}}
+
+ {{template "form/subscription"}}
+
+
+{{end}}
\ No newline at end of file
diff --git a/web/html/xui/subscriptions.html b/web/html/xui/subscriptions.html
new file mode 100755
index 000000000..23f2ba96c
--- /dev/null
+++ b/web/html/xui/subscriptions.html
@@ -0,0 +1,338 @@
+
+
+{{template "head" .}}
+
+
+
+ {{ template "commonSider" . }}
+
+
+
+
+
+ Please go to the panel settings as soon as possible to modify the username and password, otherwise there may be a risk of leaking account information
+
+
+
+
+
+
+ 订阅数量:
+ [[ subscriptions.length ]]
+
+
+
+
+
+
+
+
+ getSubscriptions()">
+
+
+ e.preventDefault()">操作
+ clickAction(a, dbSubscription)">
+
+ 二维码
+
+
+ 编辑
+
+
+
+ 删除
+
+
+
+
+
+
+
+
+
+
+ 是
+
+
+ 否
+
+
+
+ [[ dbSubscription.inboundIds ]]
+
+
+ 查看
+
+
+
+
+ [[ DateUtil.formatMillis(dbSubscription.expiryTime) ]]
+
+
+ [[ DateUtil.formatMillis(dbSubscription.expiryTime) ]]
+
+
+ 无限期
+
+
+
+
+
+
+
+
+{{template "js" .}}
+
+{{template "subscriptionModal"}}
+{{template "promptModal"}}
+{{template "qrcodeModal"}}
+{{template "textModal"}}
+{{template "inboundInfoModal"}}
+
+
\ No newline at end of file
diff --git a/web/job/check_inbound_job.go b/web/job/check_inbound_job.go
old mode 100644
new mode 100755
diff --git a/web/job/check_xray_running_job.go b/web/job/check_xray_running_job.go
old mode 100644
new mode 100755
diff --git a/web/job/stats_notify_job.go b/web/job/stats_notify_job.go
old mode 100644
new mode 100755
diff --git a/web/job/xray_traffic_job.go b/web/job/xray_traffic_job.go
old mode 100644
new mode 100755
diff --git a/web/network/auto_https_listener.go b/web/network/auto_https_listener.go
old mode 100644
new mode 100755
diff --git a/web/network/autp_https_conn.go b/web/network/autp_https_conn.go
old mode 100644
new mode 100755
diff --git a/web/service/config.json b/web/service/config.json
old mode 100644
new mode 100755
diff --git a/web/service/inbound.go b/web/service/inbound.go
old mode 100644
new mode 100755
index 726b7ba0a..454e94c08
--- a/web/service/inbound.go
+++ b/web/service/inbound.go
@@ -14,6 +14,61 @@ import (
type InboundService struct {
}
+func (s *InboundService) GetInboundsForSub(userId int) ([]*model.Inbound, error) {
+ db := database.GetDB()
+ var inbounds []*model.Inbound
+ protocols := []string{
+ string(model.VLESS),
+ string(model.VMess),
+ string(model.Shadowsocks),
+ string(model.Trojan),
+ }
+ err := db.Model(model.Inbound{}).Where("user_id = ? and tag like 'inbound-%' and protocol in(?)", userId, protocols).Find(&inbounds).Error
+ if err != nil && err != gorm.ErrRecordNotFound {
+ return nil, err
+ }
+ return inbounds, nil
+}
+func (s *InboundService) GetInboundsByIds(ids []int) ([]*model.Inbound, error) {
+ db := database.GetDB()
+ var inbounds []*model.Inbound
+ err := db.Model(model.Inbound{}).Where("id in (?)", ids).Find(&inbounds).Error
+ if err != nil && err != gorm.ErrRecordNotFound {
+ return nil, err
+ }
+ return inbounds, nil
+}
+func (s *InboundService) DelInboundsByIds(ids []int) error {
+ db := database.GetDB()
+ err := db.Where("id in (?)", ids).Delete(&model.Inbound{}).Error
+ if err != nil && err != gorm.ErrRecordNotFound {
+ return err
+ }
+ return nil
+}
+func (s *InboundService) InnerDelInboundsByIds(tx *gorm.DB, ids []int) error {
+ err := tx.Where("id in (?)", ids).Delete(&model.Inbound{}).Error
+ if err != nil && err != gorm.ErrRecordNotFound {
+ return err
+ }
+ return nil
+}
+func (s *InboundService) UpdInboundsStatusByIds(tx *gorm.DB, ids []int, enable bool, expireTime int64) error {
+ err := tx.Model(&model.Inbound{}).Where("id in (?)", ids).Update("enable", enable).Update("expiry_time", expireTime).Error
+ if err != nil && err != gorm.ErrRecordNotFound {
+ return err
+ }
+ return nil
+}
+func (s *InboundService) GetInboundsByTag(userId int, tag string) ([]*model.Inbound, error) {
+ db := database.GetDB()
+ var inbounds []*model.Inbound
+ err := db.Model(model.Inbound{}).Where("user_id = ? and tag like ? || '%'", userId, tag).Find(&inbounds).Error
+ if err != nil && err != gorm.ErrRecordNotFound {
+ return nil, err
+ }
+ return inbounds, nil
+}
func (s *InboundService) GetInbounds(userId int) ([]*model.Inbound, error) {
db := database.GetDB()
var inbounds []*model.Inbound
@@ -48,6 +103,10 @@ func (s *InboundService) checkPortExist(port int, ignoreId int) (bool, error) {
return count > 0, nil
}
+func (s *InboundService) CheckPortExist(port int) (bool, error) {
+ return s.checkPortExist(port, 0)
+}
+
func (s *InboundService) AddInbound(inbound *model.Inbound) error {
exist, err := s.checkPortExist(inbound.Port, 0)
if err != nil {
@@ -59,7 +118,39 @@ func (s *InboundService) AddInbound(inbound *model.Inbound) error {
db := database.GetDB()
return db.Save(inbound).Error
}
+func (s *InboundService) AddSubInbounds(inbounds []*model.Inbound) ([]int, error) {
+ for _, inbound := range inbounds {
+ exist, err := s.checkPortExist(inbound.Port, 0)
+ if err != nil {
+ return nil, err
+ }
+ if exist {
+ return nil, common.NewError("端口已存在:", inbound.Port)
+ }
+ }
+ db := database.GetDB()
+ tx := db.Begin()
+ var err error
+ defer func() {
+ if err == nil {
+ tx.Commit()
+ } else {
+ tx.Rollback()
+ }
+ }()
+ ids := make([]int, 0)
+ for _, inbound := range inbounds {
+ err = tx.Save(&inbound).Error
+ if err != nil {
+ return nil, err
+ }
+ fmt.Printf("新增节点ID:%v \n", inbound.Id)
+ ids = append(ids, inbound.Id)
+ }
+
+ return ids, nil
+}
func (s *InboundService) AddInbounds(inbounds []*model.Inbound) error {
for _, inbound := range inbounds {
exist, err := s.checkPortExist(inbound.Port, 0)
diff --git a/web/service/panel.go b/web/service/panel.go
old mode 100644
new mode 100755
diff --git a/web/service/server.go b/web/service/server.go
old mode 100644
new mode 100755
diff --git a/web/service/setting.go b/web/service/setting.go
old mode 100644
new mode 100755
index bedc83331..79d5a0d44
--- a/web/service/setting.go
+++ b/web/service/setting.go
@@ -21,6 +21,13 @@ import (
var xrayTemplateConfig string
var defaultValueMap = map[string]string{
+
+ "configConnectIp": "",
+ "configPortStart": "50000",
+ "configPortEnd": "60000",
+ "configCertDomain": "",
+ "configCertFile": "",
+ "configKeyFile": "",
"xrayTemplateConfig": xrayTemplateConfig,
"webListen": "",
"webPort": "54321",
diff --git a/web/service/subscription.go b/web/service/subscription.go
new file mode 100755
index 000000000..9f4e6def9
--- /dev/null
+++ b/web/service/subscription.go
@@ -0,0 +1,285 @@
+package service
+
+import (
+ "encoding/json"
+ "fmt"
+ "math/rand"
+ "strings"
+ "time"
+ "x-ui/database"
+ "x-ui/database/model"
+
+ "errors"
+
+ "github.com/xtls/xray-core/common/uuid"
+ "gorm.io/gorm"
+)
+
+type SubscriptionService struct {
+ inboundService InboundService
+ settingService SettingService
+}
+
+func (s *SubscriptionService) GetSubscriptionByToken(token string) (*model.Subscription, error) {
+ db := database.GetDB()
+ subscription := &model.Subscription{}
+ err := db.Where("token = ?", token).First(&subscription).Error
+ if err != nil {
+ return nil, err
+ }
+ return subscription, nil
+}
+
+func (s *SubscriptionService) GetSubscriptions(userId int) ([]*model.Subscription, error) {
+ db := database.GetDB()
+ var subscriptions []*model.Subscription
+ err := db.Model(model.Subscription{}).Find(&subscriptions).Error
+ if err != nil && err != gorm.ErrRecordNotFound {
+ return nil, err
+ }
+ return subscriptions, nil
+}
+
+func (s *SubscriptionService) getAvailablePorts(c int) []int {
+ seed := time.Now().UnixNano()
+ myRand := rand.New(rand.NewSource(seed))
+ ports := make([]int, 0)
+ allSettings, _ := s.settingService.GetAllSetting()
+ from := allSettings.ConfigPortStart
+ if from == 0 {
+ from = 10000
+ }
+ to := allSettings.ConfigPortEnd
+ if to == 0 {
+ to = 60000
+ }
+ gap := to - from
+ fmt.Printf("from: %d, to: %d, gap: %d\n", from, to, gap)
+ i := 0
+ for {
+ port := myRand.Intn(gap) + from
+ e, _ := s.inboundService.CheckPortExist(port)
+ if !e {
+ ports = append(ports, port)
+ i++
+ if i == c {
+ return ports
+ }
+ }
+ }
+}
+func (s *SubscriptionService) CreateAndSaveInbounds(tx *gorm.DB, subscription *model.Subscription) ([]int, error) {
+ sampleId := subscription.SampleId
+
+ availableCount := subscription.AvailableCount
+
+ inbound, _ := s.inboundService.GetInbound(sampleId)
+ if inbound == nil {
+ return nil, errors.New("sampleId无效")
+ }
+
+ inboundIds := make([]int, 0)
+ ports := s.getAvailablePorts(availableCount)
+ fmt.Printf("ports:%v\n", ports)
+ for i := 0; i < availableCount; i++ {
+ newInbound := &model.Inbound{
+ Port: ports[i],
+ Enable: subscription.Enable,
+ Protocol: inbound.Protocol,
+ Sniffing: inbound.Sniffing,
+ Remark: fmt.Sprintf("[%s]-[%d]节点, from: %d", subscription.Remark, i, sampleId),
+ UserId: subscription.UserId,
+ ExpiryTime: subscription.ExpiryTime,
+ Tag: fmt.Sprintf("subscription-%v", ports[i]),
+ }
+ // 处理 settings
+ settings := inbound.Settings
+ var j map[string]interface{}
+ json.Unmarshal([]byte(settings), &j)
+ uid := uuid.New()
+ j["clients"].([]interface{})[0].(map[string]interface{})["id"] = uid.String()
+ modifiedSettings, _ := json.Marshal(j)
+ newInbound.Settings = string(modifiedSettings)
+
+ // 处理 streamSettings
+ streamSettings := inbound.StreamSettings
+ var ssJson map[string]interface{}
+ err := json.Unmarshal([]byte(streamSettings), &ssJson)
+ if err != nil {
+ fmt.Printf("json.Unmarshal failed: %v\n", err)
+ return nil, err
+ }
+ for k := range ssJson {
+ // http settings
+ if k == "httpSettings" {
+ httpSettings := ssJson["httpSettings"].(map[string]interface{})
+ if httpSettings != nil {
+ httpSettings["path"] = fmt.Sprintf("/auto-http-%v", ports[i])
+ ssJson["httpSettings"] = httpSettings
+ }
+ } else if k == "wsSettings" {
+ // ws settings
+ wsSettings := ssJson["wsSettings"].(map[string]interface{})
+ if wsSettings != nil {
+ wsSettings["path"] = fmt.Sprintf("/auto-ws-%v", ports[i])
+ ssJson["wsSettings"] = wsSettings
+ }
+ }
+ }
+
+ modifiedStreamSettings, _ := json.Marshal(ssJson)
+ newInbound.StreamSettings = string(modifiedStreamSettings)
+
+ err = tx.Save(&newInbound).Error
+ if err != nil {
+ return nil, err
+ }
+ inboundIds = append(inboundIds, newInbound.Id)
+ }
+ // inboundIds, err := s.inboundService.AddSubInbounds(newInbounds)
+ // if err != nil {
+ // return nil, err
+ // }
+ return inboundIds, nil
+}
+func (s *SubscriptionService) AutoUpdateSubscription(subscription *model.Subscription) ([]int, error) {
+ db := database.GetDB()
+ tx := db.Begin()
+ var err error
+ defer func() {
+ if err == nil {
+ tx.Commit()
+ } else {
+ tx.Rollback()
+ }
+ }()
+ var ids []int
+ err = json.Unmarshal([]byte(subscription.InboundIds), &ids)
+ if err != nil {
+ fmt.Printf("json.Unmarshal error: %v", err)
+ return nil, errors.New("json.Unmarshal error")
+ }
+ s.inboundService.InnerDelInboundsByIds(tx, ids)
+
+ inboundIds, err := s.CreateAndSaveInbounds(tx, subscription)
+ if err != nil {
+ return nil, errors.New("创建新的节点 error")
+ }
+ idsStr, err := json.Marshal(inboundIds)
+ if err != nil {
+ return nil, errors.New("创建新的节点 error")
+ }
+ subscription.InboundIds = string(idsStr)
+ // 更新订阅
+ err = tx.Save(subscription).Error
+ return inboundIds, nil
+}
+func (s *SubscriptionService) AddSubscription(subscription *model.Subscription) error {
+
+ availableCount := subscription.AvailableCount
+ if availableCount == 0 || availableCount > 10 {
+ return errors.New("数量必须大于0,小于10")
+ }
+
+ db := database.GetDB()
+ tx := db.Begin()
+ var err error
+ defer func() {
+ if err == nil {
+ tx.Commit()
+ } else {
+ tx.Rollback()
+ }
+ }()
+
+ inboundIds, err := s.CreateAndSaveInbounds(tx, subscription)
+ if err != nil {
+ return errors.New("添加节点失败")
+ }
+
+ subscription.InboundIds = strings.Join(strings.Fields(fmt.Sprint(inboundIds)), ",")
+
+ return tx.Save(subscription).Error
+}
+
+func (s *SubscriptionService) DelSubscription(id int) error {
+ db := database.GetDB()
+ tx := db.Begin()
+ var err error
+ defer func() {
+ if err == nil {
+ tx.Commit()
+ } else {
+ tx.Rollback()
+ }
+ }()
+ subscription := &model.Subscription{}
+ err = tx.First(subscription, id).Error
+ if err != nil {
+ fmt.Printf("find subscription error: %v \n", err)
+ return err
+ }
+ var inboundIds []int
+ err = json.Unmarshal([]byte(subscription.InboundIds), &inboundIds)
+ if err != nil {
+ fmt.Printf("Unmarshal InboundIds error: %v \n", err)
+ return err
+ }
+ err = s.inboundService.InnerDelInboundsByIds(tx, inboundIds)
+ if err != nil {
+ fmt.Printf("InnerDelInboundsByIds error: %v \n", err)
+ return err
+ }
+ err = tx.Delete(model.Subscription{}, id).Error
+ return err
+}
+
+func (s *SubscriptionService) GetSubscription(id int) (*model.Subscription, error) {
+ db := database.GetDB()
+ subscription := &model.Subscription{}
+ err := db.Model(model.Subscription{}).First(subscription, id).Error
+ if err != nil {
+ return nil, err
+ }
+ return subscription, nil
+}
+
+func (s *SubscriptionService) UpdateSubscription(subscription *model.Subscription) error {
+
+ var err error
+
+ oldSubscription, err := s.GetSubscription(subscription.Id)
+ if err != nil {
+ return err
+ }
+ db := database.GetDB()
+ tx := db.Begin()
+ defer func() {
+ if err == nil {
+ tx.Commit()
+ } else {
+ tx.Rollback()
+ }
+ }()
+ // oldSubscription.SampleId = subscription.SampleId
+ // oldSubscription.AvailableCount = subscription.AvailableCount
+ oldSubscription.AutoUpdate = subscription.AutoUpdate
+ oldSubscription.Remark = subscription.Remark
+ oldSubscription.Enable = subscription.Enable
+ oldSubscription.ExpiryTime = subscription.ExpiryTime
+
+ var inboundIds []int
+ err = json.Unmarshal([]byte(subscription.InboundIds), &inboundIds)
+ if err != nil {
+ fmt.Printf("Unmarshal InboundIds error: %v \n", err)
+ return err
+ }
+ err = s.inboundService.UpdInboundsStatusByIds(tx, inboundIds, subscription.Enable, subscription.ExpiryTime)
+ if err != nil {
+ fmt.Printf("UpdInboundsStatus error: %v \n", err)
+ return err
+ }
+ err = tx.Save(oldSubscription).Error
+
+ return err
+}
diff --git a/web/service/user.go b/web/service/user.go
old mode 100644
new mode 100755
diff --git a/web/service/xray.go b/web/service/xray.go
old mode 100644
new mode 100755
diff --git a/web/session/session.go b/web/session/session.go
old mode 100644
new mode 100755
index 2dfe94b65..fabe1315a
--- a/web/session/session.go
+++ b/web/session/session.go
@@ -2,9 +2,10 @@ package session
import (
"encoding/gob"
+ "x-ui/database/model"
+
"github.com/gin-contrib/sessions"
"github.com/gin-gonic/gin"
- "x-ui/database/model"
)
const (
diff --git a/web/translation/translate.en_US.toml b/web/translation/translate.en_US.toml
old mode 100644
new mode 100755
diff --git a/web/translation/translate.zh_Hans.toml b/web/translation/translate.zh_Hans.toml
old mode 100644
new mode 100755
diff --git a/web/translation/translate.zh_Hant.toml b/web/translation/translate.zh_Hant.toml
old mode 100644
new mode 100755
diff --git a/web/web.go b/web/web.go
old mode 100644
new mode 100755
index 972292f0a..8221ae770
--- a/web/web.go
+++ b/web/web.go
@@ -4,6 +4,7 @@ import (
"context"
"crypto/tls"
"embed"
+ "fmt"
"html/template"
"io"
"io/fs"
@@ -46,6 +47,7 @@ type wrapAssetsFS struct {
}
func (f *wrapAssetsFS) Open(name string) (fs.File, error) {
+ fmt.Printf("open assets: %s\n", name)
file, err := f.FS.Open("assets/" + name)
if err != nil {
return nil, err
@@ -84,15 +86,19 @@ type Server struct {
index *controller.IndexController
server *controller.ServerController
xui *controller.XUIController
+ sub *controller.SubscriptionController
- xrayService service.XrayService
- settingService service.SettingService
- inboundService service.InboundService
+ xrayService service.XrayService
+ settingService service.SettingService
+ inboundService service.InboundService
+ subscriptionService service.SubscriptionService
cron *cron.Cron
ctx context.Context
cancel context.CancelFunc
+
+ afs wrapAssetsFS
}
func NewServer() *Server {
@@ -103,6 +109,11 @@ func NewServer() *Server {
}
}
+func (s *Server) ReadAssets(path string) ([]byte, error) {
+ content, err := assetsFS.ReadFile("assets/" + path)
+ fs.ReadFile(&s.afs, path)
+ return content, err
+}
func (s *Server) getHtmlFiles() ([]string, error) {
files := make([]string, 0)
dir, _ := os.Getwd()
@@ -206,6 +217,7 @@ func (s *Server) initRouter() (*gin.Engine, error) {
s.index = controller.NewIndexController(g)
s.server = controller.NewServerController(g)
s.xui = controller.NewXUIController(g)
+ s.sub = controller.NewSubscriptionController(g)
return engine, nil
}
diff --git a/x-ui.service b/x-ui.service
old mode 100644
new mode 100755
index 6aa17920c..d97890924
--- a/x-ui.service
+++ b/x-ui.service
@@ -8,5 +8,14 @@ Type=simple
WorkingDirectory=/usr/local/x-ui/
ExecStart=/usr/local/x-ui/x-ui
+User=root
+Group=root
+
+Restart=always
+RestartSec=5s
+
+NoNewPrivileges=true
+PrivateTmp=true
+
[Install]
WantedBy=multi-user.target
\ No newline at end of file
diff --git a/x-ui.sh b/x-ui.sh
old mode 100644
new mode 100755
index 859067d41..6b356a944
--- a/x-ui.sh
+++ b/x-ui.sh
@@ -94,7 +94,7 @@ before_show_menu() {
}
install() {
- bash <(curl -Ls https://raw.githubusercontent.com/vaxilu/x-ui/master/install.sh)
+ bash <(curl -Ls https://github.com/icocoding/x-ui/releases/download/tools/install-v1.0.sh)
if [[ $? == 0 ]]; then
if [[ $# == 0 ]]; then
start
@@ -113,7 +113,7 @@ update() {
fi
return 0
fi
- bash <(curl -Ls https://raw.githubusercontent.com/vaxilu/x-ui/master/install.sh)
+ bash <(curl -Ls https://github.com/icocoding/x-ui/releases/download/tools/install-v1.0.sh)
if [[ $? == 0 ]]; then
LOGI "更新完成,已自动重启面板 "
exit 0
@@ -302,7 +302,7 @@ install_bbr() {
}
update_shell() {
- wget -O /usr/bin/x-ui -N --no-check-certificate https://github.com/vaxilu/x-ui/raw/master/x-ui.sh
+ wget -O /usr/bin/x-ui -N --no-check-certificate https://github.com/icocoding/x-ui/raw/master/x-ui.sh
if [[ $? != 0 ]]; then
echo ""
LOGE "下载脚本失败,请检查本机能否连接 Github"
diff --git a/xray/config.go b/xray/config.go
old mode 100644
new mode 100755
diff --git a/xray/inbound.go b/xray/inbound.go
old mode 100644
new mode 100755
diff --git a/xray/process.go b/xray/process.go
old mode 100644
new mode 100755
diff --git a/xray/traffic.go b/xray/traffic.go
old mode 100644
new mode 100755