mirror of
https://github.com/MHSanaei/3x-ui.git
synced 2026-07-14 08:36:07 +00:00
Compare commits
26 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 2cf2c451c2 | |||
| 2708c816a8 | |||
| 18cc3d5158 | |||
| 8e8a7d92e9 | |||
| a99d031fe8 | |||
| d0c9cebac1 | |||
| d37dbb7dc8 | |||
| a9f4c5fd77 | |||
| 8a9d9ae24c | |||
| e02a199425 | |||
| d712b44ea1 | |||
| d85a23b6f2 | |||
| a660ad6421 | |||
| 0e17521326 | |||
| 7118d92980 | |||
| 59708d6410 | |||
| be8e78797a | |||
| 6d364638ca | |||
| c147636133 | |||
| fa7a6a3f99 | |||
| 620da1784b | |||
| b13e1d666d | |||
| 2935eeb36a | |||
| eb382cd5b4 | |||
| f02c82677d | |||
| 5a5f7afb68 |
+3
-3
@@ -1,6 +1,6 @@
|
||||
# 3X-UI
|
||||
|
||||
[Español](/README.es_ES.md) | [English](/README.md) | [Chinese](/README.zh.md)
|
||||
[English](/README.md) | [Chinese](/README.zh.md) | [Español](/README.es_ES.md)
|
||||
|
||||
<p align="center"><a href="#"><img src="./media/3X-UI.png" alt="Image"></a></p>
|
||||
|
||||
@@ -28,10 +28,10 @@ bash <(curl -Ls https://raw.githubusercontent.com/mhsanaei/3x-ui/master/install.
|
||||
|
||||
## Instalar una Versión Personalizada
|
||||
|
||||
Para instalar la versión deseada, agrega la versión al final del comando de instalación. Por ejemplo, ver `v2.2.6`:
|
||||
Para instalar la versión deseada, agrega la versión al final del comando de instalación. Por ejemplo, ver `v2.2.8`:
|
||||
|
||||
```
|
||||
bash <(curl -Ls https://raw.githubusercontent.com/mhsanaei/3x-ui/master/install.sh) v2.2.6
|
||||
bash <(curl -Ls https://raw.githubusercontent.com/mhsanaei/3x-ui/master/install.sh) v2.2.8
|
||||
```
|
||||
|
||||
## Certificado SSL
|
||||
|
||||
@@ -28,10 +28,10 @@ bash <(curl -Ls https://raw.githubusercontent.com/mhsanaei/3x-ui/master/install.
|
||||
|
||||
## Install Custom Version
|
||||
|
||||
To install your desired version, add the version to the end of the installation command. e.g., ver `v2.2.7`:
|
||||
To install your desired version, add the version to the end of the installation command. e.g., ver `v2.3.0`:
|
||||
|
||||
```
|
||||
bash <(curl -Ls https://raw.githubusercontent.com/mhsanaei/3x-ui/master/install.sh) v2.2.7
|
||||
bash <(curl -Ls https://raw.githubusercontent.com/mhsanaei/3x-ui/master/install.sh) v2.3.0
|
||||
```
|
||||
|
||||
## SSL Certificate
|
||||
@@ -47,8 +47,20 @@ The Management script has a built-in SSL certificate application for Cloudflare.
|
||||
- Cloudflare Global API Key
|
||||
- The domain name has been resolved to the current server through cloudflare
|
||||
|
||||
**1:** Run the`x-ui`command on the terminal, then choose `Cloudflare SSL Certificate`.
|
||||
How to get the Cloudflare Global API Key:
|
||||
|
||||
1. Run the`x-ui`command on the terminal, then choose `Cloudflare SSL Certificate`.
|
||||
|
||||
2. Visit the link https://dash.cloudflare.com/profile/api-tokens
|
||||
|
||||
3. Click on View Global API Key (See the screenshot below)
|
||||

|
||||
|
||||
4. You may have to re-authenticate your account. After that, the API Key will be shown (See the screenshot below)\
|
||||

|
||||
|
||||
When using, just enter `domain name`, `email`, `API KEY`, the diagram is as follows:
|
||||

|
||||
|
||||
### Certbot
|
||||
```
|
||||
@@ -183,6 +195,7 @@ remove 3x-ui from docker
|
||||
- CentOS 8+
|
||||
- Fedora 36+
|
||||
- Arch Linux
|
||||
- Parch Linux
|
||||
- Manjaro
|
||||
- Armbian
|
||||
- AlmaLinux 9+
|
||||
|
||||
+3
-3
@@ -1,6 +1,6 @@
|
||||
# 3X-UI
|
||||
|
||||
[English](/README.md) | [Chinese](/README.zh.md)
|
||||
[English](/README.md) | [Chinese](/README.zh.md) | [Español](/README.es_ES.md)
|
||||
|
||||
<p align="center"><a href="#"><img src="./media/3X-UI.png" alt="Image"></a></p>
|
||||
|
||||
@@ -28,10 +28,10 @@ bash <(curl -Ls https://raw.githubusercontent.com/mhsanaei/3x-ui/master/install.
|
||||
|
||||
## 安装指定版本
|
||||
|
||||
要安装所需的版本,请将该版本添加到安装命令的末尾。 e.g., ver `v2.2.6`:
|
||||
要安装所需的版本,请将该版本添加到安装命令的末尾。 e.g., ver `v2.2.8`:
|
||||
|
||||
```
|
||||
bash <(curl -Ls https://raw.githubusercontent.com/mhsanaei/3x-ui/master/install.sh) v2.2.6
|
||||
bash <(curl -Ls https://raw.githubusercontent.com/mhsanaei/3x-ui/master/install.sh) v2.2.8
|
||||
```
|
||||
|
||||
## SSL 认证
|
||||
|
||||
+1
-1
@@ -1 +1 @@
|
||||
2.2.7
|
||||
2.3.0
|
||||
@@ -91,7 +91,7 @@ type Client struct {
|
||||
TotalGB int64 `json:"totalGB" form:"totalGB"`
|
||||
ExpiryTime int64 `json:"expiryTime" form:"expiryTime"`
|
||||
Enable bool `json:"enable" form:"enable"`
|
||||
TgID string `json:"tgId" form:"tgId"`
|
||||
TgID int64 `json:"tgId" form:"tgId"`
|
||||
SubID string `json:"subId" form:"subId"`
|
||||
Reset int `json:"reset" form:"reset"`
|
||||
}
|
||||
|
||||
@@ -1,23 +1,23 @@
|
||||
module x-ui
|
||||
|
||||
go 1.22.0
|
||||
go 1.22.2
|
||||
|
||||
require (
|
||||
github.com/Calidity/gin-sessions v1.3.1
|
||||
github.com/gin-contrib/gzip v1.0.0
|
||||
github.com/gin-gonic/gin v1.9.1
|
||||
github.com/goccy/go-json v0.10.2
|
||||
github.com/mymmrac/telego v0.29.1
|
||||
github.com/mymmrac/telego v0.29.2
|
||||
github.com/nicksnyder/go-i18n/v2 v2.4.0
|
||||
github.com/op/go-logging v0.0.0-20160315200505-970db520ece7
|
||||
github.com/pelletier/go-toml/v2 v2.2.0
|
||||
github.com/pelletier/go-toml/v2 v2.2.1
|
||||
github.com/robfig/cron/v3 v3.0.1
|
||||
github.com/shirou/gopsutil/v3 v3.24.2
|
||||
github.com/shirou/gopsutil/v3 v3.24.3
|
||||
github.com/valyala/fasthttp v1.52.0
|
||||
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.62.1
|
||||
google.golang.org/grpc v1.63.2
|
||||
gorm.io/driver/sqlite v1.5.5
|
||||
gorm.io/gorm v1.25.9
|
||||
)
|
||||
@@ -38,7 +38,6 @@ require (
|
||||
github.com/go-playground/universal-translator v0.18.1 // indirect
|
||||
github.com/go-playground/validator/v10 v10.19.0 // indirect
|
||||
github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 // indirect
|
||||
github.com/golang/protobuf v1.5.4 // indirect
|
||||
github.com/google/btree v1.1.2 // indirect
|
||||
github.com/google/pprof v0.0.0-20240227163752-401108e1b7e7 // indirect
|
||||
github.com/gorilla/context v1.1.2 // indirect
|
||||
@@ -83,16 +82,16 @@ require (
|
||||
go.uber.org/mock v0.4.0 // indirect
|
||||
go4.org/netipx v0.0.0-20231129151722-fdeea329fbba // indirect
|
||||
golang.org/x/arch v0.7.0 // indirect
|
||||
golang.org/x/crypto v0.21.0 // indirect
|
||||
golang.org/x/crypto v0.22.0 // indirect
|
||||
golang.org/x/exp v0.0.0-20240222234643-814bf88cf225 // indirect
|
||||
golang.org/x/mod v0.16.0 // indirect
|
||||
golang.org/x/net v0.22.0 // indirect
|
||||
golang.org/x/sys v0.18.0 // indirect
|
||||
golang.org/x/net v0.24.0 // indirect
|
||||
golang.org/x/sys v0.19.0 // indirect
|
||||
golang.org/x/time v0.5.0 // indirect
|
||||
golang.org/x/tools v0.19.0 // indirect
|
||||
golang.zx2c4.com/wintun v0.0.0-20230126152724-0fa3db229ce2 // indirect
|
||||
golang.zx2c4.com/wireguard v0.0.0-20231211153847-12269c276173 // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240308144416-29370a3891b7 // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240415180920-8c6c420018be // indirect
|
||||
google.golang.org/protobuf v1.33.0 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
gvisor.dev/gvisor v0.0.0-20231104011432-48a6d7d5bd0b // indirect
|
||||
|
||||
@@ -163,8 +163,8 @@ github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJ
|
||||
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
|
||||
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/mymmrac/telego v0.29.1 h1:nsNnK0mS18OL+unoDjDI6BVfafJBbT8Wtj7rCzEWoM8=
|
||||
github.com/mymmrac/telego v0.29.1/go.mod h1:ZLD1+L2TQRr97NPOCoN1V2w8y9kmFov33OfZ3qT8cF4=
|
||||
github.com/mymmrac/telego v0.29.2 h1:5+fQ/b8d8Ld6ihCJ0OLe1CwUdT3t1sIUl3RaSaSvRJs=
|
||||
github.com/mymmrac/telego v0.29.2/go.mod h1:BsKr+GF9BHqaVaLBwsZeDnfuJcJx2olWuDEtKm4zHMc=
|
||||
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.4.0 h1:3IcvPOAvnCKwNm0TB0dLDTuawWEj+ax/RERNC+diLMM=
|
||||
@@ -178,8 +178,8 @@ github.com/op/go-logging v0.0.0-20160315200505-970db520ece7/go.mod h1:HzydrMdWEr
|
||||
github.com/openzipkin/zipkin-go v0.1.1/go.mod h1:NtoC/o8u3JlF1lSlyPNswIbeQH9bJTmOf0Erfk+hxe8=
|
||||
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/pelletier/go-toml/v2 v2.2.1 h1:9TA9+T8+8CUCO2+WYnDLCgrYi9+omqKXyjDtosvtEhg=
|
||||
github.com/pelletier/go-toml/v2 v2.2.1/go.mod h1:1t835xjRzz80PqgE6HHgN2JOsmgYu/h4qDAS4n929Rs=
|
||||
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/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
@@ -212,8 +212,8 @@ github.com/savsgio/gotils v0.0.0-20240303185622-093b76447511/go.mod h1:sM7Mt7uEo
|
||||
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/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo=
|
||||
github.com/shirou/gopsutil/v3 v3.24.2 h1:kcR0erMbLg5/3LcInpw0X/rrPSqq4CDPyI6A6ZRC18Y=
|
||||
github.com/shirou/gopsutil/v3 v3.24.2/go.mod h1:tSg/594BcA+8UdQU2XcW803GWYgdtauFFPgJCJKZlVk=
|
||||
github.com/shirou/gopsutil/v3 v3.24.3 h1:eoUGJSmdfLzJ3mxIhmOAhgKEKgQkeOwKpz1NbhVnuPE=
|
||||
github.com/shirou/gopsutil/v3 v3.24.3/go.mod h1:JpND7O217xa72ewWz9zN2eIIkPWsDN/3pl0H8Qt0uwg=
|
||||
github.com/shoenig/go-m1cpu v0.1.6 h1:nxdKQNcEB6vzgA2E2bvzKIYRuNj7XNJ4S/aRSwKzFtM=
|
||||
github.com/shoenig/go-m1cpu v0.1.6/go.mod h1:1JJMcUBvfNwpq05QDQVAnx3gUHr9IYF7GNg9SUEw2VQ=
|
||||
github.com/shoenig/test v0.6.4 h1:kVTaSd7WLz5WZ2IaoM0RSzRsUD+m8wRR+5qvntpn4LU=
|
||||
@@ -301,8 +301,8 @@ golang.org/x/build v0.0.0-20190111050920-041ab4dc3f9d/go.mod h1:OWs+y06UdEOHN4y+
|
||||
golang.org/x/crypto v0.0.0-20181030102418-4d3f4d9ffa16/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
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.21.0 h1:X31++rzVUdKhX5sWmSOFZxx8UW/ldWx55cbf08iNAMA=
|
||||
golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs=
|
||||
golang.org/x/crypto v0.22.0 h1:g1v0xeRhjcugydODzvb3mEM9SQ0HGp9s/nh3COQ/C30=
|
||||
golang.org/x/crypto v0.22.0/go.mod h1:vr6Su+7cTlO45qkww3VDJlzDn0ctJvRgYbC2NvXHt+M=
|
||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
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=
|
||||
@@ -319,8 +319,8 @@ golang.org/x/net v0.0.0-20181106065722-10aee1819953/go.mod h1:mL1N/T3taQHkDXs73r
|
||||
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-20190313220215-9f648a60d977/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
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/net v0.24.0 h1:1PcaxkF854Fu3+lvBIx5SYn9wRlBzzcnHZSiaFFAb0w=
|
||||
golang.org/x/net v0.24.0/go.mod h1:2Q7sJY5mzlzWjKtYUEXSlBWCdyaioyXzRB2RtU8KVE8=
|
||||
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=
|
||||
@@ -346,9 +346,9 @@ 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.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
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/sys v0.19.0 h1:q5f1RH2jigJ1MoAWp2KTp3gm5zAGFUTarQZ5U386+4o=
|
||||
golang.org/x/sys v0.19.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
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.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
|
||||
@@ -380,14 +380,14 @@ google.golang.org/genproto v0.0.0-20180831171423-11092d34479b/go.mod h1:JiN7NxoA
|
||||
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/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/genproto/googleapis/rpc v0.0.0-20240415180920-8c6c420018be h1:LG9vZxsWGOmUKieR8wPAUR3u3MpnYFQZROPIMaXh7/A=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240415180920-8c6c420018be/go.mod h1:WtryC6hu0hhx87FDGxWCDptyssuo68sk10vYjF+T9fY=
|
||||
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.62.1 h1:B4n+nfKzOICUXMgyrNd19h/I9oH0L1pizfk1d4zSgTk=
|
||||
google.golang.org/grpc v1.62.1/go.mod h1:IWTG0VlJLCh1SkC58F7np9ka9mx/WNkjl4PGJaiq+QE=
|
||||
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/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
|
||||
+4
-1
@@ -43,6 +43,8 @@ os_version=$(grep -i version_id /etc/os-release | cut -d \" -f2 | cut -d . -f1)
|
||||
|
||||
if [[ "${release}" == "arch" ]]; then
|
||||
echo "Your OS is Arch Linux"
|
||||
elif [[ "${release}" == "parch" ]]; then
|
||||
echo "Your OS is Parch linux"
|
||||
elif [[ "${release}" == "manjaro" ]]; then
|
||||
echo "Your OS is Manjaro"
|
||||
elif [[ "${release}" == "armbian" ]]; then
|
||||
@@ -83,6 +85,7 @@ else
|
||||
echo "- CentOS 8+"
|
||||
echo "- Fedora 36+"
|
||||
echo "- Arch Linux"
|
||||
echo "- Parch Linux"
|
||||
echo "- Manjaro"
|
||||
echo "- Armbian"
|
||||
echo "- AlmaLinux 9+"
|
||||
@@ -100,7 +103,7 @@ install_base() {
|
||||
fedora)
|
||||
dnf -y update && dnf install -y -q wget curl tar tzdata
|
||||
;;
|
||||
arch | manjaro)
|
||||
arch | manjaro | parch)
|
||||
pacman -Syu && pacman -Syu --noconfirm wget curl tar tzdata
|
||||
;;
|
||||
*)
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 15 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 9.8 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 6.7 KiB |
+30
-6
@@ -231,8 +231,13 @@ func (s *SubService) genVmessLink(inbound *model.Inbound, email string) string {
|
||||
httpupgrade, _ := stream["httpupgradeSettings"].(map[string]interface{})
|
||||
obj["path"] = httpupgrade["path"].(string)
|
||||
obj["host"] = httpupgrade["host"].(string)
|
||||
if headers, ok := httpupgrade["headers"].(map[string]interface{}); ok {
|
||||
hostFromHeaders := searchHost(headers)
|
||||
if hostFromHeaders != "" {
|
||||
obj["host"] = hostFromHeaders
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
security, _ := stream["security"].(string)
|
||||
obj["tls"] = security
|
||||
if security == "tls" {
|
||||
@@ -347,8 +352,8 @@ func (s *SubService) genVlessLink(inbound *model.Inbound, email string) string {
|
||||
case "ws":
|
||||
ws, _ := stream["wsSettings"].(map[string]interface{})
|
||||
params["path"] = ws["path"].(string)
|
||||
headers, _ := ws["headers"].(map[string]interface{})
|
||||
params["host"] = ws["host"].(string)
|
||||
headers, _ := ws["headers"].(map[string]interface{})
|
||||
if headers != nil {
|
||||
hostFromHeaders := searchHost(headers)
|
||||
if hostFromHeaders != "" {
|
||||
@@ -376,8 +381,14 @@ func (s *SubService) genVlessLink(inbound *model.Inbound, email string) string {
|
||||
httpupgrade, _ := stream["httpupgradeSettings"].(map[string]interface{})
|
||||
params["path"] = httpupgrade["path"].(string)
|
||||
params["host"] = httpupgrade["host"].(string)
|
||||
headers, _ := httpupgrade["headers"].(map[string]interface{})
|
||||
if headers != nil {
|
||||
hostFromHeaders := searchHost(headers)
|
||||
if hostFromHeaders != "" {
|
||||
params["host"] = hostFromHeaders
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
security, _ := stream["security"].(string)
|
||||
if security == "tls" {
|
||||
params["security"] = "tls"
|
||||
@@ -570,8 +581,8 @@ func (s *SubService) genTrojanLink(inbound *model.Inbound, email string) string
|
||||
case "ws":
|
||||
ws, _ := stream["wsSettings"].(map[string]interface{})
|
||||
params["path"] = ws["path"].(string)
|
||||
headers, _ := ws["headers"].(map[string]interface{})
|
||||
params["host"] = ws["host"].(string)
|
||||
headers, _ := ws["headers"].(map[string]interface{})
|
||||
if headers != nil {
|
||||
hostFromHeaders := searchHost(headers)
|
||||
if hostFromHeaders != "" {
|
||||
@@ -599,8 +610,14 @@ func (s *SubService) genTrojanLink(inbound *model.Inbound, email string) string
|
||||
httpupgrade, _ := stream["httpupgradeSettings"].(map[string]interface{})
|
||||
params["path"] = httpupgrade["path"].(string)
|
||||
params["host"] = httpupgrade["host"].(string)
|
||||
headers, _ := httpupgrade["headers"].(map[string]interface{})
|
||||
if headers != nil {
|
||||
hostFromHeaders := searchHost(headers)
|
||||
if hostFromHeaders != "" {
|
||||
params["host"] = hostFromHeaders
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
security, _ := stream["security"].(string)
|
||||
if security == "tls" {
|
||||
params["security"] = "tls"
|
||||
@@ -794,8 +811,8 @@ func (s *SubService) genShadowsocksLink(inbound *model.Inbound, email string) st
|
||||
case "ws":
|
||||
ws, _ := stream["wsSettings"].(map[string]interface{})
|
||||
params["path"] = ws["path"].(string)
|
||||
headers, _ := ws["headers"].(map[string]interface{})
|
||||
params["host"] = ws["host"].(string)
|
||||
headers, _ := ws["headers"].(map[string]interface{})
|
||||
if headers != nil {
|
||||
hostFromHeaders := searchHost(headers)
|
||||
if hostFromHeaders != "" {
|
||||
@@ -823,6 +840,13 @@ func (s *SubService) genShadowsocksLink(inbound *model.Inbound, email string) st
|
||||
httpupgrade, _ := stream["httpupgradeSettings"].(map[string]interface{})
|
||||
params["path"] = httpupgrade["path"].(string)
|
||||
params["host"] = httpupgrade["host"].(string)
|
||||
headers, _ := httpupgrade["headers"].(map[string]interface{})
|
||||
if headers != nil {
|
||||
hostFromHeaders := searchHost(headers)
|
||||
if hostFromHeaders != "" {
|
||||
params["host"] = hostFromHeaders
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
security, _ := stream["security"].(string)
|
||||
|
||||
File diff suppressed because one or more lines are too long
+1
-1
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Vendored
+3
-8
File diff suppressed because one or more lines are too long
+4
-4
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -3,7 +3,7 @@
|
||||
|
||||
// This is CodeMirror (https://codemirror.net/5), a code editor
|
||||
// implemented in JavaScript on top of the browser's DOM.
|
||||
//
|
||||
// CodeMirror v5.65.15
|
||||
// You can find some technical background for some of the code below
|
||||
// at http://marijnhaverbeke.nl/blog/#cm-internals .
|
||||
|
||||
|
||||
+1
-1459
File diff suppressed because one or more lines are too long
@@ -194,8 +194,7 @@ class WsStreamSettings extends CommonClass {
|
||||
static fromJson(json={}) {
|
||||
return new WsStreamSettings(
|
||||
json.path,
|
||||
json.host,
|
||||
json.headers && !ObjectUtil.isEmpty(json.headers.Host) ? json.headers.Host : '',
|
||||
json.host
|
||||
);
|
||||
}
|
||||
|
||||
@@ -289,7 +288,7 @@ class HttpUpgradeStreamSettings extends CommonClass {
|
||||
static fromJson(json={}) {
|
||||
return new HttpUpgradeStreamSettings(
|
||||
json.path,
|
||||
json.Host,
|
||||
json.host
|
||||
);
|
||||
}
|
||||
|
||||
@@ -297,6 +296,7 @@ class HttpUpgradeStreamSettings extends CommonClass {
|
||||
return {
|
||||
path: this.path,
|
||||
host: this.host,
|
||||
headers: ObjectUtil.isEmpty(this.host) ? undefined : {Host: this.host},
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -830,7 +830,7 @@ Outbound.FreedomSettings.Fragment = class extends CommonClass {
|
||||
Outbound.BlackholeSettings = class extends CommonClass {
|
||||
constructor(type) {
|
||||
super();
|
||||
this.type;
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
static fromJson(json={}) {
|
||||
|
||||
+87
-43
@@ -475,19 +475,38 @@ class GrpcStreamSettings extends XrayCommonClass {
|
||||
}
|
||||
}
|
||||
|
||||
class HttpUpgradeStreamSettings extends XrayCommonClass {
|
||||
constructor(acceptProxyProtocol=false, path='/', host='') {
|
||||
class HTTPUpgradeStreamSettings extends XrayCommonClass {
|
||||
constructor(acceptProxyProtocol=false, path='/', host='', headers=[]) {
|
||||
super();
|
||||
this.acceptProxyProtocol = acceptProxyProtocol;
|
||||
this.path = path;
|
||||
this.host = host;
|
||||
this.headers = headers;
|
||||
}
|
||||
|
||||
addHeader(name, value) {
|
||||
this.headers.push({ name: name, value: value });
|
||||
}
|
||||
|
||||
getHeader(name) {
|
||||
for (const header of this.headers) {
|
||||
if (header.name.toLowerCase() === name.toLowerCase()) {
|
||||
return header.value;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
removeHeader(index) {
|
||||
this.headers.splice(index, 1);
|
||||
}
|
||||
|
||||
static fromJson(json={}) {
|
||||
return new HttpUpgradeStreamSettings(
|
||||
return new HTTPUpgradeStreamSettings(
|
||||
json.acceptProxyProtocol,
|
||||
json.path,
|
||||
json.host,
|
||||
XrayCommonClass.toHeaders(json.headers),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -496,6 +515,7 @@ class HttpUpgradeStreamSettings extends XrayCommonClass {
|
||||
acceptProxyProtocol: this.acceptProxyProtocol,
|
||||
path: this.path,
|
||||
host: this.host,
|
||||
headers: XrayCommonClass.toV2Headers(this.headers, false),
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -864,7 +884,7 @@ class StreamSettings extends XrayCommonClass {
|
||||
httpSettings=new HttpStreamSettings(),
|
||||
quicSettings=new QuicStreamSettings(),
|
||||
grpcSettings=new GrpcStreamSettings(),
|
||||
httpupgradeSettings=new HttpUpgradeStreamSettings(),
|
||||
httpupgradeSettings=new HTTPUpgradeStreamSettings(),
|
||||
sockopt = undefined,
|
||||
) {
|
||||
super();
|
||||
@@ -943,7 +963,7 @@ class StreamSettings extends XrayCommonClass {
|
||||
HttpStreamSettings.fromJson(json.httpSettings),
|
||||
QuicStreamSettings.fromJson(json.quicSettings),
|
||||
GrpcStreamSettings.fromJson(json.grpcSettings),
|
||||
HttpUpgradeStreamSettings.fromJson(json.httpupgradeSettings),
|
||||
HTTPUpgradeStreamSettings.fromJson(json.httpupgradeSettings),
|
||||
SockoptStreamSettings.fromJson(json.sockopt),
|
||||
);
|
||||
}
|
||||
@@ -1120,7 +1140,12 @@ class Inbound extends XrayCommonClass {
|
||||
} else if (this.isH2) {
|
||||
return this.stream.http.host[0];
|
||||
} else if (this.isHttpupgrade) {
|
||||
return this.stream.httpupgrade.host;
|
||||
const hostHeader = this.stream.httpupgrade.getHeader("Host");
|
||||
if (hostHeader !== null) {
|
||||
return hostHeader;
|
||||
} else {
|
||||
return this.stream.httpupgrade.host;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
@@ -1261,6 +1286,10 @@ class Inbound extends XrayCommonClass {
|
||||
let httpupgrade = this.stream.httpupgrade;
|
||||
obj.path = httpupgrade.path;
|
||||
obj.host = httpupgrade.host;
|
||||
let index = httpupgrade.headers.findIndex(header => header.name.toLowerCase() === 'host');
|
||||
if (index >= 0) {
|
||||
obj.host = httpupgrade.headers[index].value;
|
||||
}
|
||||
}
|
||||
|
||||
if (security === 'tls') {
|
||||
@@ -1293,9 +1322,9 @@ class Inbound extends XrayCommonClass {
|
||||
if (tcp.type === 'http') {
|
||||
const request = tcp.request;
|
||||
params.set("path", request.path.join(','));
|
||||
const index = request.headers.findIndex(header => header.name.toLowerCase() === 'host');
|
||||
if (index >= 0) {
|
||||
const host = request.headers[index].value;
|
||||
const tcpIndex = request.headers.findIndex(header => header.name.toLowerCase() === 'host');
|
||||
if (tcpIndex >= 0) {
|
||||
const host = request.headers[tcpIndex].value;
|
||||
params.set("host", host);
|
||||
}
|
||||
params.set("headerType", 'http');
|
||||
@@ -1310,9 +1339,9 @@ class Inbound extends XrayCommonClass {
|
||||
const ws = this.stream.ws;
|
||||
params.set("path", ws.path);
|
||||
params.set("host", ws.host);
|
||||
const index = ws.headers.findIndex(header => header.name.toLowerCase() === 'host');
|
||||
if (index >= 0) {
|
||||
const host = ws.headers[index].value;
|
||||
const wsIndex = ws.headers.findIndex(header => header.name.toLowerCase() === 'host');
|
||||
if (wsIndex >= 0) {
|
||||
const host = ws.headers[wsIndex].value;
|
||||
params.set("host", host);
|
||||
}
|
||||
break;
|
||||
@@ -1336,9 +1365,14 @@ class Inbound extends XrayCommonClass {
|
||||
}
|
||||
break;
|
||||
case "httpupgrade":
|
||||
const httpupgrade = this.stream.httpupgrade;
|
||||
params.set("path", httpupgrade.path);
|
||||
params.set("host", httpupgrade.host);
|
||||
const httpupgrade = this.stream.httpupgrade;
|
||||
params.set("path", httpupgrade.path);
|
||||
params.set("host", httpupgrade.host);
|
||||
const httpupgradeIndex = httpupgrade.headers.findIndex(header => header.name.toLowerCase() === 'host');
|
||||
if (httpupgradeIndex >= 0) {
|
||||
const host = httpupgrade.headers[httpupgradeIndex].value;
|
||||
params.set("host", host);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -1402,7 +1436,7 @@ class Inbound extends XrayCommonClass {
|
||||
return url.toString();
|
||||
}
|
||||
|
||||
genSSLink(address='', port=this.port, forceTls, remark='', clientPassword) {
|
||||
genSSLink(address = '', port = this.port, forceTls, remark = '', clientPassword) {
|
||||
let settings = this.settings;
|
||||
const type = this.stream.network;
|
||||
const security = forceTls == 'same' ? this.stream.security : forceTls;
|
||||
@@ -1414,9 +1448,9 @@ class Inbound extends XrayCommonClass {
|
||||
if (tcp.type === 'http') {
|
||||
const request = tcp.request;
|
||||
params.set("path", request.path.join(','));
|
||||
const index = request.headers.findIndex(header => header.name.toLowerCase() === 'host');
|
||||
if (index >= 0) {
|
||||
const host = request.headers[index].value;
|
||||
const tcpIndex = request.headers.findIndex(header => header.name.toLowerCase() === 'host');
|
||||
if (tcpIndex >= 0) {
|
||||
const host = request.headers[tcpIndex].value;
|
||||
params.set("host", host);
|
||||
}
|
||||
params.set("headerType", 'http');
|
||||
@@ -1431,9 +1465,9 @@ class Inbound extends XrayCommonClass {
|
||||
const ws = this.stream.ws;
|
||||
params.set("path", ws.path);
|
||||
params.set("host", ws.host);
|
||||
const index = ws.headers.findIndex(header => header.name.toLowerCase() === 'host');
|
||||
if (index >= 0) {
|
||||
const host = ws.headers[index].value;
|
||||
const wsIndex = ws.headers.findIndex(header => header.name.toLowerCase() === 'host');
|
||||
if (wsIndex >= 0) {
|
||||
const host = ws.headers[wsIndex].value;
|
||||
params.set("host", host);
|
||||
}
|
||||
break;
|
||||
@@ -1452,26 +1486,31 @@ class Inbound extends XrayCommonClass {
|
||||
const grpc = this.stream.grpc;
|
||||
params.set("serviceName", grpc.serviceName);
|
||||
params.set("authority", grpc.authority);
|
||||
if(grpc.multiMode){
|
||||
if (grpc.multiMode) {
|
||||
params.set("mode", "multi");
|
||||
}
|
||||
break;
|
||||
case "httpupgrade":
|
||||
const httpupgrade = this.stream.httpupgrade;
|
||||
params.set("path", httpupgrade.path);
|
||||
params.set("host", httpupgrade.host);
|
||||
const httpupgrade = this.stream.httpupgrade;
|
||||
params.set("path", httpupgrade.path);
|
||||
params.set("host", httpupgrade.host);
|
||||
const httpupgradeIndex = httpupgrade.headers.findIndex(header => header.name.toLowerCase() === 'host');
|
||||
if (httpupgradeIndex >= 0) {
|
||||
const host = httpupgrade.headers[httpupgradeIndex].value;
|
||||
params.set("host", host);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (security === 'tls') {
|
||||
params.set("security", "tls");
|
||||
if (this.stream.isTls){
|
||||
params.set("fp" , this.stream.tls.settings.fingerprint);
|
||||
if (this.stream.isTls) {
|
||||
params.set("fp", this.stream.tls.settings.fingerprint);
|
||||
params.set("alpn", this.stream.tls.alpn);
|
||||
if(this.stream.tls.settings.allowInsecure){
|
||||
if (this.stream.tls.settings.allowInsecure) {
|
||||
params.set("allowInsecure", "1");
|
||||
}
|
||||
if (!ObjectUtil.isEmpty(this.stream.tls.sni)){
|
||||
if (!ObjectUtil.isEmpty(this.stream.tls.sni)) {
|
||||
params.set("sni", this.stream.tls.sni);
|
||||
}
|
||||
}
|
||||
@@ -1502,9 +1541,9 @@ class Inbound extends XrayCommonClass {
|
||||
if (tcp.type === 'http') {
|
||||
const request = tcp.request;
|
||||
params.set("path", request.path.join(','));
|
||||
const index = request.headers.findIndex(header => header.name.toLowerCase() === 'host');
|
||||
if (index >= 0) {
|
||||
const host = request.headers[index].value;
|
||||
const tcpIndex = request.headers.findIndex(header => header.name.toLowerCase() === 'host');
|
||||
if (tcpIndex >= 0) {
|
||||
const host = request.headers[tcpIndex].value;
|
||||
params.set("host", host);
|
||||
}
|
||||
params.set("headerType", 'http');
|
||||
@@ -1519,9 +1558,9 @@ class Inbound extends XrayCommonClass {
|
||||
const ws = this.stream.ws;
|
||||
params.set("path", ws.path);
|
||||
params.set("host", ws.host);
|
||||
const index = ws.headers.findIndex(header => header.name.toLowerCase() === 'host');
|
||||
if (index >= 0) {
|
||||
const host = ws.headers[index].value;
|
||||
const wsIndex = ws.headers.findIndex(header => header.name.toLowerCase() === 'host');
|
||||
if (wsIndex >= 0) {
|
||||
const host = ws.headers[wsIndex].value;
|
||||
params.set("host", host);
|
||||
}
|
||||
break;
|
||||
@@ -1545,9 +1584,14 @@ class Inbound extends XrayCommonClass {
|
||||
}
|
||||
break;
|
||||
case "httpupgrade":
|
||||
const httpupgrade = this.stream.httpupgrade;
|
||||
params.set("path", httpupgrade.path);
|
||||
params.set("host", httpupgrade.host);
|
||||
const httpupgrade = this.stream.httpupgrade;
|
||||
params.set("path", httpupgrade.path);
|
||||
params.set("host", httpupgrade.host);
|
||||
const httpUpgradeIndex = httpupgrade.headers.findIndex(header => header.name.toLowerCase() === 'host');
|
||||
if (httpUpgradeIndex >= 0) {
|
||||
const host = httpupgrade.headers[httpUpgradeIndex].value;
|
||||
params.set("host", host);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -1804,7 +1848,7 @@ Inbound.VmessSettings = class extends Inbound.Settings {
|
||||
}
|
||||
};
|
||||
Inbound.VmessSettings.Vmess = class extends XrayCommonClass {
|
||||
constructor(id=RandomUtil.randomUUID(), email=RandomUtil.randomLowerAndNum(8),limitIp=0, totalGB=0, expiryTime=0, enable=true, tgId='', subId=RandomUtil.randomLowerAndNum(16), reset=0) {
|
||||
constructor(id=RandomUtil.randomUUID(), email=RandomUtil.randomLowerAndNum(8),limitIp=0, totalGB=0, expiryTime=0, enable=true, tgId=0, subId=RandomUtil.randomLowerAndNum(16), reset=0) {
|
||||
super();
|
||||
this.id = id;
|
||||
this.email = email;
|
||||
@@ -1895,7 +1939,7 @@ Inbound.VLESSSettings = class extends Inbound.Settings {
|
||||
};
|
||||
|
||||
Inbound.VLESSSettings.VLESS = class extends XrayCommonClass {
|
||||
constructor(id=RandomUtil.randomUUID(), flow='', email=RandomUtil.randomLowerAndNum(8),limitIp=0, totalGB=0, expiryTime=0, enable=true, tgId='', subId=RandomUtil.randomLowerAndNum(16), reset=0) {
|
||||
constructor(id=RandomUtil.randomUUID(), flow='', email=RandomUtil.randomLowerAndNum(8),limitIp=0, totalGB=0, expiryTime=0, enable=true, tgId=0, subId=RandomUtil.randomLowerAndNum(16), reset=0) {
|
||||
super();
|
||||
this.id = id;
|
||||
this.flow = flow;
|
||||
@@ -2020,7 +2064,7 @@ Inbound.TrojanSettings = class extends Inbound.Settings {
|
||||
}
|
||||
};
|
||||
Inbound.TrojanSettings.Trojan = class extends XrayCommonClass {
|
||||
constructor(password=RandomUtil.randomSeq(10), flow='', email=RandomUtil.randomLowerAndNum(8),limitIp=0, totalGB=0, expiryTime=0, enable=true, tgId='', subId=RandomUtil.randomLowerAndNum(16), reset=0) {
|
||||
constructor(password=RandomUtil.randomSeq(10), flow='', email=RandomUtil.randomLowerAndNum(8),limitIp=0, totalGB=0, expiryTime=0, enable=true, tgId=0, subId=RandomUtil.randomLowerAndNum(16), reset=0) {
|
||||
super();
|
||||
this.password = password;
|
||||
this.flow = flow;
|
||||
@@ -2165,7 +2209,7 @@ Inbound.ShadowsocksSettings = class extends Inbound.Settings {
|
||||
};
|
||||
|
||||
Inbound.ShadowsocksSettings.Shadowsocks = class extends XrayCommonClass {
|
||||
constructor(method='', password=RandomUtil.randomShadowsocksPassword(), email=RandomUtil.randomLowerAndNum(8),limitIp=0, totalGB=0, expiryTime=0, enable=true, tgId='', subId=RandomUtil.randomLowerAndNum(16), reset=0) {
|
||||
constructor(method='', password=RandomUtil.randomShadowsocksPassword(), email=RandomUtil.randomLowerAndNum(8),limitIp=0, totalGB=0, expiryTime=0, enable=true, tgId=0, subId=RandomUtil.randomLowerAndNum(16), reset=0) {
|
||||
super();
|
||||
this.method = method;
|
||||
this.password = password;
|
||||
|
||||
+1
-1252
File diff suppressed because one or more lines are too long
+1
-455
File diff suppressed because one or more lines are too long
Vendored
+92
-90
@@ -1,93 +1,95 @@
|
||||
/*! URI.js v1.19.5 http://medialize.github.io/URI.js/ */
|
||||
/*! URI.js v1.19.11 http://medialize.github.io/URI.js/ */
|
||||
/* build contains: IPv6.js, punycode.js, SecondLevelDomains.js, URI.js, URITemplate.js */
|
||||
(function(r,x){"object"===typeof module&&module.exports?module.exports=x():"function"===typeof define&&define.amd?define(x):r.IPv6=x(r)})(this,function(r){var x=r&&r.IPv6;return{best:function(k){k=k.toLowerCase().split(":");var m=k.length,d=8;""===k[0]&&""===k[1]&&""===k[2]?(k.shift(),k.shift()):""===k[0]&&""===k[1]?k.shift():""===k[m-1]&&""===k[m-2]&&k.pop();m=k.length;-1!==k[m-1].indexOf(".")&&(d=7);var q;for(q=0;q<m&&""!==k[q];q++);if(q<d)for(k.splice(q,1,"0000");k.length<d;)k.splice(q,0,"0000");
|
||||
for(q=0;q<d;q++){m=k[q].split("");for(var E=0;3>E;E++)if("0"===m[0]&&1<m.length)m.splice(0,1);else break;k[q]=m.join("")}m=-1;var A=E=0,h=-1,p=!1;for(q=0;q<d;q++)p?"0"===k[q]?A+=1:(p=!1,A>E&&(m=h,E=A)):"0"===k[q]&&(p=!0,h=q,A=1);A>E&&(m=h,E=A);1<E&&k.splice(m,E,"");m=k.length;d="";""===k[0]&&(d=":");for(q=0;q<m;q++){d+=k[q];if(q===m-1)break;d+=":"}""===k[m-1]&&(d+=":");return d},noConflict:function(){r.IPv6===this&&(r.IPv6=x);return this}}});
|
||||
(function(r){function x(l){throw new RangeError(H[l]);}function k(l,t){for(var C=l.length,y=[];C--;)y[C]=t(l[C]);return y}function m(l,t){var C=l.split("@"),y="";1<C.length&&(y=C[0]+"@",l=C[1]);l=l.replace(w,".");C=l.split(".");C=k(C,t).join(".");return y+C}function d(l){for(var t=[],C=0,y=l.length,J,M;C<y;)J=l.charCodeAt(C++),55296<=J&&56319>=J&&C<y?(M=l.charCodeAt(C++),56320==(M&64512)?t.push(((J&1023)<<10)+(M&1023)+65536):(t.push(J),C--)):t.push(J);return t}function q(l){return k(l,function(t){var C=
|
||||
"";65535<t&&(t-=65536,C+=g(t>>>10&1023|55296),t=56320|t&1023);return C+=g(t)}).join("")}function E(l,t,C){var y=0;l=C?v(l/700):l>>1;for(l+=v(l/t);455<l;y+=36)l=v(l/35);return v(y+36*l/(l+38))}function A(l){var t=[],C=l.length,y=0,J=128,M=72,a,b;var c=l.lastIndexOf("-");0>c&&(c=0);for(a=0;a<c;++a)128<=l.charCodeAt(a)&&x("not-basic"),t.push(l.charCodeAt(a));for(c=0<c?c+1:0;c<C;){a=y;var e=1;for(b=36;;b+=36){c>=C&&x("invalid-input");var f=l.charCodeAt(c++);f=10>f-48?f-22:26>f-65?f-65:26>f-97?f-97:36;
|
||||
(36<=f||f>v((2147483647-y)/e))&&x("overflow");y+=f*e;var n=b<=M?1:b>=M+26?26:b-M;if(f<n)break;f=36-n;e>v(2147483647/f)&&x("overflow");e*=f}e=t.length+1;M=E(y-a,e,0==a);v(y/e)>2147483647-J&&x("overflow");J+=v(y/e);y%=e;t.splice(y++,0,J)}return q(t)}function h(l){var t,C,y,J=[];l=d(l);var M=l.length;var a=128;var b=0;var c=72;for(y=0;y<M;++y){var e=l[y];128>e&&J.push(g(e))}for((t=C=J.length)&&J.push("-");t<M;){var f=2147483647;for(y=0;y<M;++y)e=l[y],e>=a&&e<f&&(f=e);var n=t+1;f-a>v((2147483647-b)/n)&&
|
||||
x("overflow");b+=(f-a)*n;a=f;for(y=0;y<M;++y)if(e=l[y],e<a&&2147483647<++b&&x("overflow"),e==a){var z=b;for(f=36;;f+=36){e=f<=c?1:f>=c+26?26:f-c;if(z<e)break;var I=z-e;z=36-e;var L=J;e+=I%z;L.push.call(L,g(e+22+75*(26>e)-0));z=v(I/z)}J.push(g(z+22+75*(26>z)-0));c=E(b,n,t==C);b=0;++t}++b;++a}return J.join("")}var p="object"==typeof exports&&exports&&!exports.nodeType&&exports,D="object"==typeof module&&module&&!module.nodeType&&module,u="object"==typeof global&&global;if(u.global===u||u.window===u||
|
||||
u.self===u)r=u;var K=/^xn--/,F=/[^\x20-\x7E]/,w=/[\x2E\u3002\uFF0E\uFF61]/g,H={overflow:"Overflow: input needs wider integers to process","not-basic":"Illegal input >= 0x80 (not a basic code point)","invalid-input":"Invalid input"},v=Math.floor,g=String.fromCharCode,B;var G={version:"1.3.2",ucs2:{decode:d,encode:q},decode:A,encode:h,toASCII:function(l){return m(l,function(t){return F.test(t)?"xn--"+h(t):t})},toUnicode:function(l){return m(l,function(t){return K.test(t)?A(t.slice(4).toLowerCase()):
|
||||
t})}};if("function"==typeof define&&"object"==typeof define.amd&&define.amd)define("punycode",function(){return G});else if(p&&D)if(module.exports==p)D.exports=G;else for(B in G)G.hasOwnProperty(B)&&(p[B]=G[B]);else r.punycode=G})(this);
|
||||
(function(r,x){"object"===typeof module&&module.exports?module.exports=x():"function"===typeof define&&define.amd?define(x):r.SecondLevelDomains=x(r)})(this,function(r){var x=r&&r.SecondLevelDomains,k={list:{ac:" com gov mil net org ",ae:" ac co gov mil name net org pro sch ",af:" com edu gov net org ",al:" com edu gov mil net org ",ao:" co ed gv it og pb ",ar:" com edu gob gov int mil net org tur ",at:" ac co gv or ",au:" asn com csiro edu gov id net org ",ba:" co com edu gov mil net org rs unbi unmo unsa untz unze ",
|
||||
bb:" biz co com edu gov info net org store tv ",bh:" biz cc com edu gov info net org ",bn:" com edu gov net org ",bo:" com edu gob gov int mil net org tv ",br:" adm adv agr am arq art ato b bio blog bmd cim cng cnt com coop ecn edu eng esp etc eti far flog fm fnd fot fst g12 ggf gov imb ind inf jor jus lel mat med mil mus net nom not ntr odo org ppg pro psc psi qsl rec slg srv tmp trd tur tv vet vlog wiki zlg ",bs:" com edu gov net org ",bz:" du et om ov rg ",ca:" ab bc mb nb nf nl ns nt nu on pe qc sk yk ",
|
||||
ck:" biz co edu gen gov info net org ",cn:" ac ah bj com cq edu fj gd gov gs gx gz ha hb he hi hl hn jl js jx ln mil net nm nx org qh sc sd sh sn sx tj tw xj xz yn zj ",co:" com edu gov mil net nom org ",cr:" ac c co ed fi go or sa ",cy:" ac biz com ekloges gov ltd name net org parliament press pro tm ","do":" art com edu gob gov mil net org sld web ",dz:" art asso com edu gov net org pol ",ec:" com edu fin gov info med mil net org pro ",eg:" com edu eun gov mil name net org sci ",er:" com edu gov ind mil net org rochest w ",
|
||||
es:" com edu gob nom org ",et:" biz com edu gov info name net org ",fj:" ac biz com info mil name net org pro ",fk:" ac co gov net nom org ",fr:" asso com f gouv nom prd presse tm ",gg:" co net org ",gh:" com edu gov mil org ",gn:" ac com gov net org ",gr:" com edu gov mil net org ",gt:" com edu gob ind mil net org ",gu:" com edu gov net org ",hk:" com edu gov idv net org ",hu:" 2000 agrar bolt casino city co erotica erotika film forum games hotel info ingatlan jogasz konyvelo lakas media news org priv reklam sex shop sport suli szex tm tozsde utazas video ",
|
||||
id:" ac co go mil net or sch web ",il:" ac co gov idf k12 muni net org ","in":" ac co edu ernet firm gen gov i ind mil net nic org res ",iq:" com edu gov i mil net org ",ir:" ac co dnssec gov i id net org sch ",it:" edu gov ",je:" co net org ",jo:" com edu gov mil name net org sch ",jp:" ac ad co ed go gr lg ne or ",ke:" ac co go info me mobi ne or sc ",kh:" com edu gov mil net org per ",ki:" biz com de edu gov info mob net org tel ",km:" asso com coop edu gouv k medecin mil nom notaires pharmaciens presse tm veterinaire ",
|
||||
kn:" edu gov net org ",kr:" ac busan chungbuk chungnam co daegu daejeon es gangwon go gwangju gyeongbuk gyeonggi gyeongnam hs incheon jeju jeonbuk jeonnam k kg mil ms ne or pe re sc seoul ulsan ",kw:" com edu gov net org ",ky:" com edu gov net org ",kz:" com edu gov mil net org ",lb:" com edu gov net org ",lk:" assn com edu gov grp hotel int ltd net ngo org sch soc web ",lr:" com edu gov net org ",lv:" asn com conf edu gov id mil net org ",ly:" com edu gov id med net org plc sch ",ma:" ac co gov m net org press ",
|
||||
mc:" asso tm ",me:" ac co edu gov its net org priv ",mg:" com edu gov mil nom org prd tm ",mk:" com edu gov inf name net org pro ",ml:" com edu gov net org presse ",mn:" edu gov org ",mo:" com edu gov net org ",mt:" com edu gov net org ",mv:" aero biz com coop edu gov info int mil museum name net org pro ",mw:" ac co com coop edu gov int museum net org ",mx:" com edu gob net org ",my:" com edu gov mil name net org sch ",nf:" arts com firm info net other per rec store web ",ng:" biz com edu gov mil mobi name net org sch ",
|
||||
ni:" ac co com edu gob mil net nom org ",np:" com edu gov mil net org ",nr:" biz com edu gov info net org ",om:" ac biz co com edu gov med mil museum net org pro sch ",pe:" com edu gob mil net nom org sld ",ph:" com edu gov i mil net ngo org ",pk:" biz com edu fam gob gok gon gop gos gov net org web ",pl:" art bialystok biz com edu gda gdansk gorzow gov info katowice krakow lodz lublin mil net ngo olsztyn org poznan pwr radom slupsk szczecin torun warszawa waw wroc wroclaw zgora ",pr:" ac biz com edu est gov info isla name net org pro prof ",
|
||||
ps:" com edu gov net org plo sec ",pw:" belau co ed go ne or ",ro:" arts com firm info nom nt org rec store tm www ",rs:" ac co edu gov in org ",sb:" com edu gov net org ",sc:" com edu gov net org ",sh:" co com edu gov net nom org ",sl:" com edu gov net org ",st:" co com consulado edu embaixada gov mil net org principe saotome store ",sv:" com edu gob org red ",sz:" ac co org ",tr:" av bbs bel biz com dr edu gen gov info k12 name net org pol tel tsk tv web ",tt:" aero biz cat co com coop edu gov info int jobs mil mobi museum name net org pro tel travel ",
|
||||
tw:" club com ebiz edu game gov idv mil net org ",mu:" ac co com gov net or org ",mz:" ac co edu gov org ",na:" co com ",nz:" ac co cri geek gen govt health iwi maori mil net org parliament school ",pa:" abo ac com edu gob ing med net nom org sld ",pt:" com edu gov int net nome org publ ",py:" com edu gov mil net org ",qa:" com edu gov mil net org ",re:" asso com nom ",ru:" ac adygeya altai amur arkhangelsk astrakhan bashkiria belgorod bir bryansk buryatia cbg chel chelyabinsk chita chukotka chuvashia com dagestan e-burg edu gov grozny int irkutsk ivanovo izhevsk jar joshkar-ola kalmykia kaluga kamchatka karelia kazan kchr kemerovo khabarovsk khakassia khv kirov koenig komi kostroma kranoyarsk kuban kurgan kursk lipetsk magadan mari mari-el marine mil mordovia mosreg msk murmansk nalchik net nnov nov novosibirsk nsk omsk orenburg org oryol penza perm pp pskov ptz rnd ryazan sakhalin samara saratov simbirsk smolensk spb stavropol stv surgut tambov tatarstan tom tomsk tsaritsyn tsk tula tuva tver tyumen udm udmurtia ulan-ude vladikavkaz vladimir vladivostok volgograd vologda voronezh vrn vyatka yakutia yamal yekaterinburg yuzhno-sakhalinsk ",
|
||||
rw:" ac co com edu gouv gov int mil net ",sa:" com edu gov med net org pub sch ",sd:" com edu gov info med net org tv ",se:" a ac b bd c d e f g h i k l m n o org p parti pp press r s t tm u w x y z ",sg:" com edu gov idn net org per ",sn:" art com edu gouv org perso univ ",sy:" com edu gov mil net news org ",th:" ac co go in mi net or ",tj:" ac biz co com edu go gov info int mil name net nic org test web ",tn:" agrinet com defense edunet ens fin gov ind info intl mincom nat net org perso rnrt rns rnu tourism ",
|
||||
tz:" ac co go ne or ",ua:" biz cherkassy chernigov chernovtsy ck cn co com crimea cv dn dnepropetrovsk donetsk dp edu gov if in ivano-frankivsk kh kharkov kherson khmelnitskiy kiev kirovograd km kr ks kv lg lugansk lutsk lviv me mk net nikolaev od odessa org pl poltava pp rovno rv sebastopol sumy te ternopil uzhgorod vinnica vn zaporizhzhe zhitomir zp zt ",ug:" ac co go ne or org sc ",uk:" ac bl british-library co cym gov govt icnet jet lea ltd me mil mod national-library-scotland nel net nhs nic nls org orgn parliament plc police sch scot soc ",
|
||||
us:" dni fed isa kids nsn ",uy:" com edu gub mil net org ",ve:" co com edu gob info mil net org web ",vi:" co com k12 net org ",vn:" ac biz com edu gov health info int name net org pro ",ye:" co com gov ltd me net org plc ",yu:" ac co edu gov org ",za:" ac agric alt bourse city co cybernet db edu gov grondar iaccess imt inca landesign law mil net ngo nis nom olivetti org pix school tm web ",zm:" ac co com edu gov net org sch ",com:"ar br cn de eu gb gr hu jpn kr no qc ru sa se uk us uy za ",net:"gb jp se uk ",
|
||||
org:"ae",de:"com "},has:function(m){var d=m.lastIndexOf(".");if(0>=d||d>=m.length-1)return!1;var q=m.lastIndexOf(".",d-1);if(0>=q||q>=d-1)return!1;var E=k.list[m.slice(d+1)];return E?0<=E.indexOf(" "+m.slice(q+1,d)+" "):!1},is:function(m){var d=m.lastIndexOf(".");if(0>=d||d>=m.length-1||0<=m.lastIndexOf(".",d-1))return!1;var q=k.list[m.slice(d+1)];return q?0<=q.indexOf(" "+m.slice(0,d)+" "):!1},get:function(m){var d=m.lastIndexOf(".");if(0>=d||d>=m.length-1)return null;var q=m.lastIndexOf(".",d-1);
|
||||
if(0>=q||q>=d-1)return null;var E=k.list[m.slice(d+1)];return!E||0>E.indexOf(" "+m.slice(q+1,d)+" ")?null:m.slice(q+1)},noConflict:function(){r.SecondLevelDomains===this&&(r.SecondLevelDomains=x);return this}};return k});
|
||||
(function(r,x){"object"===typeof module&&module.exports?module.exports=x(require("./punycode"),require("./IPv6"),require("./SecondLevelDomains")):"function"===typeof define&&define.amd?define(["./punycode","./IPv6","./SecondLevelDomains"],x):r.URI=x(r.punycode,r.IPv6,r.SecondLevelDomains,r)})(this,function(r,x,k,m){function d(a,b){var c=1<=arguments.length,e=2<=arguments.length;if(!(this instanceof d))return c?e?new d(a,b):new d(a):new d;if(void 0===a){if(c)throw new TypeError("undefined is not a valid argument for URI");
|
||||
a="undefined"!==typeof location?location.href+"":""}if(null===a&&c)throw new TypeError("null is not a valid argument for URI");this.href(a);return void 0!==b?this.absoluteTo(b):this}function q(a){return a.replace(/([.*+?^=!:${}()|[\]\/\\])/g,"\\$1")}function E(a){return void 0===a?"Undefined":String(Object.prototype.toString.call(a)).slice(8,-1)}function A(a){return"Array"===E(a)}function h(a,b){var c={},e;if("RegExp"===E(b))c=null;else if(A(b)){var f=0;for(e=b.length;f<e;f++)c[b[f]]=!0}else c[b]=
|
||||
!0;f=0;for(e=a.length;f<e;f++)if(c&&void 0!==c[a[f]]||!c&&b.test(a[f]))a.splice(f,1),e--,f--;return a}function p(a,b){var c;if(A(b)){var e=0;for(c=b.length;e<c;e++)if(!p(a,b[e]))return!1;return!0}var f=E(b);e=0;for(c=a.length;e<c;e++)if("RegExp"===f){if("string"===typeof a[e]&&a[e].match(b))return!0}else if(a[e]===b)return!0;return!1}function D(a,b){if(!A(a)||!A(b)||a.length!==b.length)return!1;a.sort();b.sort();for(var c=0,e=a.length;c<e;c++)if(a[c]!==b[c])return!1;return!0}function u(a){return a.replace(/^\/+|\/+$/g,
|
||||
"")}function K(a){return escape(a)}function F(a){return encodeURIComponent(a).replace(/[!'()*]/g,K).replace(/\*/g,"%2A")}function w(a){return function(b,c){if(void 0===b)return this._parts[a]||"";this._parts[a]=b||null;this.build(!c);return this}}function H(a,b){return function(c,e){if(void 0===c)return this._parts[a]||"";null!==c&&(c+="",c.charAt(0)===b&&(c=c.substring(1)));this._parts[a]=c;this.build(!e);return this}}var v=m&&m.URI;d.version="1.19.5";var g=d.prototype,B=Object.prototype.hasOwnProperty;
|
||||
'use strict';(function(r,x){"object"===typeof module&&module.exports?module.exports=x():"function"===typeof define&&define.amd?define(x):r.IPv6=x(r)})(this,function(r){var x=r&&r.IPv6;return{best:function(k){k=k.toLowerCase().split(":");var m=k.length,d=8;""===k[0]&&""===k[1]&&""===k[2]?(k.shift(),k.shift()):""===k[0]&&""===k[1]?k.shift():""===k[m-1]&&""===k[m-2]&&k.pop();m=k.length;-1!==k[m-1].indexOf(".")&&(d=7);var q;for(q=0;q<m&&""!==k[q];q++);if(q<d)for(k.splice(q,1,"0000");k.length<d;)k.splice(q,
|
||||
0,"0000");for(q=0;q<d;q++){m=k[q].split("");for(var B=0;3>B;B++)if("0"===m[0]&&1<m.length)m.splice(0,1);else break;k[q]=m.join("")}m=-1;var z=B=0,h=-1,p=!1;for(q=0;q<d;q++)p?"0"===k[q]?z+=1:(p=!1,z>B&&(m=h,B=z)):"0"===k[q]&&(p=!0,h=q,z=1);z>B&&(m=h,B=z);1<B&&k.splice(m,B,"");m=k.length;d="";""===k[0]&&(d=":");for(q=0;q<m;q++){d+=k[q];if(q===m-1)break;d+=":"}""===k[m-1]&&(d+=":");return d},noConflict:function(){r.IPv6===this&&(r.IPv6=x);return this}}});
|
||||
(function(r){function x(l){throw new RangeError(G[l]);}function k(l,t){for(var H=l.length,y=[];H--;)y[H]=t(l[H]);return y}function m(l,t){var H=l.split("@"),y="";1<H.length&&(y=H[0]+"@",l=H[1]);l=l.replace(w,".");l=l.split(".");t=k(l,t).join(".");return y+t}function d(l){for(var t=[],H=0,y=l.length,I,M;H<y;)I=l.charCodeAt(H++),55296<=I&&56319>=I&&H<y?(M=l.charCodeAt(H++),56320==(M&64512)?t.push(((I&1023)<<10)+(M&1023)+65536):(t.push(I),H--)):t.push(I);return t}function q(l){return k(l,function(t){var H=
|
||||
"";65535<t&&(t-=65536,H+=g(t>>>10&1023|55296),t=56320|t&1023);return H+=g(t)}).join("")}function B(l,t,H){var y=0;l=H?v(l/700):l>>1;for(l+=v(l/t);455<l;y+=36)l=v(l/35);return v(y+36*l/(l+38))}function z(l){var t=[],H=l.length,y=0,I=128,M=72,a,b;var c=l.lastIndexOf("-");0>c&&(c=0);for(a=0;a<c;++a)128<=l.charCodeAt(a)&&x("not-basic"),t.push(l.charCodeAt(a));for(c=0<c?c+1:0;c<H;){a=y;var e=1;for(b=36;;b+=36){c>=H&&x("invalid-input");var f=l.charCodeAt(c++);f=10>f-48?f-22:26>f-65?f-65:26>f-97?f-97:36;
|
||||
(36<=f||f>v((2147483647-y)/e))&&x("overflow");y+=f*e;var n=b<=M?1:b>=M+26?26:b-M;if(f<n)break;f=36-n;e>v(2147483647/f)&&x("overflow");e*=f}e=t.length+1;M=B(y-a,e,0==a);v(y/e)>2147483647-I&&x("overflow");I+=v(y/e);y%=e;t.splice(y++,0,I)}return q(t)}function h(l){var t,H,y,I=[];l=d(l);var M=l.length;var a=128;var b=0;var c=72;for(y=0;y<M;++y){var e=l[y];128>e&&I.push(g(e))}for((t=H=I.length)&&I.push("-");t<M;){var f=2147483647;for(y=0;y<M;++y)e=l[y],e>=a&&e<f&&(f=e);var n=t+1;f-a>v((2147483647-b)/n)&&
|
||||
x("overflow");b+=(f-a)*n;a=f;for(y=0;y<M;++y)if(e=l[y],e<a&&2147483647<++b&&x("overflow"),e==a){var E=b;for(f=36;;f+=36){e=f<=c?1:f>=c+26?26:f-c;if(E<e)break;var K=E-e;E=36-e;var L=I;e+=K%E;L.push.call(L,g(e+22+75*(26>e)-0));E=v(K/E)}I.push(g(E+22+75*(26>E)-0));c=B(b,n,t==H);b=0;++t}++b;++a}return I.join("")}var p="object"==typeof exports&&exports&&!exports.nodeType&&exports,F="object"==typeof module&&module&&!module.nodeType&&module,u="object"==typeof global&&global;if(u.global===u||u.window===u||
|
||||
u.self===u)r=u;var J=/^xn--/,C=/[^\x20-\x7E]/,w=/[\x2E\u3002\uFF0E\uFF61]/g,G={overflow:"Overflow: input needs wider integers to process","not-basic":"Illegal input >= 0x80 (not a basic code point)","invalid-input":"Invalid input"},v=Math.floor,g=String.fromCharCode,A;var D={version:"1.3.2",ucs2:{decode:d,encode:q},decode:z,encode:h,toASCII:function(l){return m(l,function(t){return C.test(t)?"xn--"+h(t):t})},toUnicode:function(l){return m(l,function(t){return J.test(t)?z(t.slice(4).toLowerCase()):
|
||||
t})}};if("function"==typeof define&&"object"==typeof define.amd&&define.amd)define("punycode",function(){return D});else if(p&&F)if(module.exports==p)F.exports=D;else for(A in D)D.hasOwnProperty(A)&&(p[A]=D[A]);else r.punycode=D})(this);
|
||||
(function(r,x){"object"===typeof module&&module.exports?module.exports=x():"function"===typeof define&&define.amd?define(x):r.SecondLevelDomains=x(r)})(this,function(r){var x=r&&r.SecondLevelDomains,k={list:{ac:" com gov mil net org ",ae:" ac co gov mil name net org pro sch ",af:" com edu gov net org ",al:" com edu gov mil net org ",ao:" co ed gv it og pb ",ar:" com edu gob gov int mil net org tur ",at:" ac co gv or ",au:" asn com csiro edu gov id net org ",ba:" co com edu gov mil net org rs unbi unmo unsa untz unze ",
|
||||
bb:" biz co com edu gov info net org store tv ",bh:" biz cc com edu gov info net org ",bn:" com edu gov net org ",bo:" com edu gob gov int mil net org tv ",br:" adm adv agr am arq art ato b bio blog bmd cim cng cnt com coop ecn edu eng esp etc eti far flog fm fnd fot fst g12 ggf gov imb ind inf jor jus lel mat med mil mus net nom not ntr odo org ppg pro psc psi qsl rec slg srv tmp trd tur tv vet vlog wiki zlg ",bs:" com edu gov net org ",bz:" du et om ov rg ",ca:" ab bc mb nb nf nl ns nt nu on pe qc sk yk ",
|
||||
ck:" biz co edu gen gov info net org ",cn:" ac ah bj com cq edu fj gd gov gs gx gz ha hb he hi hl hn jl js jx ln mil net nm nx org qh sc sd sh sn sx tj tw xj xz yn zj ",co:" com edu gov mil net nom org ",cr:" ac c co ed fi go or sa ",cy:" ac biz com ekloges gov ltd name net org parliament press pro tm ","do":" art com edu gob gov mil net org sld web ",dz:" art asso com edu gov net org pol ",ec:" com edu fin gov info med mil net org pro ",eg:" com edu eun gov mil name net org sci ",er:" com edu gov ind mil net org rochest w ",
|
||||
es:" com edu gob nom org ",et:" biz com edu gov info name net org ",fj:" ac biz com info mil name net org pro ",fk:" ac co gov net nom org ",fr:" asso com f gouv nom prd presse tm ",gg:" co net org ",gh:" com edu gov mil org ",gn:" ac com gov net org ",gr:" com edu gov mil net org ",gt:" com edu gob ind mil net org ",gu:" com edu gov net org ",hk:" com edu gov idv net org ",hu:" 2000 agrar bolt casino city co erotica erotika film forum games hotel info ingatlan jogasz konyvelo lakas media news org priv reklam sex shop sport suli szex tm tozsde utazas video ",
|
||||
id:" ac co go mil net or sch web ",il:" ac co gov idf k12 muni net org ","in":" ac co edu ernet firm gen gov i ind mil net nic org res ",iq:" com edu gov i mil net org ",ir:" ac co dnssec gov i id net org sch ",it:" edu gov ",je:" co net org ",jo:" com edu gov mil name net org sch ",jp:" ac ad co ed go gr lg ne or ",ke:" ac co go info me mobi ne or sc ",kh:" com edu gov mil net org per ",ki:" biz com de edu gov info mob net org tel ",km:" asso com coop edu gouv k medecin mil nom notaires pharmaciens presse tm veterinaire ",
|
||||
kn:" edu gov net org ",kr:" ac busan chungbuk chungnam co daegu daejeon es gangwon go gwangju gyeongbuk gyeonggi gyeongnam hs incheon jeju jeonbuk jeonnam k kg mil ms ne or pe re sc seoul ulsan ",kw:" com edu gov net org ",ky:" com edu gov net org ",kz:" com edu gov mil net org ",lb:" com edu gov net org ",lk:" assn com edu gov grp hotel int ltd net ngo org sch soc web ",lr:" com edu gov net org ",lv:" asn com conf edu gov id mil net org ",ly:" com edu gov id med net org plc sch ",ma:" ac co gov m net org press ",
|
||||
mc:" asso tm ",me:" ac co edu gov its net org priv ",mg:" com edu gov mil nom org prd tm ",mk:" com edu gov inf name net org pro ",ml:" com edu gov net org presse ",mn:" edu gov org ",mo:" com edu gov net org ",mt:" com edu gov net org ",mv:" aero biz com coop edu gov info int mil museum name net org pro ",mw:" ac co com coop edu gov int museum net org ",mx:" com edu gob net org ",my:" com edu gov mil name net org sch ",nf:" arts com firm info net other per rec store web ",ng:" biz com edu gov mil mobi name net org sch ",
|
||||
ni:" ac co com edu gob mil net nom org ",np:" com edu gov mil net org ",nr:" biz com edu gov info net org ",om:" ac biz co com edu gov med mil museum net org pro sch ",pe:" com edu gob mil net nom org sld ",ph:" com edu gov i mil net ngo org ",pk:" biz com edu fam gob gok gon gop gos gov net org web ",pl:" art bialystok biz com edu gda gdansk gorzow gov info katowice krakow lodz lublin mil net ngo olsztyn org poznan pwr radom slupsk szczecin torun warszawa waw wroc wroclaw zgora ",pr:" ac biz com edu est gov info isla name net org pro prof ",
|
||||
ps:" com edu gov net org plo sec ",pw:" belau co ed go ne or ",ro:" arts com firm info nom nt org rec store tm www ",rs:" ac co edu gov in org ",sb:" com edu gov net org ",sc:" com edu gov net org ",sh:" co com edu gov net nom org ",sl:" com edu gov net org ",st:" co com consulado edu embaixada gov mil net org principe saotome store ",sv:" com edu gob org red ",sz:" ac co org ",tr:" av bbs bel biz com dr edu gen gov info k12 name net org pol tel tsk tv web ",tt:" aero biz cat co com coop edu gov info int jobs mil mobi museum name net org pro tel travel ",
|
||||
tw:" club com ebiz edu game gov idv mil net org ",mu:" ac co com gov net or org ",mz:" ac co edu gov org ",na:" co com ",nz:" ac co cri geek gen govt health iwi maori mil net org parliament school ",pa:" abo ac com edu gob ing med net nom org sld ",pt:" com edu gov int net nome org publ ",py:" com edu gov mil net org ",qa:" com edu gov mil net org ",re:" asso com nom ",ru:" ac adygeya altai amur arkhangelsk astrakhan bashkiria belgorod bir bryansk buryatia cbg chel chelyabinsk chita chukotka chuvashia com dagestan e-burg edu gov grozny int irkutsk ivanovo izhevsk jar joshkar-ola kalmykia kaluga kamchatka karelia kazan kchr kemerovo khabarovsk khakassia khv kirov koenig komi kostroma kranoyarsk kuban kurgan kursk lipetsk magadan mari mari-el marine mil mordovia mosreg msk murmansk nalchik net nnov nov novosibirsk nsk omsk orenburg org oryol penza perm pp pskov ptz rnd ryazan sakhalin samara saratov simbirsk smolensk spb stavropol stv surgut tambov tatarstan tom tomsk tsaritsyn tsk tula tuva tver tyumen udm udmurtia ulan-ude vladikavkaz vladimir vladivostok volgograd vologda voronezh vrn vyatka yakutia yamal yekaterinburg yuzhno-sakhalinsk ",
|
||||
rw:" ac co com edu gouv gov int mil net ",sa:" com edu gov med net org pub sch ",sd:" com edu gov info med net org tv ",se:" a ac b bd c d e f g h i k l m n o org p parti pp press r s t tm u w x y z ",sg:" com edu gov idn net org per ",sn:" art com edu gouv org perso univ ",sy:" com edu gov mil net news org ",th:" ac co go in mi net or ",tj:" ac biz co com edu go gov info int mil name net nic org test web ",tn:" agrinet com defense edunet ens fin gov ind info intl mincom nat net org perso rnrt rns rnu tourism ",
|
||||
tz:" ac co go ne or ",ua:" biz cherkassy chernigov chernovtsy ck cn co com crimea cv dn dnepropetrovsk donetsk dp edu gov if in ivano-frankivsk kh kharkov kherson khmelnitskiy kiev kirovograd km kr ks kv lg lugansk lutsk lviv me mk net nikolaev od odessa org pl poltava pp rovno rv sebastopol sumy te ternopil uzhgorod vinnica vn zaporizhzhe zhitomir zp zt ",ug:" ac co go ne or org sc ",uk:" ac bl british-library co cym gov govt icnet jet lea ltd me mil mod national-library-scotland nel net nhs nic nls org orgn parliament plc police sch scot soc ",
|
||||
us:" dni fed isa kids nsn ",uy:" com edu gub mil net org ",ve:" co com edu gob info mil net org web ",vi:" co com k12 net org ",vn:" ac biz com edu gov health info int name net org pro ",ye:" co com gov ltd me net org plc ",yu:" ac co edu gov org ",za:" ac agric alt bourse city co cybernet db edu gov grondar iaccess imt inca landesign law mil net ngo nis nom olivetti org pix school tm web ",zm:" ac co com edu gov net org sch ",com:"ar br cn de eu gb gr hu jpn kr no qc ru sa se uk us uy za ",net:"gb jp se uk ",
|
||||
org:"ae",de:"com "},has:function(m){var d=m.lastIndexOf(".");if(0>=d||d>=m.length-1)return!1;var q=m.lastIndexOf(".",d-1);if(0>=q||q>=d-1)return!1;var B=k.list[m.slice(d+1)];return B?0<=B.indexOf(" "+m.slice(q+1,d)+" "):!1},is:function(m){var d=m.lastIndexOf(".");if(0>=d||d>=m.length-1||0<=m.lastIndexOf(".",d-1))return!1;var q=k.list[m.slice(d+1)];return q?0<=q.indexOf(" "+m.slice(0,d)+" "):!1},get:function(m){var d=m.lastIndexOf(".");if(0>=d||d>=m.length-1)return null;var q=m.lastIndexOf(".",d-1);
|
||||
if(0>=q||q>=d-1)return null;var B=k.list[m.slice(d+1)];return!B||0>B.indexOf(" "+m.slice(q+1,d)+" ")?null:m.slice(q+1)},noConflict:function(){r.SecondLevelDomains===this&&(r.SecondLevelDomains=x);return this}};return k});
|
||||
(function(r,x){"object"===typeof module&&module.exports?module.exports=x(require("./punycode"),require("./IPv6"),require("./SecondLevelDomains")):"function"===typeof define&&define.amd?define(["./punycode","./IPv6","./SecondLevelDomains"],x):r.URI=x(r.punycode,r.IPv6,r.SecondLevelDomains,r)})(this,function(r,x,k,m){function d(a,b){var c=1<=arguments.length,e=2<=arguments.length;if(!(this instanceof d))return c?e?new d(a,b):new d(a):new d;if(void 0===a){if(c)throw new TypeError("undefined is not a valid argument for URI");
|
||||
a="undefined"!==typeof location?location.href+"":""}if(null===a&&c)throw new TypeError("null is not a valid argument for URI");this.href(a);return void 0!==b?this.absoluteTo(b):this}function q(a){return a.replace(/([.*+?^=!:${}()|[\]\/\\])/g,"\\$1")}function B(a){return void 0===a?"Undefined":String(Object.prototype.toString.call(a)).slice(8,-1)}function z(a){return"Array"===B(a)}function h(a,b){var c={},e;if("RegExp"===B(b))c=null;else if(z(b)){var f=0;for(e=b.length;f<e;f++)c[b[f]]=!0}else c[b]=
|
||||
!0;f=0;for(e=a.length;f<e;f++)if(c&&void 0!==c[a[f]]||!c&&b.test(a[f]))a.splice(f,1),e--,f--;return a}function p(a,b){var c;if(z(b)){var e=0;for(c=b.length;e<c;e++)if(!p(a,b[e]))return!1;return!0}var f=B(b);e=0;for(c=a.length;e<c;e++)if("RegExp"===f){if("string"===typeof a[e]&&a[e].match(b))return!0}else if(a[e]===b)return!0;return!1}function F(a,b){if(!z(a)||!z(b)||a.length!==b.length)return!1;a.sort();b.sort();for(var c=0,e=a.length;c<e;c++)if(a[c]!==b[c])return!1;return!0}function u(a){return a.replace(/^\/+|\/+$/g,
|
||||
"")}function J(a){return escape(a)}function C(a){return encodeURIComponent(a).replace(/[!'()*]/g,J).replace(/\*/g,"%2A")}function w(a){return function(b,c){if(void 0===b)return this._parts[a]||"";this._parts[a]=b||null;this.build(!c);return this}}function G(a,b){return function(c,e){if(void 0===c)return this._parts[a]||"";null!==c&&(c+="",c.charAt(0)===b&&(c=c.substring(1)));this._parts[a]=c;this.build(!e);return this}}var v=m&&m.URI;d.version="1.19.11";var g=d.prototype,A=Object.prototype.hasOwnProperty;
|
||||
d._parts=function(){return{protocol:null,username:null,password:null,hostname:null,urn:null,port:null,path:null,query:null,fragment:null,preventInvalidHostname:d.preventInvalidHostname,duplicateQueryParameters:d.duplicateQueryParameters,escapeQuerySpace:d.escapeQuerySpace}};d.preventInvalidHostname=!1;d.duplicateQueryParameters=!1;d.escapeQuerySpace=!0;d.protocol_expression=/^[a-z][a-z0-9.+-]*$/i;d.idn_expression=/[^a-z0-9\._-]/i;d.punycode_expression=/(xn--)/i;d.ip4_expression=/^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/;
|
||||
d.ip6_expression=/^\s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:)))(%.+)?\s*$/;
|
||||
d.find_uri_expression=/\b((?:[a-z][\w-]+:(?:\/{1,3}|[a-z0-9%])|www\d{0,3}[.]|[a-z0-9.\-]+[.][a-z]{2,4}\/)(?:[^\s()<>]+|\(([^\s()<>]+|(\([^\s()<>]+\)))*\))+(?:\(([^\s()<>]+|(\([^\s()<>]+\)))*\)|[^\s`!()\[\]{};:'".,<>?\u00ab\u00bb\u201c\u201d\u2018\u2019]))/ig;d.findUri={start:/\b(?:([a-z][a-z0-9.+-]*:\/\/)|www\.)/gi,end:/[\s\r\n]|$/,trim:/[`!()\[\]{};:'".,<>?\u00ab\u00bb\u201c\u201d\u201e\u2018\u2019]+$/,parens:/(\([^\)]*\)|\[[^\]]*\]|\{[^}]*\}|<[^>]*>)/g};d.defaultPorts={http:"80",https:"443",ftp:"21",
|
||||
gopher:"70",ws:"80",wss:"443"};d.hostProtocols=["http","https"];d.invalid_hostname_characters=/[^a-zA-Z0-9\.\-:_]/;d.domAttributes={a:"href",blockquote:"cite",link:"href",base:"href",script:"src",form:"action",img:"src",area:"href",iframe:"src",embed:"src",source:"src",track:"src",input:"src",audio:"src",video:"src"};d.getDomAttribute=function(a){if(a&&a.nodeName){var b=a.nodeName.toLowerCase();if("input"!==b||"image"===a.type)return d.domAttributes[b]}};d.encode=F;d.decode=decodeURIComponent;d.iso8859=
|
||||
function(){d.encode=escape;d.decode=unescape};d.unicode=function(){d.encode=F;d.decode=decodeURIComponent};d.characters={pathname:{encode:{expression:/%(24|26|2B|2C|3B|3D|3A|40)/ig,map:{"%24":"$","%26":"&","%2B":"+","%2C":",","%3B":";","%3D":"=","%3A":":","%40":"@"}},decode:{expression:/[\/\?#]/g,map:{"/":"%2F","?":"%3F","#":"%23"}}},reserved:{encode:{expression:/%(21|23|24|26|27|28|29|2A|2B|2C|2F|3A|3B|3D|3F|40|5B|5D)/ig,map:{"%3A":":","%2F":"/","%3F":"?","%23":"#","%5B":"[","%5D":"]","%40":"@",
|
||||
"%21":"!","%24":"$","%26":"&","%27":"'","%28":"(","%29":")","%2A":"*","%2B":"+","%2C":",","%3B":";","%3D":"="}}},urnpath:{encode:{expression:/%(21|24|27|28|29|2A|2B|2C|3B|3D|40)/ig,map:{"%21":"!","%24":"$","%27":"'","%28":"(","%29":")","%2A":"*","%2B":"+","%2C":",","%3B":";","%3D":"=","%40":"@"}},decode:{expression:/[\/\?#:]/g,map:{"/":"%2F","?":"%3F","#":"%23",":":"%3A"}}}};d.encodeQuery=function(a,b){var c=d.encode(a+"");void 0===b&&(b=d.escapeQuerySpace);return b?c.replace(/%20/g,"+"):c};d.decodeQuery=
|
||||
function(a,b){a+="";void 0===b&&(b=d.escapeQuerySpace);try{return d.decode(b?a.replace(/\+/g,"%20"):a)}catch(c){return a}};var G={encode:"encode",decode:"decode"},l,t=function(a,b){return function(c){try{return d[b](c+"").replace(d.characters[a][b].expression,function(e){return d.characters[a][b].map[e]})}catch(e){return c}}};for(l in G)d[l+"PathSegment"]=t("pathname",G[l]),d[l+"UrnPathSegment"]=t("urnpath",G[l]);G=function(a,b,c){return function(e){var f=c?function(I){return d[b](d[c](I))}:d[b];
|
||||
e=(e+"").split(a);for(var n=0,z=e.length;n<z;n++)e[n]=f(e[n]);return e.join(a)}};d.decodePath=G("/","decodePathSegment");d.decodeUrnPath=G(":","decodeUrnPathSegment");d.recodePath=G("/","encodePathSegment","decode");d.recodeUrnPath=G(":","encodeUrnPathSegment","decode");d.encodeReserved=t("reserved","encode");d.parse=function(a,b){b||(b={preventInvalidHostname:d.preventInvalidHostname});var c=a.indexOf("#");-1<c&&(b.fragment=a.substring(c+1)||null,a=a.substring(0,c));c=a.indexOf("?");-1<c&&(b.query=
|
||||
a.substring(c+1)||null,a=a.substring(0,c));"//"===a.substring(0,2)?(b.protocol=null,a=a.substring(2),a=d.parseAuthority(a,b)):(c=a.indexOf(":"),-1<c&&(b.protocol=a.substring(0,c)||null,b.protocol&&!b.protocol.match(d.protocol_expression)?b.protocol=void 0:"//"===a.substring(c+1,c+3)?(a=a.substring(c+3),a=d.parseAuthority(a,b)):(a=a.substring(c+1),b.urn=!0)));b.path=a;return b};d.parseHost=function(a,b){a||(a="");a=a.replace(/\\/g,"/");var c=a.indexOf("/");-1===c&&(c=a.length);if("["===a.charAt(0)){var e=
|
||||
a.indexOf("]");b.hostname=a.substring(1,e)||null;b.port=a.substring(e+2,c)||null;"/"===b.port&&(b.port=null)}else{var f=a.indexOf(":");e=a.indexOf("/");f=a.indexOf(":",f+1);-1!==f&&(-1===e||f<e)?(b.hostname=a.substring(0,c)||null,b.port=null):(e=a.substring(0,c).split(":"),b.hostname=e[0]||null,b.port=e[1]||null)}b.hostname&&"/"!==a.substring(c).charAt(0)&&(c++,a="/"+a);b.preventInvalidHostname&&d.ensureValidHostname(b.hostname,b.protocol);b.port&&d.ensureValidPort(b.port);return a.substring(c)||
|
||||
"/"};d.parseAuthority=function(a,b){a=d.parseUserinfo(a,b);return d.parseHost(a,b)};d.parseUserinfo=function(a,b){var c=a;-1!==a.indexOf("\\")&&(a=a.replace(/\\/g,"/"));var e=a.indexOf("/"),f=a.lastIndexOf("@",-1<e?e:a.length-1);-1<f&&(-1===e||f<e)?(e=a.substring(0,f).split(":"),b.username=e[0]?d.decode(e[0]):null,e.shift(),b.password=e[0]?d.decode(e.join(":")):null,a=c.substring(f+1)):(b.username=null,b.password=null);return a};d.parseQuery=function(a,b){if(!a)return{};a=a.replace(/&+/g,"&").replace(/^\?*&*|&+$/g,
|
||||
"");if(!a)return{};for(var c={},e=a.split("&"),f=e.length,n,z,I=0;I<f;I++)if(n=e[I].split("="),z=d.decodeQuery(n.shift(),b),n=n.length?d.decodeQuery(n.join("="),b):null,B.call(c,z)){if("string"===typeof c[z]||null===c[z])c[z]=[c[z]];c[z].push(n)}else c[z]=n;return c};d.build=function(a){var b="",c=!1;a.protocol&&(b+=a.protocol+":");a.urn||!b&&!a.hostname||(b+="//",c=!0);b+=d.buildAuthority(a)||"";"string"===typeof a.path&&("/"!==a.path.charAt(0)&&c&&(b+="/"),b+=a.path);"string"===typeof a.query&&
|
||||
a.query&&(b+="?"+a.query);"string"===typeof a.fragment&&a.fragment&&(b+="#"+a.fragment);return b};d.buildHost=function(a){var b="";if(a.hostname)b=d.ip6_expression.test(a.hostname)?b+("["+a.hostname+"]"):b+a.hostname;else return"";a.port&&(b+=":"+a.port);return b};d.buildAuthority=function(a){return d.buildUserinfo(a)+d.buildHost(a)};d.buildUserinfo=function(a){var b="";a.username&&(b+=d.encode(a.username));a.password&&(b+=":"+d.encode(a.password));b&&(b+="@");return b};d.buildQuery=function(a,b,
|
||||
c){var e="",f,n;for(f in a)if(B.call(a,f))if(A(a[f])){var z={};var I=0;for(n=a[f].length;I<n;I++)void 0!==a[f][I]&&void 0===z[a[f][I]+""]&&(e+="&"+d.buildQueryParameter(f,a[f][I],c),!0!==b&&(z[a[f][I]+""]=!0))}else void 0!==a[f]&&(e+="&"+d.buildQueryParameter(f,a[f],c));return e.substring(1)};d.buildQueryParameter=function(a,b,c){return d.encodeQuery(a,c)+(null!==b?"="+d.encodeQuery(b,c):"")};d.addQuery=function(a,b,c){if("object"===typeof b)for(var e in b)B.call(b,e)&&d.addQuery(a,e,b[e]);else if("string"===
|
||||
typeof b)void 0===a[b]?a[b]=c:("string"===typeof a[b]&&(a[b]=[a[b]]),A(c)||(c=[c]),a[b]=(a[b]||[]).concat(c));else throw new TypeError("URI.addQuery() accepts an object, string as the name parameter");};d.setQuery=function(a,b,c){if("object"===typeof b)for(var e in b)B.call(b,e)&&d.setQuery(a,e,b[e]);else if("string"===typeof b)a[b]=void 0===c?null:c;else throw new TypeError("URI.setQuery() accepts an object, string as the name parameter");};d.removeQuery=function(a,b,c){var e;if(A(b))for(c=0,e=b.length;c<
|
||||
e;c++)a[b[c]]=void 0;else if("RegExp"===E(b))for(e in a)b.test(e)&&(a[e]=void 0);else if("object"===typeof b)for(e in b)B.call(b,e)&&d.removeQuery(a,e,b[e]);else if("string"===typeof b)void 0!==c?"RegExp"===E(c)?!A(a[b])&&c.test(a[b])?a[b]=void 0:a[b]=h(a[b],c):a[b]!==String(c)||A(c)&&1!==c.length?A(a[b])&&(a[b]=h(a[b],c)):a[b]=void 0:a[b]=void 0;else throw new TypeError("URI.removeQuery() accepts an object, string, RegExp as the first parameter");};d.hasQuery=function(a,b,c,e){switch(E(b)){case "String":break;
|
||||
case "RegExp":for(var f in a)if(B.call(a,f)&&b.test(f)&&(void 0===c||d.hasQuery(a,f,c)))return!0;return!1;case "Object":for(var n in b)if(B.call(b,n)&&!d.hasQuery(a,n,b[n]))return!1;return!0;default:throw new TypeError("URI.hasQuery() accepts a string, regular expression or object as the name parameter");}switch(E(c)){case "Undefined":return b in a;case "Boolean":return a=!(A(a[b])?!a[b].length:!a[b]),c===a;case "Function":return!!c(a[b],b,a);case "Array":return A(a[b])?(e?p:D)(a[b],c):!1;case "RegExp":return A(a[b])?
|
||||
e?p(a[b],c):!1:!(!a[b]||!a[b].match(c));case "Number":c=String(c);case "String":return A(a[b])?e?p(a[b],c):!1:a[b]===c;default:throw new TypeError("URI.hasQuery() accepts undefined, boolean, string, number, RegExp, Function as the value parameter");}};d.joinPaths=function(){for(var a=[],b=[],c=0,e=0;e<arguments.length;e++){var f=new d(arguments[e]);a.push(f);f=f.segment();for(var n=0;n<f.length;n++)"string"===typeof f[n]&&b.push(f[n]),f[n]&&c++}if(!b.length||!c)return new d("");b=(new d("")).segment(b);
|
||||
""!==a[0].path()&&"/"!==a[0].path().slice(0,1)||b.path("/"+b.path());return b.normalize()};d.commonPath=function(a,b){var c=Math.min(a.length,b.length),e;for(e=0;e<c;e++)if(a.charAt(e)!==b.charAt(e)){e--;break}if(1>e)return a.charAt(0)===b.charAt(0)&&"/"===a.charAt(0)?"/":"";if("/"!==a.charAt(e)||"/"!==b.charAt(e))e=a.substring(0,e).lastIndexOf("/");return a.substring(0,e+1)};d.withinString=function(a,b,c){c||(c={});var e=c.start||d.findUri.start,f=c.end||d.findUri.end,n=c.trim||d.findUri.trim,z=
|
||||
c.parens||d.findUri.parens,I=/[a-z0-9-]=["']?$/i;for(e.lastIndex=0;;){var L=e.exec(a);if(!L)break;var P=L.index;if(c.ignoreHtml){var N=a.slice(Math.max(P-3,0),P);if(N&&I.test(N))continue}var O=P+a.slice(P).search(f);N=a.slice(P,O);for(O=-1;;){var Q=z.exec(N);if(!Q)break;O=Math.max(O,Q.index+Q[0].length)}N=-1<O?N.slice(0,O)+N.slice(O).replace(n,""):N.replace(n,"");N.length<=L[0].length||c.ignore&&c.ignore.test(N)||(O=P+N.length,L=b(N,P,O,a),void 0===L?e.lastIndex=O:(L=String(L),a=a.slice(0,P)+L+a.slice(O),
|
||||
e.lastIndex=P+L.length))}e.lastIndex=0;return a};d.ensureValidHostname=function(a,b){var c=!!a,e=!1;b&&(e=p(d.hostProtocols,b));if(e&&!c)throw new TypeError("Hostname cannot be empty, if protocol is "+b);if(a&&a.match(d.invalid_hostname_characters)){if(!r)throw new TypeError('Hostname "'+a+'" contains characters other than [A-Z0-9.-:_] and Punycode.js is not available');if(r.toASCII(a).match(d.invalid_hostname_characters))throw new TypeError('Hostname "'+a+'" contains characters other than [A-Z0-9.-:_]');
|
||||
}};d.ensureValidPort=function(a){if(a){var b=Number(a);if(!(/^[0-9]+$/.test(b)&&0<b&&65536>b))throw new TypeError('Port "'+a+'" is not a valid port');}};d.noConflict=function(a){if(a)return a={URI:this.noConflict()},m.URITemplate&&"function"===typeof m.URITemplate.noConflict&&(a.URITemplate=m.URITemplate.noConflict()),m.IPv6&&"function"===typeof m.IPv6.noConflict&&(a.IPv6=m.IPv6.noConflict()),m.SecondLevelDomains&&"function"===typeof m.SecondLevelDomains.noConflict&&(a.SecondLevelDomains=m.SecondLevelDomains.noConflict()),
|
||||
a;m.URI===this&&(m.URI=v);return this};g.build=function(a){if(!0===a)this._deferred_build=!0;else if(void 0===a||this._deferred_build)this._string=d.build(this._parts),this._deferred_build=!1;return this};g.clone=function(){return new d(this)};g.valueOf=g.toString=function(){return this.build(!1)._string};g.protocol=w("protocol");g.username=w("username");g.password=w("password");g.hostname=w("hostname");g.port=w("port");g.query=H("query","?");g.fragment=H("fragment","#");g.search=function(a,b){var c=
|
||||
this.query(a,b);return"string"===typeof c&&c.length?"?"+c:c};g.hash=function(a,b){var c=this.fragment(a,b);return"string"===typeof c&&c.length?"#"+c:c};g.pathname=function(a,b){if(void 0===a||!0===a){var c=this._parts.path||(this._parts.hostname?"/":"");return a?(this._parts.urn?d.decodeUrnPath:d.decodePath)(c):c}this._parts.path=this._parts.urn?a?d.recodeUrnPath(a):"":a?d.recodePath(a):"/";this.build(!b);return this};g.path=g.pathname;g.href=function(a,b){var c;if(void 0===a)return this.toString();
|
||||
this._string="";this._parts=d._parts();var e=a instanceof d,f="object"===typeof a&&(a.hostname||a.path||a.pathname);a.nodeName&&(f=d.getDomAttribute(a),a=a[f]||"",f=!1);!e&&f&&void 0!==a.pathname&&(a=a.toString());if("string"===typeof a||a instanceof String)this._parts=d.parse(String(a),this._parts);else if(e||f){e=e?a._parts:a;for(c in e)"query"!==c&&B.call(this._parts,c)&&(this._parts[c]=e[c]);e.query&&this.query(e.query,!1)}else throw new TypeError("invalid input");this.build(!b);return this};
|
||||
g.is=function(a){var b=!1,c=!1,e=!1,f=!1,n=!1,z=!1,I=!1,L=!this._parts.urn;this._parts.hostname&&(L=!1,c=d.ip4_expression.test(this._parts.hostname),e=d.ip6_expression.test(this._parts.hostname),b=c||e,n=(f=!b)&&k&&k.has(this._parts.hostname),z=f&&d.idn_expression.test(this._parts.hostname),I=f&&d.punycode_expression.test(this._parts.hostname));switch(a.toLowerCase()){case "relative":return L;case "absolute":return!L;case "domain":case "name":return f;case "sld":return n;case "ip":return b;case "ip4":case "ipv4":case "inet4":return c;
|
||||
case "ip6":case "ipv6":case "inet6":return e;case "idn":return z;case "url":return!this._parts.urn;case "urn":return!!this._parts.urn;case "punycode":return I}return null};var C=g.protocol,y=g.port,J=g.hostname;g.protocol=function(a,b){if(a&&(a=a.replace(/:(\/\/)?$/,""),!a.match(d.protocol_expression)))throw new TypeError('Protocol "'+a+"\" contains characters other than [A-Z0-9.+-] or doesn't start with [A-Z]");return C.call(this,a,b)};g.scheme=g.protocol;g.port=function(a,b){if(this._parts.urn)return void 0===
|
||||
a?"":this;void 0!==a&&(0===a&&(a=null),a&&(a+="",":"===a.charAt(0)&&(a=a.substring(1)),d.ensureValidPort(a)));return y.call(this,a,b)};g.hostname=function(a,b){if(this._parts.urn)return void 0===a?"":this;if(void 0!==a){var c={preventInvalidHostname:this._parts.preventInvalidHostname};if("/"!==d.parseHost(a,c))throw new TypeError('Hostname "'+a+'" contains characters other than [A-Z0-9.-]');a=c.hostname;this._parts.preventInvalidHostname&&d.ensureValidHostname(a,this._parts.protocol)}return J.call(this,
|
||||
a,b)};g.origin=function(a,b){if(this._parts.urn)return void 0===a?"":this;if(void 0===a){var c=this.protocol();return this.authority()?(c?c+"://":"")+this.authority():""}c=d(a);this.protocol(c.protocol()).authority(c.authority()).build(!b);return this};g.host=function(a,b){if(this._parts.urn)return void 0===a?"":this;if(void 0===a)return this._parts.hostname?d.buildHost(this._parts):"";if("/"!==d.parseHost(a,this._parts))throw new TypeError('Hostname "'+a+'" contains characters other than [A-Z0-9.-]');
|
||||
this.build(!b);return this};g.authority=function(a,b){if(this._parts.urn)return void 0===a?"":this;if(void 0===a)return this._parts.hostname?d.buildAuthority(this._parts):"";if("/"!==d.parseAuthority(a,this._parts))throw new TypeError('Hostname "'+a+'" contains characters other than [A-Z0-9.-]');this.build(!b);return this};g.userinfo=function(a,b){if(this._parts.urn)return void 0===a?"":this;if(void 0===a){var c=d.buildUserinfo(this._parts);return c?c.substring(0,c.length-1):c}"@"!==a[a.length-1]&&
|
||||
(a+="@");d.parseUserinfo(a,this._parts);this.build(!b);return this};g.resource=function(a,b){if(void 0===a)return this.path()+this.search()+this.hash();var c=d.parse(a);this._parts.path=c.path;this._parts.query=c.query;this._parts.fragment=c.fragment;this.build(!b);return this};g.subdomain=function(a,b){if(this._parts.urn)return void 0===a?"":this;if(void 0===a){if(!this._parts.hostname||this.is("IP"))return"";var c=this._parts.hostname.length-this.domain().length-1;return this._parts.hostname.substring(0,
|
||||
c)||""}c=this._parts.hostname.length-this.domain().length;c=this._parts.hostname.substring(0,c);c=new RegExp("^"+q(c));a&&"."!==a.charAt(a.length-1)&&(a+=".");if(-1!==a.indexOf(":"))throw new TypeError("Domains cannot contain colons");a&&d.ensureValidHostname(a,this._parts.protocol);this._parts.hostname=this._parts.hostname.replace(c,a);this.build(!b);return this};g.domain=function(a,b){if(this._parts.urn)return void 0===a?"":this;"boolean"===typeof a&&(b=a,a=void 0);if(void 0===a){if(!this._parts.hostname||
|
||||
this.is("IP"))return"";var c=this._parts.hostname.match(/\./g);if(c&&2>c.length)return this._parts.hostname;c=this._parts.hostname.length-this.tld(b).length-1;c=this._parts.hostname.lastIndexOf(".",c-1)+1;return this._parts.hostname.substring(c)||""}if(!a)throw new TypeError("cannot set domain empty");if(-1!==a.indexOf(":"))throw new TypeError("Domains cannot contain colons");d.ensureValidHostname(a,this._parts.protocol);!this._parts.hostname||this.is("IP")?this._parts.hostname=a:(c=new RegExp(q(this.domain())+
|
||||
"$"),this._parts.hostname=this._parts.hostname.replace(c,a));this.build(!b);return this};g.tld=function(a,b){if(this._parts.urn)return void 0===a?"":this;"boolean"===typeof a&&(b=a,a=void 0);if(void 0===a){if(!this._parts.hostname||this.is("IP"))return"";var c=this._parts.hostname.lastIndexOf(".");c=this._parts.hostname.substring(c+1);return!0!==b&&k&&k.list[c.toLowerCase()]?k.get(this._parts.hostname)||c:c}if(a)if(a.match(/[^a-zA-Z0-9-]/))if(k&&k.is(a))c=new RegExp(q(this.tld())+"$"),this._parts.hostname=
|
||||
this._parts.hostname.replace(c,a);else throw new TypeError('TLD "'+a+'" contains characters other than [A-Z0-9]');else{if(!this._parts.hostname||this.is("IP"))throw new ReferenceError("cannot set TLD on non-domain host");c=new RegExp(q(this.tld())+"$");this._parts.hostname=this._parts.hostname.replace(c,a)}else throw new TypeError("cannot set TLD empty");this.build(!b);return this};g.directory=function(a,b){if(this._parts.urn)return void 0===a?"":this;if(void 0===a||!0===a){if(!this._parts.path&&
|
||||
!this._parts.hostname)return"";if("/"===this._parts.path)return"/";var c=this._parts.path.length-this.filename().length-1;c=this._parts.path.substring(0,c)||(this._parts.hostname?"/":"");return a?d.decodePath(c):c}c=this._parts.path.length-this.filename().length;c=this._parts.path.substring(0,c);c=new RegExp("^"+q(c));this.is("relative")||(a||(a="/"),"/"!==a.charAt(0)&&(a="/"+a));a&&"/"!==a.charAt(a.length-1)&&(a+="/");a=d.recodePath(a);this._parts.path=this._parts.path.replace(c,a);this.build(!b);
|
||||
return this};g.filename=function(a,b){if(this._parts.urn)return void 0===a?"":this;if("string"!==typeof a){if(!this._parts.path||"/"===this._parts.path)return"";var c=this._parts.path.lastIndexOf("/");c=this._parts.path.substring(c+1);return a?d.decodePathSegment(c):c}c=!1;"/"===a.charAt(0)&&(a=a.substring(1));a.match(/\.?\//)&&(c=!0);var e=new RegExp(q(this.filename())+"$");a=d.recodePath(a);this._parts.path=this._parts.path.replace(e,a);c?this.normalizePath(b):this.build(!b);return this};g.suffix=
|
||||
function(a,b){if(this._parts.urn)return void 0===a?"":this;if(void 0===a||!0===a){if(!this._parts.path||"/"===this._parts.path)return"";var c=this.filename(),e=c.lastIndexOf(".");if(-1===e)return"";c=c.substring(e+1);c=/^[a-z0-9%]+$/i.test(c)?c:"";return a?d.decodePathSegment(c):c}"."===a.charAt(0)&&(a=a.substring(1));if(c=this.suffix())e=a?new RegExp(q(c)+"$"):new RegExp(q("."+c)+"$");else{if(!a)return this;this._parts.path+="."+d.recodePath(a)}e&&(a=d.recodePath(a),this._parts.path=this._parts.path.replace(e,
|
||||
a));this.build(!b);return this};g.segment=function(a,b,c){var e=this._parts.urn?":":"/",f=this.path(),n="/"===f.substring(0,1);f=f.split(e);void 0!==a&&"number"!==typeof a&&(c=b,b=a,a=void 0);if(void 0!==a&&"number"!==typeof a)throw Error('Bad segment "'+a+'", must be 0-based integer');n&&f.shift();0>a&&(a=Math.max(f.length+a,0));if(void 0===b)return void 0===a?f:f[a];if(null===a||void 0===f[a])if(A(b)){f=[];a=0;for(var z=b.length;a<z;a++)if(b[a].length||f.length&&f[f.length-1].length)f.length&&!f[f.length-
|
||||
1].length&&f.pop(),f.push(u(b[a]))}else{if(b||"string"===typeof b)b=u(b),""===f[f.length-1]?f[f.length-1]=b:f.push(b)}else b?f[a]=u(b):f.splice(a,1);n&&f.unshift("");return this.path(f.join(e),c)};g.segmentCoded=function(a,b,c){var e;"number"!==typeof a&&(c=b,b=a,a=void 0);if(void 0===b){a=this.segment(a,b,c);if(A(a)){var f=0;for(e=a.length;f<e;f++)a[f]=d.decode(a[f])}else a=void 0!==a?d.decode(a):void 0;return a}if(A(b))for(f=0,e=b.length;f<e;f++)b[f]=d.encode(b[f]);else b="string"===typeof b||b instanceof
|
||||
String?d.encode(b):b;return this.segment(a,b,c)};var M=g.query;g.query=function(a,b){if(!0===a)return d.parseQuery(this._parts.query,this._parts.escapeQuerySpace);if("function"===typeof a){var c=d.parseQuery(this._parts.query,this._parts.escapeQuerySpace),e=a.call(this,c);this._parts.query=d.buildQuery(e||c,this._parts.duplicateQueryParameters,this._parts.escapeQuerySpace);this.build(!b);return this}return void 0!==a&&"string"!==typeof a?(this._parts.query=d.buildQuery(a,this._parts.duplicateQueryParameters,
|
||||
this._parts.escapeQuerySpace),this.build(!b),this):M.call(this,a,b)};g.setQuery=function(a,b,c){var e=d.parseQuery(this._parts.query,this._parts.escapeQuerySpace);if("string"===typeof a||a instanceof String)e[a]=void 0!==b?b:null;else if("object"===typeof a)for(var f in a)B.call(a,f)&&(e[f]=a[f]);else throw new TypeError("URI.addQuery() accepts an object, string as the name parameter");this._parts.query=d.buildQuery(e,this._parts.duplicateQueryParameters,this._parts.escapeQuerySpace);"string"!==typeof a&&
|
||||
(c=b);this.build(!c);return this};g.addQuery=function(a,b,c){var e=d.parseQuery(this._parts.query,this._parts.escapeQuerySpace);d.addQuery(e,a,void 0===b?null:b);this._parts.query=d.buildQuery(e,this._parts.duplicateQueryParameters,this._parts.escapeQuerySpace);"string"!==typeof a&&(c=b);this.build(!c);return this};g.removeQuery=function(a,b,c){var e=d.parseQuery(this._parts.query,this._parts.escapeQuerySpace);d.removeQuery(e,a,b);this._parts.query=d.buildQuery(e,this._parts.duplicateQueryParameters,
|
||||
this._parts.escapeQuerySpace);"string"!==typeof a&&(c=b);this.build(!c);return this};g.hasQuery=function(a,b,c){var e=d.parseQuery(this._parts.query,this._parts.escapeQuerySpace);return d.hasQuery(e,a,b,c)};g.setSearch=g.setQuery;g.addSearch=g.addQuery;g.removeSearch=g.removeQuery;g.hasSearch=g.hasQuery;g.normalize=function(){return this._parts.urn?this.normalizeProtocol(!1).normalizePath(!1).normalizeQuery(!1).normalizeFragment(!1).build():this.normalizeProtocol(!1).normalizeHostname(!1).normalizePort(!1).normalizePath(!1).normalizeQuery(!1).normalizeFragment(!1).build()};
|
||||
g.normalizeProtocol=function(a){"string"===typeof this._parts.protocol&&(this._parts.protocol=this._parts.protocol.toLowerCase(),this.build(!a));return this};g.normalizeHostname=function(a){this._parts.hostname&&(this.is("IDN")&&r?this._parts.hostname=r.toASCII(this._parts.hostname):this.is("IPv6")&&x&&(this._parts.hostname=x.best(this._parts.hostname)),this._parts.hostname=this._parts.hostname.toLowerCase(),this.build(!a));return this};g.normalizePort=function(a){"string"===typeof this._parts.protocol&&
|
||||
this._parts.port===d.defaultPorts[this._parts.protocol]&&(this._parts.port=null,this.build(!a));return this};g.normalizePath=function(a){var b=this._parts.path;if(!b)return this;if(this._parts.urn)return this._parts.path=d.recodeUrnPath(this._parts.path),this.build(!a),this;if("/"===this._parts.path)return this;b=d.recodePath(b);var c="";if("/"!==b.charAt(0)){var e=!0;b="/"+b}if("/.."===b.slice(-3)||"/."===b.slice(-2))b+="/";b=b.replace(/(\/(\.\/)+)|(\/\.$)/g,"/").replace(/\/{2,}/g,"/");e&&(c=b.substring(1).match(/^(\.\.\/)+/)||
|
||||
"")&&(c=c[0]);for(;;){var f=b.search(/\/\.\.(\/|$)/);if(-1===f)break;else if(0===f){b=b.substring(3);continue}var n=b.substring(0,f).lastIndexOf("/");-1===n&&(n=f);b=b.substring(0,n)+b.substring(f+3)}e&&this.is("relative")&&(b=c+b.substring(1));this._parts.path=b;this.build(!a);return this};g.normalizePathname=g.normalizePath;g.normalizeQuery=function(a){"string"===typeof this._parts.query&&(this._parts.query.length?this.query(d.parseQuery(this._parts.query,this._parts.escapeQuerySpace)):this._parts.query=
|
||||
null,this.build(!a));return this};g.normalizeFragment=function(a){this._parts.fragment||(this._parts.fragment=null,this.build(!a));return this};g.normalizeSearch=g.normalizeQuery;g.normalizeHash=g.normalizeFragment;g.iso8859=function(){var a=d.encode,b=d.decode;d.encode=escape;d.decode=decodeURIComponent;try{this.normalize()}finally{d.encode=a,d.decode=b}return this};g.unicode=function(){var a=d.encode,b=d.decode;d.encode=F;d.decode=unescape;try{this.normalize()}finally{d.encode=a,d.decode=b}return this};
|
||||
g.readable=function(){var a=this.clone();a.username("").password("").normalize();var b="";a._parts.protocol&&(b+=a._parts.protocol+"://");a._parts.hostname&&(a.is("punycode")&&r?(b+=r.toUnicode(a._parts.hostname),a._parts.port&&(b+=":"+a._parts.port)):b+=a.host());a._parts.hostname&&a._parts.path&&"/"!==a._parts.path.charAt(0)&&(b+="/");b+=a.path(!0);if(a._parts.query){for(var c="",e=0,f=a._parts.query.split("&"),n=f.length;e<n;e++){var z=(f[e]||"").split("=");c+="&"+d.decodeQuery(z[0],this._parts.escapeQuerySpace).replace(/&/g,
|
||||
"%26");void 0!==z[1]&&(c+="="+d.decodeQuery(z[1],this._parts.escapeQuerySpace).replace(/&/g,"%26"))}b+="?"+c.substring(1)}return b+=d.decodeQuery(a.hash(),!0)};g.absoluteTo=function(a){var b=this.clone(),c=["protocol","username","password","hostname","port"],e,f;if(this._parts.urn)throw Error("URNs do not have any generally defined hierarchical components");a instanceof d||(a=new d(a));if(b._parts.protocol)return b;b._parts.protocol=a._parts.protocol;if(this._parts.hostname)return b;for(e=0;f=c[e];e++)b._parts[f]=
|
||||
a._parts[f];b._parts.path?(".."===b._parts.path.substring(-2)&&(b._parts.path+="/"),"/"!==b.path().charAt(0)&&(c=(c=a.directory())?c:0===a.path().indexOf("/")?"/":"",b._parts.path=(c?c+"/":"")+b._parts.path,b.normalizePath())):(b._parts.path=a._parts.path,b._parts.query||(b._parts.query=a._parts.query));b.build();return b};g.relativeTo=function(a){var b=this.clone().normalize();if(b._parts.urn)throw Error("URNs do not have any generally defined hierarchical components");a=(new d(a)).normalize();var c=
|
||||
b._parts;var e=a._parts;var f=b.path();a=a.path();if("/"!==f.charAt(0))throw Error("URI is already relative");if("/"!==a.charAt(0))throw Error("Cannot calculate a URI relative to another relative URI");c.protocol===e.protocol&&(c.protocol=null);if(c.username===e.username&&c.password===e.password&&null===c.protocol&&null===c.username&&null===c.password&&c.hostname===e.hostname&&c.port===e.port)c.hostname=null,c.port=null;else return b.build();if(f===a)return c.path="",b.build();f=d.commonPath(f,a);
|
||||
if(!f)return b.build();e=e.path.substring(f.length).replace(/[^\/]*$/,"").replace(/.*?\//g,"../");c.path=e+c.path.substring(f.length)||"./";return b.build()};g.equals=function(a){var b=this.clone(),c=new d(a);a={};var e;b.normalize();c.normalize();if(b.toString()===c.toString())return!0;var f=b.query();var n=c.query();b.query("");c.query("");if(b.toString()!==c.toString()||f.length!==n.length)return!1;b=d.parseQuery(f,this._parts.escapeQuerySpace);n=d.parseQuery(n,this._parts.escapeQuerySpace);for(e in b)if(B.call(b,
|
||||
e)){if(!A(b[e])){if(b[e]!==n[e])return!1}else if(!D(b[e],n[e]))return!1;a[e]=!0}for(e in n)if(B.call(n,e)&&!a[e])return!1;return!0};g.preventInvalidHostname=function(a){this._parts.preventInvalidHostname=!!a;return this};g.duplicateQueryParameters=function(a){this._parts.duplicateQueryParameters=!!a;return this};g.escapeQuerySpace=function(a){this._parts.escapeQuerySpace=!!a;return this};return d});
|
||||
(function(r,x){"object"===typeof module&&module.exports?module.exports=x(require("./URI")):"function"===typeof define&&define.amd?define(["./URI"],x):r.URITemplate=x(r.URI,r)})(this,function(r,x){function k(h){if(k._cache[h])return k._cache[h];if(!(this instanceof k))return new k(h);this.expression=h;k._cache[h]=this;return this}function m(h){this.data=h;this.cache={}}var d=x&&x.URITemplate,q=Object.prototype.hasOwnProperty,E=k.prototype,A={"":{prefix:"",separator:",",named:!1,empty_name_separator:!1,
|
||||
encode:"encode"},"+":{prefix:"",separator:",",named:!1,empty_name_separator:!1,encode:"encodeReserved"},"#":{prefix:"#",separator:",",named:!1,empty_name_separator:!1,encode:"encodeReserved"},".":{prefix:".",separator:".",named:!1,empty_name_separator:!1,encode:"encode"},"/":{prefix:"/",separator:"/",named:!1,empty_name_separator:!1,encode:"encode"},";":{prefix:";",separator:";",named:!0,empty_name_separator:!1,encode:"encode"},"?":{prefix:"?",separator:"&",named:!0,empty_name_separator:!0,encode:"encode"},
|
||||
"&":{prefix:"&",separator:"&",named:!0,empty_name_separator:!0,encode:"encode"}};k._cache={};k.EXPRESSION_PATTERN=/\{([^a-zA-Z0-9%_]?)([^\}]+)(\}|$)/g;k.VARIABLE_PATTERN=/^([^*:.](?:\.?[^*:.])*)((\*)|:(\d+))?$/;k.VARIABLE_NAME_PATTERN=/[^a-zA-Z0-9%_.]/;k.LITERAL_PATTERN=/[<>{}"`^| \\]/;k.expand=function(h,p,D){var u=A[h.operator],K=u.named?"Named":"Unnamed";h=h.variables;var F=[],w,H;for(H=0;w=h[H];H++){var v=p.get(w.name);if(0===v.type&&D&&D.strict)throw Error('Missing expansion value for variable "'+
|
||||
w.name+'"');if(v.val.length){if(1<v.type&&w.maxlength)throw Error('Invalid expression: Prefix modifier not applicable to variable "'+w.name+'"');F.push(k["expand"+K](v,u,w.explode,w.explode&&u.separator||",",w.maxlength,w.name))}else v.type&&F.push("")}return F.length?u.prefix+F.join(u.separator):""};k.expandNamed=function(h,p,D,u,K,F){var w="",H=p.encode;p=p.empty_name_separator;var v=!h[H].length,g=2===h.type?"":r[H](F),B;var G=0;for(B=h.val.length;G<B;G++){if(K){var l=r[H](h.val[G][1].substring(0,
|
||||
K));2===h.type&&(g=r[H](h.val[G][0].substring(0,K)))}else v?(l=r[H](h.val[G][1]),2===h.type?(g=r[H](h.val[G][0]),h[H].push([g,l])):h[H].push([void 0,l])):(l=h[H][G][1],2===h.type&&(g=h[H][G][0]));w&&(w+=u);D?w+=g+(p||l?"=":"")+l:(G||(w+=r[H](F)+(p||l?"=":"")),2===h.type&&(w+=g+","),w+=l)}return w};k.expandUnnamed=function(h,p,D,u,K){var F="",w=p.encode;p=p.empty_name_separator;var H=!h[w].length,v;var g=0;for(v=h.val.length;g<v;g++){if(K)var B=r[w](h.val[g][1].substring(0,K));else H?(B=r[w](h.val[g][1]),
|
||||
h[w].push([2===h.type?r[w](h.val[g][0]):void 0,B])):B=h[w][g][1];F&&(F+=u);if(2===h.type){var G=K?r[w](h.val[g][0].substring(0,K)):h[w][g][0];F+=G;F=D?F+(p||B?"=":""):F+","}F+=B}return F};k.noConflict=function(){x.URITemplate===k&&(x.URITemplate=d);return k};E.expand=function(h,p){var D="";this.parts&&this.parts.length||this.parse();h instanceof m||(h=new m(h));for(var u=0,K=this.parts.length;u<K;u++)D+="string"===typeof this.parts[u]?this.parts[u]:k.expand(this.parts[u],h,p);return D};E.parse=function(){var h=
|
||||
this.expression,p=k.EXPRESSION_PATTERN,D=k.VARIABLE_PATTERN,u=k.VARIABLE_NAME_PATTERN,K=k.LITERAL_PATTERN,F=[],w=0,H=function(t){if(t.match(K))throw Error('Invalid Literal "'+t+'"');return t};for(p.lastIndex=0;;){var v=p.exec(h);if(null===v){F.push(H(h.substring(w)));break}else F.push(H(h.substring(w,v.index))),w=v.index+v[0].length;if(!A[v[1]])throw Error('Unknown Operator "'+v[1]+'" in "'+v[0]+'"');if(!v[3])throw Error('Unclosed Expression "'+v[0]+'"');var g=v[2].split(",");for(var B=0,G=g.length;B<
|
||||
G;B++){var l=g[B].match(D);if(null===l)throw Error('Invalid Variable "'+g[B]+'" in "'+v[0]+'"');if(l[1].match(u))throw Error('Invalid Variable Name "'+l[1]+'" in "'+v[0]+'"');g[B]={name:l[1],explode:!!l[3],maxlength:l[4]&&parseInt(l[4],10)}}if(!g.length)throw Error('Expression Missing Variable(s) "'+v[0]+'"');F.push({expression:v[0],operator:v[1],variables:g})}F.length||F.push(H(h));this.parts=F;return this};m.prototype.get=function(h){var p=this.data,D={type:0,val:[],encode:[],encodeReserved:[]};
|
||||
if(void 0!==this.cache[h])return this.cache[h];this.cache[h]=D;p="[object Function]"===String(Object.prototype.toString.call(p))?p(h):"[object Function]"===String(Object.prototype.toString.call(p[h]))?p[h](h):p[h];if(void 0!==p&&null!==p)if("[object Array]"===String(Object.prototype.toString.call(p))){var u=0;for(h=p.length;u<h;u++)void 0!==p[u]&&null!==p[u]&&D.val.push([void 0,String(p[u])]);D.val.length&&(D.type=3)}else if("[object Object]"===String(Object.prototype.toString.call(p))){for(u in p)q.call(p,
|
||||
u)&&void 0!==p[u]&&null!==p[u]&&D.val.push([u,String(p[u])]);D.val.length&&(D.type=2)}else D.type=1,D.val.push([void 0,String(p)]);return D};r.expand=function(h,p){var D=(new k(h)).expand(p);return new r(D)};return k});
|
||||
d.find_uri_expression=/\b((?:[a-z][\w-]+:(?:\/{1,3}|[a-z0-9%])|www\d{0,3}[.]|[a-z0-9.\-]+[.][a-z]{2,4}\/)(?:[^\s()<>]+|\(([^\s()<>]+|(\([^\s()<>]+\)))*\))+(?:\(([^\s()<>]+|(\([^\s()<>]+\)))*\)|[^\s`!()\[\]{};:'".,<>?\u00ab\u00bb\u201c\u201d\u2018\u2019]))/ig;d.findUri={start:/\b(?:([a-z][a-z0-9.+-]*:\/\/)|www\.)/gi,end:/[\s\r\n]|$/,trim:/[`!()\[\]{};:'".,<>?\u00ab\u00bb\u201c\u201d\u201e\u2018\u2019]+$/,parens:/(\([^\)]*\)|\[[^\]]*\]|\{[^}]*\}|<[^>]*>)/g};d.leading_whitespace_expression=/^[\x00-\x20\u00a0\u1680\u2000-\u200a\u2028\u2029\u202f\u205f\u3000\ufeff]+/;
|
||||
d.ascii_tab_whitespace=/[\u0009\u000A\u000D]+/g;d.defaultPorts={http:"80",https:"443",ftp:"21",gopher:"70",ws:"80",wss:"443"};d.hostProtocols=["http","https"];d.invalid_hostname_characters=/[^a-zA-Z0-9\.\-:_]/;d.domAttributes={a:"href",blockquote:"cite",link:"href",base:"href",script:"src",form:"action",img:"src",area:"href",iframe:"src",embed:"src",source:"src",track:"src",input:"src",audio:"src",video:"src"};d.getDomAttribute=function(a){if(a&&a.nodeName){var b=a.nodeName.toLowerCase();if("input"!==
|
||||
b||"image"===a.type)return d.domAttributes[b]}};d.encode=C;d.decode=decodeURIComponent;d.iso8859=function(){d.encode=escape;d.decode=unescape};d.unicode=function(){d.encode=C;d.decode=decodeURIComponent};d.characters={pathname:{encode:{expression:/%(24|26|2B|2C|3B|3D|3A|40)/ig,map:{"%24":"$","%26":"&","%2B":"+","%2C":",","%3B":";","%3D":"=","%3A":":","%40":"@"}},decode:{expression:/[\/\?#]/g,map:{"/":"%2F","?":"%3F","#":"%23"}}},reserved:{encode:{expression:/%(21|23|24|26|27|28|29|2A|2B|2C|2F|3A|3B|3D|3F|40|5B|5D)/ig,
|
||||
map:{"%3A":":","%2F":"/","%3F":"?","%23":"#","%5B":"[","%5D":"]","%40":"@","%21":"!","%24":"$","%26":"&","%27":"'","%28":"(","%29":")","%2A":"*","%2B":"+","%2C":",","%3B":";","%3D":"="}}},urnpath:{encode:{expression:/%(21|24|27|28|29|2A|2B|2C|3B|3D|40)/ig,map:{"%21":"!","%24":"$","%27":"'","%28":"(","%29":")","%2A":"*","%2B":"+","%2C":",","%3B":";","%3D":"=","%40":"@"}},decode:{expression:/[\/\?#:]/g,map:{"/":"%2F","?":"%3F","#":"%23",":":"%3A"}}}};d.encodeQuery=function(a,b){a=d.encode(a+"");void 0===
|
||||
b&&(b=d.escapeQuerySpace);return b?a.replace(/%20/g,"+"):a};d.decodeQuery=function(a,b){a+="";void 0===b&&(b=d.escapeQuerySpace);try{return d.decode(b?a.replace(/\+/g,"%20"):a)}catch(c){return a}};var D={encode:"encode",decode:"decode"},l,t=function(a,b){return function(c){try{return d[b](c+"").replace(d.characters[a][b].expression,function(e){return d.characters[a][b].map[e]})}catch(e){return c}}};for(l in D)d[l+"PathSegment"]=t("pathname",D[l]),d[l+"UrnPathSegment"]=t("urnpath",D[l]);D=function(a,
|
||||
b,c){return function(e){var f=c?function(K){return d[b](d[c](K))}:d[b];e=(e+"").split(a);for(var n=0,E=e.length;n<E;n++)e[n]=f(e[n]);return e.join(a)}};d.decodePath=D("/","decodePathSegment");d.decodeUrnPath=D(":","decodeUrnPathSegment");d.recodePath=D("/","encodePathSegment","decode");d.recodeUrnPath=D(":","encodeUrnPathSegment","decode");d.encodeReserved=t("reserved","encode");d.parse=function(a,b){b||={preventInvalidHostname:d.preventInvalidHostname};a=a.replace(d.leading_whitespace_expression,
|
||||
"");a=a.replace(d.ascii_tab_whitespace,"");var c=a.indexOf("#");-1<c&&(b.fragment=a.substring(c+1)||null,a=a.substring(0,c));c=a.indexOf("?");-1<c&&(b.query=a.substring(c+1)||null,a=a.substring(0,c));a=a.replace(/^(https?|ftp|wss?)?:+[/\\]*/i,"$1://");a=a.replace(/^[/\\]{2,}/i,"//");"//"===a.substring(0,2)?(b.protocol=null,a=a.substring(2),a=d.parseAuthority(a,b)):(c=a.indexOf(":"),-1<c&&(b.protocol=a.substring(0,c)||null,b.protocol&&!b.protocol.match(d.protocol_expression)?b.protocol=void 0:"//"===
|
||||
a.substring(c+1,c+3).replace(/\\/g,"/")?(a=a.substring(c+3),a=d.parseAuthority(a,b)):(a=a.substring(c+1),b.urn=!0)));b.path=a;return b};d.parseHost=function(a,b){a||="";a=a.replace(/\\/g,"/");var c=a.indexOf("/");-1===c&&(c=a.length);if("["===a.charAt(0)){var e=a.indexOf("]");b.hostname=a.substring(1,e)||null;b.port=a.substring(e+2,c)||null;"/"===b.port&&(b.port=null)}else{var f=a.indexOf(":");e=a.indexOf("/");f=a.indexOf(":",f+1);-1!==f&&(-1===e||f<e)?(b.hostname=a.substring(0,c)||null,b.port=null):
|
||||
(e=a.substring(0,c).split(":"),b.hostname=e[0]||null,b.port=e[1]||null)}b.hostname&&"/"!==a.substring(c).charAt(0)&&(c++,a="/"+a);b.preventInvalidHostname&&d.ensureValidHostname(b.hostname,b.protocol);b.port&&d.ensureValidPort(b.port);return a.substring(c)||"/"};d.parseAuthority=function(a,b){a=d.parseUserinfo(a,b);return d.parseHost(a,b)};d.parseUserinfo=function(a,b){var c=a;-1!==a.indexOf("\\")&&(a=a.replace(/\\/g,"/"));var e=a.indexOf("/"),f=a.lastIndexOf("@",-1<e?e:a.length-1);-1<f&&(-1===e||
|
||||
f<e)?(a=a.substring(0,f).split(":"),b.username=a[0]?d.decode(a[0]):null,a.shift(),b.password=a[0]?d.decode(a.join(":")):null,a=c.substring(f+1)):(b.username=null,b.password=null);return a};d.parseQuery=function(a,b){if(!a)return{};a=a.replace(/&+/g,"&").replace(/^\?*&*|&+$/g,"");if(!a)return{};var c={};a=a.split("&");for(var e=a.length,f,n,E=0;E<e;E++)if(f=a[E].split("="),n=d.decodeQuery(f.shift(),b),f=f.length?d.decodeQuery(f.join("="),b):null,"__proto__"!==n)if(A.call(c,n)){if("string"===typeof c[n]||
|
||||
null===c[n])c[n]=[c[n]];c[n].push(f)}else c[n]=f;return c};d.build=function(a){var b="",c=!1;a.protocol&&(b+=a.protocol+":");a.urn||!b&&!a.hostname||(b+="//",c=!0);b+=d.buildAuthority(a)||"";"string"===typeof a.path&&("/"!==a.path.charAt(0)&&c&&(b+="/"),b+=a.path);"string"===typeof a.query&&a.query&&(b+="?"+a.query);"string"===typeof a.fragment&&a.fragment&&(b+="#"+a.fragment);return b};d.buildHost=function(a){var b="";if(a.hostname)b=d.ip6_expression.test(a.hostname)?b+("["+a.hostname+"]"):b+a.hostname;
|
||||
else return"";a.port&&(b+=":"+a.port);return b};d.buildAuthority=function(a){return d.buildUserinfo(a)+d.buildHost(a)};d.buildUserinfo=function(a){var b="";a.username&&(b+=d.encode(a.username));a.password&&(b+=":"+d.encode(a.password));b&&(b+="@");return b};d.buildQuery=function(a,b,c){var e="",f,n;for(f in a)if("__proto__"!==f&&A.call(a,f))if(z(a[f])){var E={};var K=0;for(n=a[f].length;K<n;K++)void 0!==a[f][K]&&void 0===E[a[f][K]+""]&&(e+="&"+d.buildQueryParameter(f,a[f][K],c),!0!==b&&(E[a[f][K]+
|
||||
""]=!0))}else void 0!==a[f]&&(e+="&"+d.buildQueryParameter(f,a[f],c));return e.substring(1)};d.buildQueryParameter=function(a,b,c){return d.encodeQuery(a,c)+(null!==b?"="+d.encodeQuery(b,c):"")};d.addQuery=function(a,b,c){if("object"===typeof b)for(var e in b)A.call(b,e)&&d.addQuery(a,e,b[e]);else if("string"===typeof b)void 0===a[b]?a[b]=c:("string"===typeof a[b]&&(a[b]=[a[b]]),z(c)||(c=[c]),a[b]=(a[b]||[]).concat(c));else throw new TypeError("URI.addQuery() accepts an object, string as the name parameter");
|
||||
};d.setQuery=function(a,b,c){if("object"===typeof b)for(var e in b)A.call(b,e)&&d.setQuery(a,e,b[e]);else if("string"===typeof b)a[b]=void 0===c?null:c;else throw new TypeError("URI.setQuery() accepts an object, string as the name parameter");};d.removeQuery=function(a,b,c){var e;if(z(b))for(c=0,e=b.length;c<e;c++)a[b[c]]=void 0;else if("RegExp"===B(b))for(e in a)b.test(e)&&(a[e]=void 0);else if("object"===typeof b)for(e in b)A.call(b,e)&&d.removeQuery(a,e,b[e]);else if("string"===typeof b)void 0!==
|
||||
c?"RegExp"===B(c)?!z(a[b])&&c.test(a[b])?a[b]=void 0:a[b]=h(a[b],c):a[b]!==String(c)||z(c)&&1!==c.length?z(a[b])&&(a[b]=h(a[b],c)):a[b]=void 0:a[b]=void 0;else throw new TypeError("URI.removeQuery() accepts an object, string, RegExp as the first parameter");};d.hasQuery=function(a,b,c,e){switch(B(b)){case "String":break;case "RegExp":for(var f in a)if(A.call(a,f)&&b.test(f)&&(void 0===c||d.hasQuery(a,f,c)))return!0;return!1;case "Object":for(var n in b)if(A.call(b,n)&&!d.hasQuery(a,n,b[n]))return!1;
|
||||
return!0;default:throw new TypeError("URI.hasQuery() accepts a string, regular expression or object as the name parameter");}switch(B(c)){case "Undefined":return b in a;case "Boolean":return a=!(z(a[b])?!a[b].length:!a[b]),c===a;case "Function":return!!c(a[b],b,a);case "Array":return z(a[b])?(e?p:F)(a[b],c):!1;case "RegExp":return z(a[b])?e?p(a[b],c):!1:!(!a[b]||!a[b].match(c));case "Number":c=String(c);case "String":return z(a[b])?e?p(a[b],c):!1:a[b]===c;default:throw new TypeError("URI.hasQuery() accepts undefined, boolean, string, number, RegExp, Function as the value parameter");
|
||||
}};d.joinPaths=function(){for(var a=[],b=[],c=0,e=0;e<arguments.length;e++){var f=new d(arguments[e]);a.push(f);f=f.segment();for(var n=0;n<f.length;n++)"string"===typeof f[n]&&b.push(f[n]),f[n]&&c++}if(!b.length||!c)return new d("");b=(new d("")).segment(b);""!==a[0].path()&&"/"!==a[0].path().slice(0,1)||b.path("/"+b.path());return b.normalize()};d.commonPath=function(a,b){var c=Math.min(a.length,b.length),e;for(e=0;e<c;e++)if(a.charAt(e)!==b.charAt(e)){e--;break}if(1>e)return a.charAt(0)===b.charAt(0)&&
|
||||
"/"===a.charAt(0)?"/":"";if("/"!==a.charAt(e)||"/"!==b.charAt(e))e=a.substring(0,e).lastIndexOf("/");return a.substring(0,e+1)};d.withinString=function(a,b,c){c||={};var e=c.start||d.findUri.start,f=c.end||d.findUri.end,n=c.trim||d.findUri.trim,E=c.parens||d.findUri.parens,K=/[a-z0-9-]=["']?$/i;for(e.lastIndex=0;;){var L=e.exec(a);if(!L)break;var P=L.index;if(c.ignoreHtml){var N=a.slice(Math.max(P-3,0),P);if(N&&K.test(N))continue}var O=P+a.slice(P).search(f);N=a.slice(P,O);for(O=-1;;){var Q=E.exec(N);
|
||||
if(!Q)break;O=Math.max(O,Q.index+Q[0].length)}N=-1<O?N.slice(0,O)+N.slice(O).replace(n,""):N.replace(n,"");N.length<=L[0].length||c.ignore&&c.ignore.test(N)||(O=P+N.length,L=b(N,P,O,a),void 0===L?e.lastIndex=O:(L=String(L),a=a.slice(0,P)+L+a.slice(O),e.lastIndex=P+L.length))}e.lastIndex=0;return a};d.ensureValidHostname=function(a,b){var c=!!a,e=!1;b&&(e=p(d.hostProtocols,b));if(e&&!c)throw new TypeError("Hostname cannot be empty, if protocol is "+b);if(a&&a.match(d.invalid_hostname_characters)){if(!r)throw new TypeError('Hostname "'+
|
||||
a+'" contains characters other than [A-Z0-9.-:_] and Punycode.js is not available');if(r.toASCII(a).match(d.invalid_hostname_characters))throw new TypeError('Hostname "'+a+'" contains characters other than [A-Z0-9.-:_]');}};d.ensureValidPort=function(a){if(a){var b=Number(a);if(!(/^[0-9]+$/.test(b)&&0<b&&65536>b))throw new TypeError('Port "'+a+'" is not a valid port');}};d.noConflict=function(a){if(a)return a={URI:this.noConflict()},m.URITemplate&&"function"===typeof m.URITemplate.noConflict&&(a.URITemplate=
|
||||
m.URITemplate.noConflict()),m.IPv6&&"function"===typeof m.IPv6.noConflict&&(a.IPv6=m.IPv6.noConflict()),m.SecondLevelDomains&&"function"===typeof m.SecondLevelDomains.noConflict&&(a.SecondLevelDomains=m.SecondLevelDomains.noConflict()),a;m.URI===this&&(m.URI=v);return this};g.build=function(a){if(!0===a)this._deferred_build=!0;else if(void 0===a||this._deferred_build)this._string=d.build(this._parts),this._deferred_build=!1;return this};g.clone=function(){return new d(this)};g.valueOf=g.toString=
|
||||
function(){return this.build(!1)._string};g.protocol=w("protocol");g.username=w("username");g.password=w("password");g.hostname=w("hostname");g.port=w("port");g.query=G("query","?");g.fragment=G("fragment","#");g.search=function(a,b){a=this.query(a,b);return"string"===typeof a&&a.length?"?"+a:a};g.hash=function(a,b){a=this.fragment(a,b);return"string"===typeof a&&a.length?"#"+a:a};g.pathname=function(a,b){if(void 0===a||!0===a)return b=this._parts.path||(this._parts.hostname?"/":""),a?(this._parts.urn?
|
||||
d.decodeUrnPath:d.decodePath)(b):b;this._parts.path=this._parts.urn?a?d.recodeUrnPath(a):"":a?d.recodePath(a):"/";this.build(!b);return this};g.path=g.pathname;g.href=function(a,b){var c;if(void 0===a)return this.toString();this._string="";this._parts=d._parts();var e=a instanceof d,f="object"===typeof a&&(a.hostname||a.path||a.pathname);a.nodeName&&(f=d.getDomAttribute(a),a=a[f]||"",f=!1);!e&&f&&void 0!==a.pathname&&(a=a.toString());if("string"===typeof a||a instanceof String)this._parts=d.parse(String(a),
|
||||
this._parts);else if(e||f){a=e?a._parts:a;for(c in a)"query"!==c&&A.call(this._parts,c)&&(this._parts[c]=a[c]);a.query&&this.query(a.query,!1)}else throw new TypeError("invalid input");this.build(!b);return this};g.is=function(a){var b=!1,c=!1,e=!1,f=!1,n=!1,E=!1,K=!1,L=!this._parts.urn;this._parts.hostname&&(L=!1,c=d.ip4_expression.test(this._parts.hostname),e=d.ip6_expression.test(this._parts.hostname),b=c||e,n=(f=!b)&&k&&k.has(this._parts.hostname),E=f&&d.idn_expression.test(this._parts.hostname),
|
||||
K=f&&d.punycode_expression.test(this._parts.hostname));switch(a.toLowerCase()){case "relative":return L;case "absolute":return!L;case "domain":case "name":return f;case "sld":return n;case "ip":return b;case "ip4":case "ipv4":case "inet4":return c;case "ip6":case "ipv6":case "inet6":return e;case "idn":return E;case "url":return!this._parts.urn;case "urn":return!!this._parts.urn;case "punycode":return K}return null};var H=g.protocol,y=g.port,I=g.hostname;g.protocol=function(a,b){if(a&&(a=a.replace(/:(\/\/)?$/,
|
||||
""),!a.match(d.protocol_expression)))throw new TypeError('Protocol "'+a+"\" contains characters other than [A-Z0-9.+-] or doesn't start with [A-Z]");return H.call(this,a,b)};g.scheme=g.protocol;g.port=function(a,b){if(this._parts.urn)return void 0===a?"":this;void 0!==a&&(0===a&&(a=null),a&&(a+="",":"===a.charAt(0)&&(a=a.substring(1)),d.ensureValidPort(a)));return y.call(this,a,b)};g.hostname=function(a,b){if(this._parts.urn)return void 0===a?"":this;if(void 0!==a){var c={preventInvalidHostname:this._parts.preventInvalidHostname};
|
||||
if("/"!==d.parseHost(a,c))throw new TypeError('Hostname "'+a+'" contains characters other than [A-Z0-9.-]');a=c.hostname;this._parts.preventInvalidHostname&&d.ensureValidHostname(a,this._parts.protocol)}return I.call(this,a,b)};g.origin=function(a,b){if(this._parts.urn)return void 0===a?"":this;if(void 0===a)return b=this.protocol(),this.authority()?(b?b+"://":"")+this.authority():"";a=d(a);this.protocol(a.protocol()).authority(a.authority()).build(!b);return this};g.host=function(a,b){if(this._parts.urn)return void 0===
|
||||
a?"":this;if(void 0===a)return this._parts.hostname?d.buildHost(this._parts):"";if("/"!==d.parseHost(a,this._parts))throw new TypeError('Hostname "'+a+'" contains characters other than [A-Z0-9.-]');this.build(!b);return this};g.authority=function(a,b){if(this._parts.urn)return void 0===a?"":this;if(void 0===a)return this._parts.hostname?d.buildAuthority(this._parts):"";if("/"!==d.parseAuthority(a,this._parts))throw new TypeError('Hostname "'+a+'" contains characters other than [A-Z0-9.-]');this.build(!b);
|
||||
return this};g.userinfo=function(a,b){if(this._parts.urn)return void 0===a?"":this;if(void 0===a)return(a=d.buildUserinfo(this._parts))?a.substring(0,a.length-1):a;"@"!==a[a.length-1]&&(a+="@");d.parseUserinfo(a,this._parts);this.build(!b);return this};g.resource=function(a,b){if(void 0===a)return this.path()+this.search()+this.hash();a=d.parse(a);this._parts.path=a.path;this._parts.query=a.query;this._parts.fragment=a.fragment;this.build(!b);return this};g.subdomain=function(a,b){if(this._parts.urn)return void 0===
|
||||
a?"":this;if(void 0===a){if(!this._parts.hostname||this.is("IP"))return"";a=this._parts.hostname.length-this.domain().length-1;return this._parts.hostname.substring(0,a)||""}var c=this._parts.hostname.length-this.domain().length;c=this._parts.hostname.substring(0,c);c=new RegExp("^"+q(c));a&&"."!==a.charAt(a.length-1)&&(a+=".");if(-1!==a.indexOf(":"))throw new TypeError("Domains cannot contain colons");a&&d.ensureValidHostname(a,this._parts.protocol);this._parts.hostname=this._parts.hostname.replace(c,
|
||||
a);this.build(!b);return this};g.domain=function(a,b){if(this._parts.urn)return void 0===a?"":this;"boolean"===typeof a&&(b=a,a=void 0);if(void 0===a){if(!this._parts.hostname||this.is("IP"))return"";if((a=this._parts.hostname.match(/\./g))&&2>a.length)return this._parts.hostname;b=this._parts.hostname.length-this.tld(b).length-1;b=this._parts.hostname.lastIndexOf(".",b-1)+1;return this._parts.hostname.substring(b)||""}if(!a)throw new TypeError("cannot set domain empty");if(-1!==a.indexOf(":"))throw new TypeError("Domains cannot contain colons");
|
||||
d.ensureValidHostname(a,this._parts.protocol);if(!this._parts.hostname||this.is("IP"))this._parts.hostname=a;else{var c=new RegExp(q(this.domain())+"$");this._parts.hostname=this._parts.hostname.replace(c,a)}this.build(!b);return this};g.tld=function(a,b){if(this._parts.urn)return void 0===a?"":this;"boolean"===typeof a&&(b=a,a=void 0);if(void 0===a){if(!this._parts.hostname||this.is("IP"))return"";a=this._parts.hostname.lastIndexOf(".");a=this._parts.hostname.substring(a+1);return!0!==b&&k&&k.list[a.toLowerCase()]?
|
||||
k.get(this._parts.hostname)||a:a}if(a)if(a.match(/[^a-zA-Z0-9-]/))if(k&&k.is(a)){var c=new RegExp(q(this.tld())+"$");this._parts.hostname=this._parts.hostname.replace(c,a)}else throw new TypeError('TLD "'+a+'" contains characters other than [A-Z0-9]');else{if(!this._parts.hostname||this.is("IP"))throw new ReferenceError("cannot set TLD on non-domain host");c=new RegExp(q(this.tld())+"$");this._parts.hostname=this._parts.hostname.replace(c,a)}else throw new TypeError("cannot set TLD empty");this.build(!b);
|
||||
return this};g.directory=function(a,b){if(this._parts.urn)return void 0===a?"":this;if(void 0===a||!0===a){if(!this._parts.path&&!this._parts.hostname)return"";if("/"===this._parts.path)return"/";b=this._parts.path.length-this.filename().length-1;b=this._parts.path.substring(0,b)||(this._parts.hostname?"/":"");return a?d.decodePath(b):b}var c=this._parts.path.length-this.filename().length;c=this._parts.path.substring(0,c);c=new RegExp("^"+q(c));this.is("relative")||(a||="/","/"!==a.charAt(0)&&(a=
|
||||
"/"+a));a&&"/"!==a.charAt(a.length-1)&&(a+="/");a=d.recodePath(a);this._parts.path=this._parts.path.replace(c,a);this.build(!b);return this};g.filename=function(a,b){if(this._parts.urn)return void 0===a?"":this;if("string"!==typeof a){if(!this._parts.path||"/"===this._parts.path)return"";b=this._parts.path.lastIndexOf("/");b=this._parts.path.substring(b+1);return a?d.decodePathSegment(b):b}var c=!1;"/"===a.charAt(0)&&(a=a.substring(1));a.match(/\.?\//)&&(c=!0);var e=new RegExp(q(this.filename())+
|
||||
"$");a=d.recodePath(a);this._parts.path=this._parts.path.replace(e,a);c?this.normalizePath(b):this.build(!b);return this};g.suffix=function(a,b){if(this._parts.urn)return void 0===a?"":this;if(void 0===a||!0===a){if(!this._parts.path||"/"===this._parts.path)return"";b=this.filename();var c=b.lastIndexOf(".");if(-1===c)return"";b=b.substring(c+1);b=/^[a-z0-9%]+$/i.test(b)?b:"";return a?d.decodePathSegment(b):b}"."===a.charAt(0)&&(a=a.substring(1));c=this.suffix();if(c)var e=a?new RegExp(q(c)+"$"):
|
||||
new RegExp(q("."+c)+"$");else{if(!a)return this;this._parts.path+="."+d.recodePath(a)}e&&(a=d.recodePath(a),this._parts.path=this._parts.path.replace(e,a));this.build(!b);return this};g.segment=function(a,b,c){var e=this._parts.urn?":":"/",f=this.path(),n="/"===f.substring(0,1);f=f.split(e);void 0!==a&&"number"!==typeof a&&(c=b,b=a,a=void 0);if(void 0!==a&&"number"!==typeof a)throw Error('Bad segment "'+a+'", must be 0-based integer');n&&f.shift();0>a&&(a=Math.max(f.length+a,0));if(void 0===b)return void 0===
|
||||
a?f:f[a];if(null===a||void 0===f[a])if(z(b)){f=[];a=0;for(var E=b.length;a<E;a++)if(b[a].length||f.length&&f[f.length-1].length)f.length&&!f[f.length-1].length&&f.pop(),f.push(u(b[a]))}else{if(b||"string"===typeof b)b=u(b),""===f[f.length-1]?f[f.length-1]=b:f.push(b)}else b?f[a]=u(b):f.splice(a,1);n&&f.unshift("");return this.path(f.join(e),c)};g.segmentCoded=function(a,b,c){var e;"number"!==typeof a&&(c=b,b=a,a=void 0);if(void 0===b){a=this.segment(a,b,c);if(z(a)){var f=0;for(e=a.length;f<e;f++)a[f]=
|
||||
d.decode(a[f])}else a=void 0!==a?d.decode(a):void 0;return a}if(z(b))for(f=0,e=b.length;f<e;f++)b[f]=d.encode(b[f]);else b="string"===typeof b||b instanceof String?d.encode(b):b;return this.segment(a,b,c)};var M=g.query;g.query=function(a,b){if(!0===a)return d.parseQuery(this._parts.query,this._parts.escapeQuerySpace);if("function"===typeof a){var c=d.parseQuery(this._parts.query,this._parts.escapeQuerySpace);a=a.call(this,c);this._parts.query=d.buildQuery(a||c,this._parts.duplicateQueryParameters,
|
||||
this._parts.escapeQuerySpace);this.build(!b);return this}return void 0!==a&&"string"!==typeof a?(this._parts.query=d.buildQuery(a,this._parts.duplicateQueryParameters,this._parts.escapeQuerySpace),this.build(!b),this):M.call(this,a,b)};g.setQuery=function(a,b,c){var e=d.parseQuery(this._parts.query,this._parts.escapeQuerySpace);if("string"===typeof a||a instanceof String)e[a]=void 0!==b?b:null;else if("object"===typeof a)for(var f in a)A.call(a,f)&&(e[f]=a[f]);else throw new TypeError("URI.addQuery() accepts an object, string as the name parameter");
|
||||
this._parts.query=d.buildQuery(e,this._parts.duplicateQueryParameters,this._parts.escapeQuerySpace);"string"!==typeof a&&(c=b);this.build(!c);return this};g.addQuery=function(a,b,c){var e=d.parseQuery(this._parts.query,this._parts.escapeQuerySpace);d.addQuery(e,a,void 0===b?null:b);this._parts.query=d.buildQuery(e,this._parts.duplicateQueryParameters,this._parts.escapeQuerySpace);"string"!==typeof a&&(c=b);this.build(!c);return this};g.removeQuery=function(a,b,c){var e=d.parseQuery(this._parts.query,
|
||||
this._parts.escapeQuerySpace);d.removeQuery(e,a,b);this._parts.query=d.buildQuery(e,this._parts.duplicateQueryParameters,this._parts.escapeQuerySpace);"string"!==typeof a&&(c=b);this.build(!c);return this};g.hasQuery=function(a,b,c){var e=d.parseQuery(this._parts.query,this._parts.escapeQuerySpace);return d.hasQuery(e,a,b,c)};g.setSearch=g.setQuery;g.addSearch=g.addQuery;g.removeSearch=g.removeQuery;g.hasSearch=g.hasQuery;g.normalize=function(){return this._parts.urn?this.normalizeProtocol(!1).normalizePath(!1).normalizeQuery(!1).normalizeFragment(!1).build():
|
||||
this.normalizeProtocol(!1).normalizeHostname(!1).normalizePort(!1).normalizePath(!1).normalizeQuery(!1).normalizeFragment(!1).build()};g.normalizeProtocol=function(a){"string"===typeof this._parts.protocol&&(this._parts.protocol=this._parts.protocol.toLowerCase(),this.build(!a));return this};g.normalizeHostname=function(a){this._parts.hostname&&(this.is("IDN")&&r?this._parts.hostname=r.toASCII(this._parts.hostname):this.is("IPv6")&&x&&(this._parts.hostname=x.best(this._parts.hostname)),this._parts.hostname=
|
||||
this._parts.hostname.toLowerCase(),this.build(!a));return this};g.normalizePort=function(a){"string"===typeof this._parts.protocol&&this._parts.port===d.defaultPorts[this._parts.protocol]&&(this._parts.port=null,this.build(!a));return this};g.normalizePath=function(a){var b=this._parts.path;if(!b)return this;if(this._parts.urn)return this._parts.path=d.recodeUrnPath(this._parts.path),this.build(!a),this;if("/"===this._parts.path)return this;b=d.recodePath(b);var c="";if("/"!==b.charAt(0)){var e=!0;
|
||||
b="/"+b}if("/.."===b.slice(-3)||"/."===b.slice(-2))b+="/";b=b.replace(/(\/(\.\/)+)|(\/\.$)/g,"/").replace(/\/{2,}/g,"/");e&&(c=b.substring(1).match(/^(\.\.\/)+/)||"")&&(c=c[0]);for(;;){var f=b.search(/\/\.\.(\/|$)/);if(-1===f)break;else if(0===f){b=b.substring(3);continue}var n=b.substring(0,f).lastIndexOf("/");-1===n&&(n=f);b=b.substring(0,n)+b.substring(f+3)}e&&this.is("relative")&&(b=c+b.substring(1));this._parts.path=b;this.build(!a);return this};g.normalizePathname=g.normalizePath;g.normalizeQuery=
|
||||
function(a){"string"===typeof this._parts.query&&(this._parts.query.length?this.query(d.parseQuery(this._parts.query,this._parts.escapeQuerySpace)):this._parts.query=null,this.build(!a));return this};g.normalizeFragment=function(a){this._parts.fragment||(this._parts.fragment=null,this.build(!a));return this};g.normalizeSearch=g.normalizeQuery;g.normalizeHash=g.normalizeFragment;g.iso8859=function(){var a=d.encode,b=d.decode;d.encode=escape;d.decode=decodeURIComponent;try{this.normalize()}finally{d.encode=
|
||||
a,d.decode=b}return this};g.unicode=function(){var a=d.encode,b=d.decode;d.encode=C;d.decode=unescape;try{this.normalize()}finally{d.encode=a,d.decode=b}return this};g.readable=function(){var a=this.clone();a.username("").password("").normalize();var b="";a._parts.protocol&&(b+=a._parts.protocol+"://");a._parts.hostname&&(a.is("punycode")&&r?(b+=r.toUnicode(a._parts.hostname),a._parts.port&&(b+=":"+a._parts.port)):b+=a.host());a._parts.hostname&&a._parts.path&&"/"!==a._parts.path.charAt(0)&&(b+="/");
|
||||
b+=a.path(!0);if(a._parts.query){for(var c="",e=0,f=a._parts.query.split("&"),n=f.length;e<n;e++){var E=(f[e]||"").split("=");c+="&"+d.decodeQuery(E[0],this._parts.escapeQuerySpace).replace(/&/g,"%26");void 0!==E[1]&&(c+="="+d.decodeQuery(E[1],this._parts.escapeQuerySpace).replace(/&/g,"%26"))}b+="?"+c.substring(1)}return b+=d.decodeQuery(a.hash(),!0)};g.absoluteTo=function(a){var b=this.clone(),c=["protocol","username","password","hostname","port"],e,f;if(this._parts.urn)throw Error("URNs do not have any generally defined hierarchical components");
|
||||
a instanceof d||(a=new d(a));if(b._parts.protocol)return b;b._parts.protocol=a._parts.protocol;if(this._parts.hostname)return b;for(e=0;f=c[e];e++)b._parts[f]=a._parts[f];b._parts.path?(".."===b._parts.path.substring(-2)&&(b._parts.path+="/"),"/"!==b.path().charAt(0)&&(c=(c=a.directory())?c:0===a.path().indexOf("/")?"/":"",b._parts.path=(c?c+"/":"")+b._parts.path,b.normalizePath())):(b._parts.path=a._parts.path,b._parts.query||(b._parts.query=a._parts.query));b.build();return b};g.relativeTo=function(a){var b=
|
||||
this.clone().normalize();if(b._parts.urn)throw Error("URNs do not have any generally defined hierarchical components");a=(new d(a)).normalize();var c=b._parts;var e=a._parts;var f=b.path();a=a.path();if("/"!==f.charAt(0))throw Error("URI is already relative");if("/"!==a.charAt(0))throw Error("Cannot calculate a URI relative to another relative URI");c.protocol===e.protocol&&(c.protocol=null);if(c.username===e.username&&c.password===e.password&&null===c.protocol&&null===c.username&&null===c.password&&
|
||||
c.hostname===e.hostname&&c.port===e.port)c.hostname=null,c.port=null;else return b.build();if(f===a)return c.path="",b.build();f=d.commonPath(f,a);if(!f)return b.build();e=e.path.substring(f.length).replace(/[^\/]*$/,"").replace(/.*?\//g,"../");c.path=e+c.path.substring(f.length)||"./";return b.build()};g.equals=function(a){var b=this.clone(),c=new d(a);a={};var e;b.normalize();c.normalize();if(b.toString()===c.toString())return!0;var f=b.query();var n=c.query();b.query("");c.query("");if(b.toString()!==
|
||||
c.toString()||f.length!==n.length)return!1;b=d.parseQuery(f,this._parts.escapeQuerySpace);n=d.parseQuery(n,this._parts.escapeQuerySpace);for(e in b)if(A.call(b,e)){if(!z(b[e])){if(b[e]!==n[e])return!1}else if(!F(b[e],n[e]))return!1;a[e]=!0}for(e in n)if(A.call(n,e)&&!a[e])return!1;return!0};g.preventInvalidHostname=function(a){this._parts.preventInvalidHostname=!!a;return this};g.duplicateQueryParameters=function(a){this._parts.duplicateQueryParameters=!!a;return this};g.escapeQuerySpace=function(a){this._parts.escapeQuerySpace=
|
||||
!!a;return this};return d});
|
||||
(function(r,x){"object"===typeof module&&module.exports?module.exports=x(require("./URI")):"function"===typeof define&&define.amd?define(["./URI"],x):r.URITemplate=x(r.URI,r)})(this,function(r,x){function k(h){if(k._cache[h])return k._cache[h];if(!(this instanceof k))return new k(h);this.expression=h;k._cache[h]=this;return this}function m(h){this.data=h;this.cache={}}var d=x&&x.URITemplate,q=Object.prototype.hasOwnProperty,B=k.prototype,z={"":{prefix:"",separator:",",named:!1,empty_name_separator:!1,
|
||||
encode:"encode"},"+":{prefix:"",separator:",",named:!1,empty_name_separator:!1,encode:"encodeReserved"},"#":{prefix:"#",separator:",",named:!1,empty_name_separator:!1,encode:"encodeReserved"},".":{prefix:".",separator:".",named:!1,empty_name_separator:!1,encode:"encode"},"/":{prefix:"/",separator:"/",named:!1,empty_name_separator:!1,encode:"encode"},";":{prefix:";",separator:";",named:!0,empty_name_separator:!1,encode:"encode"},"?":{prefix:"?",separator:"&",named:!0,empty_name_separator:!0,encode:"encode"},
|
||||
"&":{prefix:"&",separator:"&",named:!0,empty_name_separator:!0,encode:"encode"}};k._cache={};k.EXPRESSION_PATTERN=/\{([^a-zA-Z0-9%_]?)([^\}]+)(\}|$)/g;k.VARIABLE_PATTERN=/^([^*:.](?:\.?[^*:.])*)((\*)|:(\d+))?$/;k.VARIABLE_NAME_PATTERN=/[^a-zA-Z0-9%_.]/;k.LITERAL_PATTERN=/[<>{}"`^| \\]/;k.expand=function(h,p,F){var u=z[h.operator],J=u.named?"Named":"Unnamed";h=h.variables;var C=[],w,G;for(G=0;w=h[G];G++){var v=p.get(w.name);if(0===v.type&&F&&F.strict)throw Error('Missing expansion value for variable "'+
|
||||
w.name+'"');if(v.val.length){if(1<v.type&&w.maxlength)throw Error('Invalid expression: Prefix modifier not applicable to variable "'+w.name+'"');C.push(k["expand"+J](v,u,w.explode,w.explode&&u.separator||",",w.maxlength,w.name))}else v.type&&C.push("")}return C.length?u.prefix+C.join(u.separator):""};k.expandNamed=function(h,p,F,u,J,C){var w="",G=p.encode;p=p.empty_name_separator;var v=!h[G].length,g=2===h.type?"":r[G](C),A;var D=0;for(A=h.val.length;D<A;D++){if(J){var l=r[G](h.val[D][1].substring(0,
|
||||
J));2===h.type&&(g=r[G](h.val[D][0].substring(0,J)))}else v?(l=r[G](h.val[D][1]),2===h.type?(g=r[G](h.val[D][0]),h[G].push([g,l])):h[G].push([void 0,l])):(l=h[G][D][1],2===h.type&&(g=h[G][D][0]));w&&(w+=u);F?w+=g+(p||l?"=":"")+l:(D||(w+=r[G](C)+(p||l?"=":"")),2===h.type&&(w+=g+","),w+=l)}return w};k.expandUnnamed=function(h,p,F,u,J){var C="",w=p.encode;p=p.empty_name_separator;var G=!h[w].length,v;var g=0;for(v=h.val.length;g<v;g++){if(J)var A=r[w](h.val[g][1].substring(0,J));else G?(A=r[w](h.val[g][1]),
|
||||
h[w].push([2===h.type?r[w](h.val[g][0]):void 0,A])):A=h[w][g][1];C&&(C+=u);if(2===h.type){var D=J?r[w](h.val[g][0].substring(0,J)):h[w][g][0];C+=D;C=F?C+(p||A?"=":""):C+","}C+=A}return C};k.noConflict=function(){x.URITemplate===k&&(x.URITemplate=d);return k};B.expand=function(h,p){var F="";this.parts&&this.parts.length||this.parse();h instanceof m||(h=new m(h));for(var u=0,J=this.parts.length;u<J;u++)F+="string"===typeof this.parts[u]?this.parts[u]:k.expand(this.parts[u],h,p);return F};B.parse=function(){var h=
|
||||
this.expression,p=k.EXPRESSION_PATTERN,F=k.VARIABLE_PATTERN,u=k.VARIABLE_NAME_PATTERN,J=k.LITERAL_PATTERN,C=[],w=0,G=function(t){if(t.match(J))throw Error('Invalid Literal "'+t+'"');return t};for(p.lastIndex=0;;){var v=p.exec(h);if(null===v){C.push(G(h.substring(w)));break}else C.push(G(h.substring(w,v.index))),w=v.index+v[0].length;if(!z[v[1]])throw Error('Unknown Operator "'+v[1]+'" in "'+v[0]+'"');if(!v[3])throw Error('Unclosed Expression "'+v[0]+'"');var g=v[2].split(",");for(var A=0,D=g.length;A<
|
||||
D;A++){var l=g[A].match(F);if(null===l)throw Error('Invalid Variable "'+g[A]+'" in "'+v[0]+'"');if(l[1].match(u))throw Error('Invalid Variable Name "'+l[1]+'" in "'+v[0]+'"');g[A]={name:l[1],explode:!!l[3],maxlength:l[4]&&parseInt(l[4],10)}}if(!g.length)throw Error('Expression Missing Variable(s) "'+v[0]+'"');C.push({expression:v[0],operator:v[1],variables:g})}C.length||C.push(G(h));this.parts=C;return this};m.prototype.get=function(h){var p=this.data,F={type:0,val:[],encode:[],encodeReserved:[]};
|
||||
if(void 0!==this.cache[h])return this.cache[h];this.cache[h]=F;p="[object Function]"===String(Object.prototype.toString.call(p))?p(h):"[object Function]"===String(Object.prototype.toString.call(p[h]))?p[h](h):p[h];if(void 0!==p&&null!==p)if("[object Array]"===String(Object.prototype.toString.call(p))){var u=0;for(h=p.length;u<h;u++)void 0!==p[u]&&null!==p[u]&&F.val.push([void 0,String(p[u])]);F.val.length&&(F.type=3)}else if("[object Object]"===String(Object.prototype.toString.call(p))){for(u in p)q.call(p,
|
||||
u)&&void 0!==p[u]&&null!==p[u]&&F.val.push([u,String(p[u])]);F.val.length&&(F.type=2)}else F.type=1,F.val.push([void 0,String(p)]);return F};r.expand=function(h,p){h=(new k(h)).expand(p);return new r(h)};return k});
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
+6
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
+11932
File diff suppressed because it is too large
Load Diff
Vendored
+6
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Vendored
+6
File diff suppressed because one or more lines are too long
@@ -0,0 +1,76 @@
|
||||
import Vue from './vue.runtime.common.js'
|
||||
export default Vue
|
||||
|
||||
// this should be kept in sync with src/v3/index.ts
|
||||
export const {
|
||||
version,
|
||||
|
||||
// refs
|
||||
ref,
|
||||
shallowRef,
|
||||
isRef,
|
||||
toRef,
|
||||
toRefs,
|
||||
unref,
|
||||
proxyRefs,
|
||||
customRef,
|
||||
triggerRef,
|
||||
computed,
|
||||
|
||||
// reactive
|
||||
reactive,
|
||||
isReactive,
|
||||
isReadonly,
|
||||
isShallow,
|
||||
isProxy,
|
||||
shallowReactive,
|
||||
markRaw,
|
||||
toRaw,
|
||||
readonly,
|
||||
shallowReadonly,
|
||||
|
||||
// watch
|
||||
watch,
|
||||
watchEffect,
|
||||
watchPostEffect,
|
||||
watchSyncEffect,
|
||||
|
||||
// effectScope
|
||||
effectScope,
|
||||
onScopeDispose,
|
||||
getCurrentScope,
|
||||
|
||||
// provide / inject
|
||||
provide,
|
||||
inject,
|
||||
|
||||
// lifecycle
|
||||
onBeforeMount,
|
||||
onMounted,
|
||||
onBeforeUpdate,
|
||||
onUpdated,
|
||||
onBeforeUnmount,
|
||||
onUnmounted,
|
||||
onErrorCaptured,
|
||||
onActivated,
|
||||
onDeactivated,
|
||||
onServerPrefetch,
|
||||
onRenderTracked,
|
||||
onRenderTriggered,
|
||||
|
||||
// v2 only
|
||||
set,
|
||||
del,
|
||||
|
||||
// v3 compat
|
||||
h,
|
||||
getCurrentInstance,
|
||||
useSlots,
|
||||
useAttrs,
|
||||
mergeDefaults,
|
||||
nextTick,
|
||||
useCssModule,
|
||||
useCssVars,
|
||||
defineComponent,
|
||||
defineAsyncComponent
|
||||
} = Vue
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
Vendored
-6
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
-6
File diff suppressed because one or more lines are too long
@@ -1,8 +1,8 @@
|
||||
{{define "js"}}
|
||||
<script src="{{ .base_path }}assets/vue@2.6.12/vue.min.js"></script>
|
||||
<script src="{{ .base_path }}assets/vue/vue.min.js?{{ .cur_ver }}"></script>
|
||||
<script src="{{ .base_path }}assets/moment/moment.min.js"></script>
|
||||
<script src="{{ .base_path }}assets/ant-design-vue@1.7.8/antd.min.js"></script>
|
||||
<script src="{{ .base_path }}assets/axios/axios.min.js"></script>
|
||||
<script src="{{ .base_path }}assets/axios/axios.min.js?{{ .cur_ver }}"></script>
|
||||
<script src="{{ .base_path }}assets/qs/qs.min.js"></script>
|
||||
<script src="{{ .base_path }}assets/js/axios-init.js?{{ .cur_ver }}"></script>
|
||||
<script src="{{ .base_path }}assets/js/util/common.js?{{ .cur_ver }}"></script>
|
||||
|
||||
@@ -62,7 +62,7 @@
|
||||
<a-icon type="question-circle"></a-icon>
|
||||
</a-tooltip>
|
||||
</template>
|
||||
<a-input v-model.trim="clientsBulkModal.tgId"></a-input>
|
||||
<a-input-number style="width: 50%" v-model.trim="clientsBulkModal.tgId" min="0"></a-input-number>
|
||||
</a-form-item>
|
||||
<a-form-item>
|
||||
<template slot="label">
|
||||
@@ -143,7 +143,7 @@
|
||||
emailPrefix: "",
|
||||
emailPostfix: "",
|
||||
subId: "",
|
||||
tgId: "",
|
||||
tgId: 0,
|
||||
flow: "",
|
||||
delayedStart: false,
|
||||
reset: 0,
|
||||
@@ -200,7 +200,7 @@
|
||||
this.emailPrefix = "";
|
||||
this.emailPostfix = "";
|
||||
this.subId = "";
|
||||
this.tgId = "";
|
||||
this.tgId = 0;
|
||||
this.flow = "";
|
||||
this.dbInbound = new DBInbound(dbInbound);
|
||||
this.inbound = dbInbound.toInbound();
|
||||
|
||||
@@ -13,9 +13,9 @@
|
||||
{{end}}
|
||||
|
||||
{{define "component/persianDatepicker"}}
|
||||
<link rel="stylesheet" href="{{ .base_path }}assets/persian-datepicker/persian-datepicker.min.css"/>
|
||||
<script src="{{ .base_path }}assets/moment/moment-jalali.min.js"></script>
|
||||
<script src="{{ .base_path }}assets/persian-datepicker/persian-datepicker.min.js"></script>
|
||||
<link rel="stylesheet" href="{{ .base_path }}assets/persian-datepicker/persian-datepicker.min.css?{{ .cur_ver }}"/>
|
||||
<script src="{{ .base_path }}assets/moment/moment-jalali.min.js?{{ .cur_ver }}"></script>
|
||||
<script src="{{ .base_path }}assets/persian-datepicker/persian-datepicker.min.js?{{ .cur_ver }}"></script>
|
||||
<script>
|
||||
|
||||
const persianDatepicker = {};
|
||||
|
||||
@@ -61,7 +61,7 @@
|
||||
<a-icon type="question-circle"></a-icon>
|
||||
</a-tooltip>
|
||||
</template>
|
||||
<a-input v-model.trim="client.tgId"></a-input>
|
||||
<a-input-number style="width: 50%" v-model="client.tgId" min="0"></a-input-number>
|
||||
</a-form-item>
|
||||
<a-form-item v-if="app.ipLimitEnable">
|
||||
<template slot="label">
|
||||
|
||||
@@ -290,8 +290,8 @@
|
||||
<a-input v-model="outbound.stream.ws.host"></a-input>
|
||||
</a-form-item>
|
||||
<a-form-item label='{{ i18n "path" }}'>
|
||||
<a-form-item><a-input v-model.trim="outbound.stream.ws.path"></a-input>
|
||||
</a-form-item>
|
||||
<a-input v-model.trim="outbound.stream.ws.path"></a-input>
|
||||
</a-form-item>
|
||||
</template>
|
||||
|
||||
<!-- http -->
|
||||
@@ -347,8 +347,8 @@
|
||||
<a-input v-model="outbound.stream.httpupgrade.host"></a-input>
|
||||
</a-form-item>
|
||||
<a-form-item label='{{ i18n "path" }}'>
|
||||
<a-form-item><a-input v-model.trim="outbound.stream.httpupgrade.path"></a-input>
|
||||
</a-form-item>
|
||||
<a-input v-model.trim="outbound.stream.httpupgrade.path"></a-input>
|
||||
</a-form-item>
|
||||
</template>
|
||||
</template>
|
||||
|
||||
|
||||
@@ -9,5 +9,18 @@
|
||||
<a-form-item label='{{ i18n "path" }}'>
|
||||
<a-input v-model.trim="inbound.stream.httpupgrade.path"></a-input>
|
||||
</a-form-item>
|
||||
<a-form-item label='{{ i18n "pages.inbounds.stream.tcp.requestHeader" }}'>
|
||||
<a-button size="small" @click="inbound.stream.httpupgrade.addHeader('host', '')">+</a-button>
|
||||
</a-form-item>
|
||||
<a-form-item :wrapper-col="{span:24}">
|
||||
<a-input-group compact v-for="(header, index) in inbound.stream.httpupgrade.headers">
|
||||
<a-input style="width: 50%" v-model.trim="header.name" placeholder='{{ i18n "pages.inbounds.stream.general.name"}}'>
|
||||
<template slot="addonBefore" style="margin: 0;">[[ index+1 ]]</template>
|
||||
</a-input>
|
||||
<a-input style="width: 50%" v-model.trim="header.value" placeholder='{{ i18n "pages.inbounds.stream.general.value" }}'>
|
||||
<a-button slot="addonAfter" size="small" @click="inbound.stream.httpupgrade.removeHeader(index)">-</a-button>
|
||||
</a-input>
|
||||
</a-input-group>
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
{{end}}
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
<a-input v-model.trim="inbound.stream.ws.path"></a-input>
|
||||
</a-form-item>
|
||||
<a-form-item label='{{ i18n "pages.inbounds.stream.tcp.requestHeader" }}'>
|
||||
<a-button size="small" @click="inbound.stream.ws.addHeader('Host', '')">+</a-button>
|
||||
<a-button size="small" @click="inbound.stream.ws.addHeader('host', '')">+</a-button>
|
||||
</a-form-item>
|
||||
<a-form-item :wrapper-col="{span:24}">
|
||||
<a-input-group compact v-for="(header, index) in inbound.stream.ws.headers">
|
||||
|
||||
@@ -458,9 +458,9 @@
|
||||
</a-layout>
|
||||
{{template "js" .}}
|
||||
<script src="{{ .base_path }}assets/base64/base64.min.js"></script>
|
||||
<script src="{{ .base_path }}assets/qrcode/qrious2.min.js"></script>
|
||||
<script src="{{ .base_path }}assets/clipboard/clipboard.min.js"></script>
|
||||
<script src="{{ .base_path }}assets/uri/URI.min.js"></script>
|
||||
<script src="{{ .base_path }}assets/qrcode/qrious2.min.js?{{ .cur_ver }}"></script>
|
||||
<script src="{{ .base_path }}assets/clipboard/clipboard.min.js?{{ .cur_ver }}"></script>
|
||||
<script src="{{ .base_path }}assets/uri/URI.min.js?{{ .cur_ver }}"></script>
|
||||
<script src="{{ .base_path }}assets/js/model/xray.js?{{ .cur_ver }}"></script>
|
||||
<script src="{{ .base_path }}assets/js/model/dbinbound.js?{{ .cur_ver }}"></script>
|
||||
{{template "component/themeSwitcher" .}}
|
||||
|
||||
+221
-220
@@ -23,230 +23,231 @@
|
||||
{{ template "commonSider" . }}
|
||||
<a-layout id="content-layout">
|
||||
<a-layout-content>
|
||||
<a-spin :spinning="spinning" :delay="200" :tip="loadingTip"></a-spin>
|
||||
<transition name="list" appear>
|
||||
<a-alert type="error" v-if="showAlert" style="margin-bottom: 10px"
|
||||
message='{{ i18n "secAlertTitle" }}'
|
||||
color="red"
|
||||
description='{{ i18n "secAlertSsl" }}'
|
||||
show-icon closable>
|
||||
</a-alert>
|
||||
</transition>
|
||||
<transition name="list" appear>
|
||||
<a-row>
|
||||
<a-card hoverable>
|
||||
<a-row>
|
||||
<a-col :sm="24" :md="12">
|
||||
<a-row>
|
||||
<a-col :span="12" style="text-align: center">
|
||||
<a-progress type="dashboard" status="normal"
|
||||
:stroke-color="status.cpu.color"
|
||||
:percent="status.cpu.percent"></a-progress>
|
||||
<div><b>CPU:</b> [[ cpuCoreFormat(status.cpuCores) ]]</div>
|
||||
<div><b>Speed:</b> [[ cpuSpeedFormat(status.cpuSpeedMhz) ]]</div>
|
||||
</a-col>
|
||||
<a-col :span="12" style="text-align: center">
|
||||
<a-progress type="dashboard" status="normal"
|
||||
:stroke-color="status.mem.color"
|
||||
:percent="status.mem.percent"></a-progress>
|
||||
<div>
|
||||
<b>{{ i18n "pages.index.memory"}}:</b> [[ sizeFormat(status.mem.current) ]] / [[ sizeFormat(status.mem.total) ]]
|
||||
</div>
|
||||
</a-col>
|
||||
</a-row>
|
||||
</a-col>
|
||||
<a-col :sm="24" :md="12">
|
||||
<a-row>
|
||||
<a-col :span="12" style="text-align: center">
|
||||
<a-progress type="dashboard" status="normal"
|
||||
:stroke-color="status.swap.color"
|
||||
:percent="status.swap.percent"></a-progress>
|
||||
<div>
|
||||
<b>Swap:</b> [[ sizeFormat(status.swap.current) ]] / [[ sizeFormat(status.swap.total) ]]
|
||||
</div>
|
||||
</a-col>
|
||||
<a-col :span="12" style="text-align: center">
|
||||
<a-progress type="dashboard" status="normal"
|
||||
:stroke-color="status.disk.color"
|
||||
:percent="status.disk.percent"></a-progress>
|
||||
<div>
|
||||
<b>{{ i18n "pages.index.hard"}}:</b> [[ sizeFormat(status.disk.current) ]] / [[ sizeFormat(status.disk.total) ]]
|
||||
</div>
|
||||
</a-col>
|
||||
</a-row>
|
||||
</a-col>
|
||||
</a-row>
|
||||
</a-card>
|
||||
</a-row>
|
||||
</transition>
|
||||
<transition name="list" appear>
|
||||
<a-row>
|
||||
<a-col :sm="24" :lg="12">
|
||||
<a-spin :spinning="spinning" :delay="200" :tip="loadingTip">
|
||||
<transition name="list" appear>
|
||||
<a-alert type="error" v-if="showAlert" style="margin-bottom: 10px"
|
||||
message='{{ i18n "secAlertTitle" }}'
|
||||
color="red"
|
||||
description='{{ i18n "secAlertSsl" }}'
|
||||
show-icon closable>
|
||||
</a-alert>
|
||||
</transition>
|
||||
<transition name="list" appear>
|
||||
<a-row>
|
||||
<a-card hoverable>
|
||||
<b>3X-UI:</b>
|
||||
<a rel="noopener" href="https://github.com/MHSanaei/3x-ui/releases" target="_blank"><a-tag color="green">v{{ .cur_ver }}</a-tag></a>
|
||||
<a rel="noopener" href="https://t.me/XrayUI" target="_blank"><a-tag color="green">@XrayUI</a-tag></a>
|
||||
<a-row>
|
||||
<a-col :sm="24" :md="12">
|
||||
<a-row>
|
||||
<a-col :span="12" style="text-align: center">
|
||||
<a-progress type="dashboard" status="normal"
|
||||
:stroke-color="status.cpu.color"
|
||||
:percent="status.cpu.percent"></a-progress>
|
||||
<div><b>CPU:</b> [[ cpuCoreFormat(status.cpuCores) ]]</div>
|
||||
<div><b>Speed:</b> [[ cpuSpeedFormat(status.cpuSpeedMhz) ]]</div>
|
||||
</a-col>
|
||||
<a-col :span="12" style="text-align: center">
|
||||
<a-progress type="dashboard" status="normal"
|
||||
:stroke-color="status.mem.color"
|
||||
:percent="status.mem.percent"></a-progress>
|
||||
<div>
|
||||
<b>{{ i18n "pages.index.memory"}}:</b> [[ sizeFormat(status.mem.current) ]] / [[ sizeFormat(status.mem.total) ]]
|
||||
</div>
|
||||
</a-col>
|
||||
</a-row>
|
||||
</a-col>
|
||||
<a-col :sm="24" :md="12">
|
||||
<a-row>
|
||||
<a-col :span="12" style="text-align: center">
|
||||
<a-progress type="dashboard" status="normal"
|
||||
:stroke-color="status.swap.color"
|
||||
:percent="status.swap.percent"></a-progress>
|
||||
<div>
|
||||
<b>Swap:</b> [[ sizeFormat(status.swap.current) ]] / [[ sizeFormat(status.swap.total) ]]
|
||||
</div>
|
||||
</a-col>
|
||||
<a-col :span="12" style="text-align: center">
|
||||
<a-progress type="dashboard" status="normal"
|
||||
:stroke-color="status.disk.color"
|
||||
:percent="status.disk.percent"></a-progress>
|
||||
<div>
|
||||
<b>{{ i18n "pages.index.hard"}}:</b> [[ sizeFormat(status.disk.current) ]] / [[ sizeFormat(status.disk.total) ]]
|
||||
</div>
|
||||
</a-col>
|
||||
</a-row>
|
||||
</a-col>
|
||||
</a-row>
|
||||
</a-card>
|
||||
</a-col>
|
||||
<a-col :sm="24" :lg="12">
|
||||
<a-card hoverable>
|
||||
<b>{{ i18n "pages.index.operationHours" }}:</b>
|
||||
<a-tag :color="status.xray.color">Xray: [[ formatSecond(status.appStats.uptime) ]]</a-tag>
|
||||
<a-tag color="green">OS: [[ formatSecond(status.uptime) ]]</a-tag>
|
||||
</a-card>
|
||||
</a-col>
|
||||
<a-col :sm="24" :lg="12">
|
||||
<a-card hoverable>
|
||||
<b>{{ i18n "pages.index.xrayStatus" }}:</b>
|
||||
<a-tag style="text-transform: capitalize;" :color="status.xray.color">[[ status.xray.state ]] </a-tag>
|
||||
<a-popover v-if="status.xray.state === State.Error" :overlay-class-name="themeSwitcher.currentTheme">
|
||||
<span slot="title" style="font-size: 12pt">An error occurred while running Xray
|
||||
<a-tag color="purple" style="cursor: pointer; float: right;" @click="openLogs()">{{ i18n "pages.index.logs" }}</a-tag>
|
||||
</span>
|
||||
<template slot="content">
|
||||
<p style="max-width: 400px" v-for="line in status.xray.errorMsg.split('\n')">[[ line ]]</p>
|
||||
</template>
|
||||
<a-icon type="question-circle"></a-icon>
|
||||
</a-popover>
|
||||
<a-tag color="purple" style="cursor: pointer;" @click="stopXrayService">{{ i18n "pages.index.stopXray" }}</a-tag>
|
||||
<a-tag color="purple" style="cursor: pointer;" @click="restartXrayService">{{ i18n "pages.index.restartXray" }}</a-tag>
|
||||
<a-tag color="purple" style="cursor: pointer;" @click="openSelectV2rayVersion">v[[ status.xray.version ]]</a-tag>
|
||||
</a-card>
|
||||
</a-col>
|
||||
<a-col :sm="24" :lg="12">
|
||||
<a-card hoverable>
|
||||
<b>{{ i18n "menu.link" }}:</b>
|
||||
<a-tag color="purple" style="cursor: pointer;" @click="openLogs()">{{ i18n "pages.index.logs" }}</a-tag>
|
||||
<a-tag color="purple" style="cursor: pointer;" @click="openConfig">{{ i18n "pages.index.config" }}</a-tag>
|
||||
<a-tag color="purple" style="cursor: pointer;" @click="openBackup">{{ i18n "pages.index.backup" }}</a-tag>
|
||||
</a-card>
|
||||
</a-col>
|
||||
<a-col :sm="24" :lg="12">
|
||||
<a-card hoverable>
|
||||
<b>{{ i18n "pages.index.systemLoad" }}:</b>
|
||||
<a-tag color="green">
|
||||
<a-tooltip>
|
||||
[[ status.loads[0] ]] | [[ status.loads[1] ]] | [[ status.loads[2] ]]
|
||||
<template slot="title">
|
||||
{{ i18n "pages.index.systemLoadDesc" }}
|
||||
</a-row>
|
||||
</transition>
|
||||
<transition name="list" appear>
|
||||
<a-row>
|
||||
<a-col :sm="24" :lg="12">
|
||||
<a-card hoverable>
|
||||
<b>3X-UI:</b>
|
||||
<a rel="noopener" href="https://github.com/MHSanaei/3x-ui/releases" target="_blank"><a-tag color="green">v{{ .cur_ver }}</a-tag></a>
|
||||
<a rel="noopener" href="https://t.me/XrayUI" target="_blank"><a-tag color="green">@XrayUI</a-tag></a>
|
||||
</a-card>
|
||||
</a-col>
|
||||
<a-col :sm="24" :lg="12">
|
||||
<a-card hoverable>
|
||||
<b>{{ i18n "pages.index.operationHours" }}:</b>
|
||||
<a-tag :color="status.xray.color">Xray: [[ formatSecond(status.appStats.uptime) ]]</a-tag>
|
||||
<a-tag color="green">OS: [[ formatSecond(status.uptime) ]]</a-tag>
|
||||
</a-card>
|
||||
</a-col>
|
||||
<a-col :sm="24" :lg="12">
|
||||
<a-card hoverable>
|
||||
<b>{{ i18n "pages.index.xrayStatus" }}:</b>
|
||||
<a-tag style="text-transform: capitalize;" :color="status.xray.color">[[ status.xray.state ]] </a-tag>
|
||||
<a-popover v-if="status.xray.state === State.Error" :overlay-class-name="themeSwitcher.currentTheme">
|
||||
<span slot="title" style="font-size: 12pt">An error occurred while running Xray
|
||||
<a-tag color="purple" style="cursor: pointer; float: right;" @click="openLogs()">{{ i18n "pages.index.logs" }}</a-tag>
|
||||
</span>
|
||||
<template slot="content">
|
||||
<p style="max-width: 400px" v-for="line in status.xray.errorMsg.split('\n')">[[ line ]]</p>
|
||||
</template>
|
||||
</a-tooltip>
|
||||
</a-tag>
|
||||
</a-card>
|
||||
</a-col>
|
||||
<a-col :sm="24" :lg="12">
|
||||
<a-card hoverable>
|
||||
<b>{{ i18n "usage"}}:</b>
|
||||
<a-tag color="green"> RAM: [[ sizeFormat(status.appStats.mem) ]] </a-tag>
|
||||
<a-tag color="green"> Threads: [[ status.appStats.threads ]] </a-tag>
|
||||
</a-card>
|
||||
</a-col>
|
||||
<a-col :sm="24" :lg="12">
|
||||
<a-card hoverable>
|
||||
<a-row>
|
||||
<a-col :span="12">
|
||||
<a-tag>
|
||||
<a-tooltip>
|
||||
<a-icon type="global"></a-icon> IPv4
|
||||
<template slot="title">
|
||||
<a-icon type="question-circle"></a-icon>
|
||||
</a-popover>
|
||||
<a-tag color="purple" style="cursor: pointer;" @click="stopXrayService">{{ i18n "pages.index.stopXray" }}</a-tag>
|
||||
<a-tag color="purple" style="cursor: pointer;" @click="restartXrayService">{{ i18n "pages.index.restartXray" }}</a-tag>
|
||||
<a-tag color="purple" style="cursor: pointer;" @click="openSelectV2rayVersion">v[[ status.xray.version ]]</a-tag>
|
||||
</a-card>
|
||||
</a-col>
|
||||
<a-col :sm="24" :lg="12">
|
||||
<a-card hoverable>
|
||||
<b>{{ i18n "menu.link" }}:</b>
|
||||
<a-tag color="purple" style="cursor: pointer;" @click="openLogs()">{{ i18n "pages.index.logs" }}</a-tag>
|
||||
<a-tag color="purple" style="cursor: pointer;" @click="openConfig">{{ i18n "pages.index.config" }}</a-tag>
|
||||
<a-tag color="purple" style="cursor: pointer;" @click="openBackup">{{ i18n "pages.index.backup" }}</a-tag>
|
||||
</a-card>
|
||||
</a-col>
|
||||
<a-col :sm="24" :lg="12">
|
||||
<a-card hoverable>
|
||||
<b>{{ i18n "pages.index.systemLoad" }}:</b>
|
||||
<a-tag color="green">
|
||||
<a-tooltip>
|
||||
[[ status.loads[0] ]] | [[ status.loads[1] ]] | [[ status.loads[2] ]]
|
||||
<template slot="title">
|
||||
{{ i18n "pages.index.systemLoadDesc" }}
|
||||
</template>
|
||||
</a-tooltip>
|
||||
</a-tag>
|
||||
</a-card>
|
||||
</a-col>
|
||||
<a-col :sm="24" :lg="12">
|
||||
<a-card hoverable>
|
||||
<b>{{ i18n "usage"}}:</b>
|
||||
<a-tag color="green"> RAM: [[ sizeFormat(status.appStats.mem) ]] </a-tag>
|
||||
<a-tag color="green"> Threads: [[ status.appStats.threads ]] </a-tag>
|
||||
</a-card>
|
||||
</a-col>
|
||||
<a-col :sm="24" :lg="12">
|
||||
<a-card hoverable>
|
||||
<a-row>
|
||||
<a-col :span="12">
|
||||
<a-tag>
|
||||
<a-tooltip>
|
||||
<a-icon type="global"></a-icon> IPv4
|
||||
<template slot="title">
|
||||
[[ status.publicIP.ipv4 ]]
|
||||
</template>
|
||||
</a-tooltip>
|
||||
</a-tag>
|
||||
</a-col>
|
||||
<a-col :span="12">
|
||||
<a-tag>
|
||||
<a-tooltip>
|
||||
<a-icon type="global"></a-icon> IPv6
|
||||
<template slot="title">
|
||||
</template>
|
||||
</a-tooltip>
|
||||
</a-tag>
|
||||
</a-col>
|
||||
<a-col :span="12">
|
||||
<a-tag>
|
||||
<a-tooltip>
|
||||
<a-icon type="global"></a-icon> IPv6
|
||||
<template slot="title">
|
||||
[[ status.publicIP.ipv6 ]]
|
||||
</template>
|
||||
</a-tooltip>
|
||||
</a-tag>
|
||||
</a-col>
|
||||
</a-row>
|
||||
</a-card>
|
||||
</a-col>
|
||||
<a-col :sm="24" :lg="12">
|
||||
<a-card hoverable>
|
||||
<a-row>
|
||||
<a-col :span="12">
|
||||
<a-tag>
|
||||
<a-tooltip>
|
||||
<a-icon type="swap"></a-icon> TCP: [[ status.tcpCount ]]
|
||||
<template slot="title">
|
||||
{{ i18n "pages.index.connectionTcpCountDesc" }}
|
||||
</template>
|
||||
</a-tooltip>
|
||||
</a-tag>
|
||||
</a-col>
|
||||
<a-col :span="12">
|
||||
<a-tag>
|
||||
<a-tooltip>
|
||||
<a-icon type="swap"></a-icon> UDP: [[ status.udpCount ]]
|
||||
<template slot="title">
|
||||
{{ i18n "pages.index.connectionUdpCountDesc" }}
|
||||
</template>
|
||||
</a-tooltip>
|
||||
</a-tag>
|
||||
</a-col>
|
||||
</a-row>
|
||||
</a-card>
|
||||
</a-col>
|
||||
<a-col :sm="24" :lg="12">
|
||||
<a-card hoverable>
|
||||
<a-row>
|
||||
<a-col :span="12">
|
||||
<a-tag>
|
||||
<a-tooltip>
|
||||
<a-icon type="arrow-up"></a-icon> Up: [[ sizeFormat(status.netIO.up) ]]/s
|
||||
<template slot="title">
|
||||
{{ i18n "pages.index.upSpeed" }}
|
||||
</template>
|
||||
</a-tooltip>
|
||||
</a-tag>
|
||||
</a-col>
|
||||
<a-col :span="12">
|
||||
<a-tag>
|
||||
<a-tooltip>
|
||||
<a-icon type="arrow-down"></a-icon> Down: [[ sizeFormat(status.netIO.down) ]]/s
|
||||
<template slot="title">
|
||||
{{ i18n "pages.index.downSpeed" }}
|
||||
</template>
|
||||
</a-tooltip>
|
||||
</a-tag>
|
||||
</a-col>
|
||||
</a-row>
|
||||
</a-card>
|
||||
</a-col>
|
||||
<a-col :sm="24" :lg="12">
|
||||
<a-card hoverable>
|
||||
<a-row>
|
||||
<a-col :span="12">
|
||||
<a-tag>
|
||||
<a-tooltip>
|
||||
<a-icon type="cloud-upload"></a-icon>
|
||||
<template slot="title">
|
||||
{{ i18n "pages.index.totalSent" }}
|
||||
</template> Out: [[ sizeFormat(status.netTraffic.sent) ]]
|
||||
</a-tooltip>
|
||||
</a-tag>
|
||||
</a-col>
|
||||
<a-col :span="12">
|
||||
<a-tag>
|
||||
<a-tooltip>
|
||||
<a-icon type="cloud-download"></a-icon>
|
||||
<template slot="title">
|
||||
{{ i18n "pages.index.totalReceive" }}
|
||||
</template> In: [[ sizeFormat(status.netTraffic.recv) ]]
|
||||
</a-tooltip>
|
||||
</a-tag>
|
||||
</a-col>
|
||||
</a-row>
|
||||
</a-card>
|
||||
</a-col>
|
||||
</a-row>
|
||||
</transition>
|
||||
</template>
|
||||
</a-tooltip>
|
||||
</a-tag>
|
||||
</a-col>
|
||||
</a-row>
|
||||
</a-card>
|
||||
</a-col>
|
||||
<a-col :sm="24" :lg="12">
|
||||
<a-card hoverable>
|
||||
<a-row>
|
||||
<a-col :span="12">
|
||||
<a-tag>
|
||||
<a-tooltip>
|
||||
<a-icon type="swap"></a-icon> TCP: [[ status.tcpCount ]]
|
||||
<template slot="title">
|
||||
{{ i18n "pages.index.connectionTcpCountDesc" }}
|
||||
</template>
|
||||
</a-tooltip>
|
||||
</a-tag>
|
||||
</a-col>
|
||||
<a-col :span="12">
|
||||
<a-tag>
|
||||
<a-tooltip>
|
||||
<a-icon type="swap"></a-icon> UDP: [[ status.udpCount ]]
|
||||
<template slot="title">
|
||||
{{ i18n "pages.index.connectionUdpCountDesc" }}
|
||||
</template>
|
||||
</a-tooltip>
|
||||
</a-tag>
|
||||
</a-col>
|
||||
</a-row>
|
||||
</a-card>
|
||||
</a-col>
|
||||
<a-col :sm="24" :lg="12">
|
||||
<a-card hoverable>
|
||||
<a-row>
|
||||
<a-col :span="12">
|
||||
<a-tag>
|
||||
<a-tooltip>
|
||||
<a-icon type="arrow-up"></a-icon> Up: [[ sizeFormat(status.netIO.up) ]]/s
|
||||
<template slot="title">
|
||||
{{ i18n "pages.index.upSpeed" }}
|
||||
</template>
|
||||
</a-tooltip>
|
||||
</a-tag>
|
||||
</a-col>
|
||||
<a-col :span="12">
|
||||
<a-tag>
|
||||
<a-tooltip>
|
||||
<a-icon type="arrow-down"></a-icon> Down: [[ sizeFormat(status.netIO.down) ]]/s
|
||||
<template slot="title">
|
||||
{{ i18n "pages.index.downSpeed" }}
|
||||
</template>
|
||||
</a-tooltip>
|
||||
</a-tag>
|
||||
</a-col>
|
||||
</a-row>
|
||||
</a-card>
|
||||
</a-col>
|
||||
<a-col :sm="24" :lg="12">
|
||||
<a-card hoverable>
|
||||
<a-row>
|
||||
<a-col :span="12">
|
||||
<a-tag>
|
||||
<a-tooltip>
|
||||
<a-icon type="cloud-upload"></a-icon>
|
||||
<template slot="title">
|
||||
{{ i18n "pages.index.totalSent" }}
|
||||
</template> Out: [[ sizeFormat(status.netTraffic.sent) ]]
|
||||
</a-tooltip>
|
||||
</a-tag>
|
||||
</a-col>
|
||||
<a-col :span="12">
|
||||
<a-tag>
|
||||
<a-tooltip>
|
||||
<a-icon type="cloud-download"></a-icon>
|
||||
<template slot="title">
|
||||
{{ i18n "pages.index.totalReceive" }}
|
||||
</template> In: [[ sizeFormat(status.netTraffic.recv) ]]
|
||||
</a-tooltip>
|
||||
</a-tag>
|
||||
</a-col>
|
||||
</a-row>
|
||||
</a-card>
|
||||
</a-col>
|
||||
</a-row>
|
||||
</transition>
|
||||
</a-spin>
|
||||
</a-layout-content>
|
||||
</a-layout>
|
||||
<a-modal id="version-modal" v-model="versionModal.visible" title='{{ i18n "pages.index.xraySwitch" }}' :closable="true"
|
||||
@@ -322,7 +323,7 @@
|
||||
</a-modal>
|
||||
</a-layout>
|
||||
{{template "js" .}}
|
||||
<script src="{{ .base_path }}assets/clipboard/clipboard.min.js"></script>
|
||||
<script src="{{ .base_path }}assets/clipboard/clipboard.min.js?{{ .cur_ver }}"></script>
|
||||
{{template "component/themeSwitcher" .}}
|
||||
{{template "textModal"}}
|
||||
<script>
|
||||
|
||||
+318
-312
@@ -75,7 +75,7 @@
|
||||
<a-layout-content>
|
||||
<a-spin :spinning="spinning" :delay="500" tip='{{ i18n "loading"}}'>
|
||||
<transition name="list" appear>
|
||||
<a-alert type="error" v-if="confAlerts.length>0" style="margin: 10px 5px;"
|
||||
<a-alert type="error" v-if="confAlerts.length>0" style="margin-bottom: 10px;"
|
||||
message='{{ i18n "secAlertTitle" }}'
|
||||
color="red"
|
||||
show-icon closable>
|
||||
@@ -376,319 +376,325 @@
|
||||
{{template "component/password" .}}
|
||||
{{template "component/setting"}}
|
||||
<script>
|
||||
const app = new Vue({
|
||||
delimiters: ['[[', ']]'],
|
||||
el: '#app',
|
||||
data: {
|
||||
siderDrawer,
|
||||
themeSwitcher,
|
||||
spinning: false,
|
||||
changeSecret: false,
|
||||
oldAllSetting: new AllSetting(),
|
||||
allSetting: new AllSetting(),
|
||||
saveBtnDisable: true,
|
||||
user: {},
|
||||
lang: getLang(),
|
||||
remarkModels: {i:'Inbound',e:'Email',o:'Other'},
|
||||
remarkSeparators: [' ','-','_','@',':','~','|',',','.','/'],
|
||||
datepickerList: [{name:'Gregorian (Standard)', value: 'gregorian'}, {name:'Jalalian (شمسی)', value: 'jalalian'}],
|
||||
remarkSample: '',
|
||||
defaultFragment: {
|
||||
tag: "fragment",
|
||||
protocol: "freedom",
|
||||
settings: {
|
||||
domainStrategy: "AsIs",
|
||||
fragment: {
|
||||
packets: "tlshello",
|
||||
length: "100-200",
|
||||
interval: "10-20"
|
||||
}
|
||||
},
|
||||
streamSettings: {
|
||||
sockopt: {
|
||||
tcpKeepAliveIdle: 100,
|
||||
tcpNoDelay: true
|
||||
}
|
||||
}
|
||||
},
|
||||
defaultMux: {
|
||||
enabled: true,
|
||||
concurrency: 8,
|
||||
xudpConcurrency: 16,
|
||||
xudpProxyUDP443: "reject"
|
||||
},
|
||||
defaultRules: [
|
||||
{
|
||||
type: "field",
|
||||
outboundTag: "direct",
|
||||
domain: [
|
||||
"geosite:category-ir",
|
||||
"geosite:cn"
|
||||
],
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
type: "field",
|
||||
outboundTag: "direct",
|
||||
ip: [
|
||||
"geoip:private",
|
||||
"geoip:ir",
|
||||
"geoip:cn"
|
||||
],
|
||||
enabled: true
|
||||
},
|
||||
],
|
||||
countryOptions: [
|
||||
{ label: 'Private IP/Domain', value: 'private' },
|
||||
{ label: '🇮🇷 Iran', value: 'ir' },
|
||||
{ label: '🇨🇳 China', value: 'cn' },
|
||||
{ label: '🇷🇺 Russia', value: 'ru' },
|
||||
{ label: '🇻🇳 Vietnam', value: 'vn' },
|
||||
],
|
||||
get remarkModel() {
|
||||
rm = this.allSetting.remarkModel;
|
||||
return rm.length>1 ? rm.substring(1).split('') : [];
|
||||
},
|
||||
set remarkModel(value) {
|
||||
rs = this.allSetting.remarkModel[0];
|
||||
this.allSetting.remarkModel = rs + value.join('');
|
||||
this.changeRemarkSample();
|
||||
},
|
||||
get remarkSeparator() {
|
||||
return this.allSetting.remarkModel.length > 1 ? this.allSetting.remarkModel.charAt(0) : '-';
|
||||
},
|
||||
set remarkSeparator(value) {
|
||||
this.allSetting.remarkModel = value + this.allSetting.remarkModel.substring(1);
|
||||
this.changeRemarkSample();
|
||||
},
|
||||
get datepicker() {
|
||||
return this.allSetting.datepicker ? this.allSetting.datepicker : 'gregorian';
|
||||
},
|
||||
set datepicker(value) {
|
||||
this.allSetting.datepicker = value;
|
||||
},
|
||||
changeRemarkSample(){
|
||||
sample = []
|
||||
this.remarkModel.forEach(r => sample.push(this.remarkModels[r]));
|
||||
this.remarkSample = sample.length == 0 ? '' : sample.join(this.remarkSeparator);
|
||||
}
|
||||
const app = new Vue({
|
||||
delimiters: ['[[', ']]'],
|
||||
el: '#app',
|
||||
data: {
|
||||
siderDrawer,
|
||||
themeSwitcher,
|
||||
spinning: false,
|
||||
changeSecret: false,
|
||||
oldAllSetting: new AllSetting(),
|
||||
allSetting: new AllSetting(),
|
||||
saveBtnDisable: true,
|
||||
user: {},
|
||||
lang: getLang(),
|
||||
remarkModels: { i: 'Inbound', e: 'Email', o: 'Other' },
|
||||
remarkSeparators: [' ', '-', '_', '@', ':', '~', '|', ',', '.', '/'],
|
||||
datepickerList: [{ name: 'Gregorian (Standard)', value: 'gregorian' }, { name: 'Jalalian (شمسی)', value: 'jalalian' }],
|
||||
remarkSample: '',
|
||||
defaultFragment: {
|
||||
tag: "fragment",
|
||||
protocol: "freedom",
|
||||
settings: {
|
||||
domainStrategy: "AsIs",
|
||||
fragment: {
|
||||
packets: "tlshello",
|
||||
length: "100-200",
|
||||
interval: "10-20"
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
loading(spinning = true) {
|
||||
this.spinning = spinning;
|
||||
},
|
||||
async getAllSetting() {
|
||||
this.loading(true);
|
||||
const msg = await HttpUtil.post("/panel/setting/all");
|
||||
this.loading(false);
|
||||
if (msg.success) {
|
||||
this.oldAllSetting = new AllSetting(msg.obj);
|
||||
this.allSetting = new AllSetting(msg.obj);
|
||||
app.changeRemarkSample();
|
||||
this.saveBtnDisable = true;
|
||||
}
|
||||
await this.fetchUserSecret();
|
||||
},
|
||||
async updateAllSetting() {
|
||||
this.loading(true);
|
||||
const msg = await HttpUtil.post("/panel/setting/update", this.allSetting);
|
||||
this.loading(false);
|
||||
if (msg.success) {
|
||||
await this.getAllSetting();
|
||||
}
|
||||
},
|
||||
async updateUser() {
|
||||
this.loading(true);
|
||||
const msg = await HttpUtil.post("/panel/setting/updateUser", this.user);
|
||||
this.loading(false);
|
||||
if (msg.success) {
|
||||
this.user = {};
|
||||
}
|
||||
},
|
||||
async restartPanel() {
|
||||
await new Promise(resolve => {
|
||||
this.$confirm({
|
||||
title: '{{ i18n "pages.settings.restartPanel" }}',
|
||||
content: '{{ i18n "pages.settings.restartPanelDesc" }}',
|
||||
class: themeSwitcher.currentTheme,
|
||||
okText: '{{ i18n "sure" }}',
|
||||
cancelText: '{{ i18n "cancel" }}',
|
||||
onOk: () => resolve(),
|
||||
});
|
||||
});
|
||||
this.loading(true);
|
||||
const msg = await HttpUtil.post("/panel/setting/restartPanel");
|
||||
this.loading(false);
|
||||
if (msg.success) {
|
||||
this.loading(true);
|
||||
await PromiseUtil.sleep(5000);
|
||||
let { webCertFile, webKeyFile, webDomain: host, webPort: port, webBasePath: base } = this.allSetting;
|
||||
const isTLS = webCertFile !== "" || webKeyFile !== "";
|
||||
const url = buildURL({ host, port, isTLS, base, path: "panel/settings" });
|
||||
window.location.replace(url);
|
||||
}
|
||||
},
|
||||
async fetchUserSecret() {
|
||||
this.loading(true);
|
||||
const userMessage = await HttpUtil.post("/panel/setting/getUserSecret", this.user);
|
||||
if (userMessage.success) {
|
||||
this.user = userMessage.obj;
|
||||
}
|
||||
this.loading(false);
|
||||
},
|
||||
async updateSecret() {
|
||||
this.loading(true);
|
||||
const msg = await HttpUtil.post("/panel/setting/updateUserSecret", this.user);
|
||||
if (msg && msg.obj) {
|
||||
this.user = msg.obj;
|
||||
}
|
||||
this.loading(false);
|
||||
await this.updateAllSetting();
|
||||
},
|
||||
generateRandomString(length) {
|
||||
var chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890";
|
||||
let randomString = "";
|
||||
for (let i = 0; i < length; i++) {
|
||||
randomString += chars[Math.floor(Math.random() * chars.length)];
|
||||
}
|
||||
return randomString;
|
||||
},
|
||||
async getNewSecret() {
|
||||
if (!this.changeSecret) {
|
||||
this.changeSecret = true;
|
||||
this.user.loginSecret = '';
|
||||
const newSecret = this.generateRandomString(64);
|
||||
await PromiseUtil.sleep(1000);
|
||||
this.user.loginSecret = newSecret;
|
||||
this.changeSecret = false;
|
||||
}
|
||||
},
|
||||
async toggleToken(value) {
|
||||
if (value) {
|
||||
await this.getNewSecret();
|
||||
} else {
|
||||
this.user.loginSecret = "";
|
||||
}
|
||||
},
|
||||
},
|
||||
computed: {
|
||||
fragment: {
|
||||
get: function() { return this.allSetting?.subJsonFragment != ""; },
|
||||
set: function (v) {
|
||||
this.allSetting.subJsonFragment = v ? JSON.stringify(this.defaultFragment) : "";
|
||||
}
|
||||
},
|
||||
fragmentPackets: {
|
||||
get: function() { return this.fragment ? JSON.parse(this.allSetting.subJsonFragment).settings.fragment.packets : ""; },
|
||||
set: function(v) {
|
||||
if (v != ""){
|
||||
newFragment = JSON.parse(this.allSetting.subJsonFragment);
|
||||
newFragment.settings.fragment.packets = v;
|
||||
this.allSetting.subJsonFragment = JSON.stringify(newFragment);
|
||||
}
|
||||
}
|
||||
},
|
||||
fragmentLength: {
|
||||
get: function() { return this.fragment ? JSON.parse(this.allSetting.subJsonFragment).settings.fragment.length : ""; },
|
||||
set: function(v) {
|
||||
if (v != ""){
|
||||
newFragment = JSON.parse(this.allSetting.subJsonFragment);
|
||||
newFragment.settings.fragment.length = v;
|
||||
this.allSetting.subJsonFragment = JSON.stringify(newFragment);
|
||||
}
|
||||
}
|
||||
},
|
||||
fragmentInterval: {
|
||||
get: function() { return this.fragment ? JSON.parse(this.allSetting.subJsonFragment).settings.fragment.interval : ""; },
|
||||
set: function(v) {
|
||||
if (v != ""){
|
||||
newFragment = JSON.parse(this.allSetting.subJsonFragment);
|
||||
newFragment.settings.fragment.interval = v;
|
||||
this.allSetting.subJsonFragment = JSON.stringify(newFragment);
|
||||
}
|
||||
}
|
||||
},
|
||||
enableMux: {
|
||||
get: function() { return this.allSetting?.subJsonMux != ""; },
|
||||
set: function (v) {
|
||||
this.allSetting.subJsonMux = v ? JSON.stringify(this.defaultMux) : "";
|
||||
}
|
||||
},
|
||||
muxConcurrency: {
|
||||
get: function() { return this.enableMux ? JSON.parse(this.allSetting.subJsonMux).concurrency : -1; },
|
||||
set: function(v) {
|
||||
newMux = JSON.parse(this.allSetting.subJsonMux);
|
||||
newMux.concurrency = v;
|
||||
this.allSetting.subJsonMux = JSON.stringify(newMux);
|
||||
}
|
||||
},
|
||||
muxXudpConcurrency: {
|
||||
get: function() { return this.enableMux ? JSON.parse(this.allSetting.subJsonMux).xudpConcurrency : -1; },
|
||||
set: function(v) {
|
||||
newMux = JSON.parse(this.allSetting.subJsonMux);
|
||||
newMux.xudpConcurrency = v;
|
||||
this.allSetting.subJsonMux = JSON.stringify(newMux);
|
||||
}
|
||||
},
|
||||
muxXudpProxyUDP443: {
|
||||
get: function() { return this.enableMux ? JSON.parse(this.allSetting.subJsonMux).xudpProxyUDP443 : "reject"; },
|
||||
set: function(v) {
|
||||
newMux = JSON.parse(this.allSetting.subJsonMux);
|
||||
newMux.xudpProxyUDP443 = v;
|
||||
this.allSetting.subJsonMux = JSON.stringify(newMux);
|
||||
}
|
||||
},
|
||||
enableDirect: {
|
||||
get: function() { return this.allSetting?.subJsonRules != ""; },
|
||||
set: function (v) {
|
||||
this.allSetting.subJsonRules = v ? JSON.stringify(this.defaultRules) : "";
|
||||
}
|
||||
},
|
||||
directCountries: {
|
||||
get: function() {
|
||||
if (!this.enableDirect) return [];
|
||||
rules = JSON.parse(this.allSetting.subJsonRules);
|
||||
return Array.isArray(rules) ? rules[1].ip.map(d => d.replace("geoip:","")) : [];
|
||||
},
|
||||
set: function (v) {
|
||||
rules = JSON.parse(this.allSetting.subJsonRules);
|
||||
if (!Array.isArray(rules)) return;
|
||||
rules[0].domain = [];
|
||||
rules[1].ip = [];
|
||||
v.forEach(d => {
|
||||
category = ["cn","private"].includes(d) ? "" : "category-";
|
||||
rules[0].domain.push("geosite:"+category+d);
|
||||
rules[1].ip.push("geoip:"+d);
|
||||
});
|
||||
this.allSetting.subJsonRules = JSON.stringify(rules);
|
||||
}
|
||||
},
|
||||
confAlerts: {
|
||||
get: function() {
|
||||
if (!this.allSetting) return [];
|
||||
var alerts = []
|
||||
if (window.location.protocol !== "https:") alerts.push('{{ i18n "secAlertSSL" }}');
|
||||
if (this.allSetting.webPort == 54321) alerts.push('{{ i18n "secAlertPanelPort" }}');
|
||||
panelPath = window.location.pathname.split('/').length<4
|
||||
if (panelPath && this.allSetting.webBasePath == '/') alerts.push('{{ i18n "secAlertPanelURI" }}');
|
||||
if (this.allSetting.subEnable) {
|
||||
subPath = this.allSetting.subURI.length >0 ? new URL(this.allSetting.subURI).pathname : this.allSetting.subPath;
|
||||
if (subPath == '/sub/') alerts.push('{{ i18n "secAlertSubURI" }}');
|
||||
subJsonPath = this.allSetting.subJsonURI.length >0 ? new URL(this.allSetting.subJsonURI).pathname : this.allSetting.subJsonPath;
|
||||
if (subJsonPath == '/json/') alerts.push('{{ i18n "secAlertSubJsonURI" }}');
|
||||
}
|
||||
return alerts
|
||||
}
|
||||
}
|
||||
},
|
||||
async mounted() {
|
||||
await this.getAllSetting();
|
||||
while (true) {
|
||||
await PromiseUtil.sleep(1000);
|
||||
this.saveBtnDisable = this.oldAllSetting.equals(this.allSetting);
|
||||
}
|
||||
streamSettings: {
|
||||
sockopt: {
|
||||
tcpKeepAliveIdle: 100,
|
||||
tcpNoDelay: true
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
defaultMux: {
|
||||
enabled: true,
|
||||
concurrency: 8,
|
||||
xudpConcurrency: 16,
|
||||
xudpProxyUDP443: "reject"
|
||||
},
|
||||
defaultRules: [
|
||||
{
|
||||
type: "field",
|
||||
outboundTag: "direct",
|
||||
domain: [
|
||||
"geosite:category-ir",
|
||||
"geosite:cn"
|
||||
],
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
type: "field",
|
||||
outboundTag: "direct",
|
||||
ip: [
|
||||
"geoip:private",
|
||||
"geoip:ir",
|
||||
"geoip:cn"
|
||||
],
|
||||
enabled: true
|
||||
},
|
||||
],
|
||||
countryOptions: [
|
||||
{ label: 'Private IP/Domain', value: 'private' },
|
||||
{ label: '🇮🇷 Iran', value: 'ir' },
|
||||
{ label: '🇨🇳 China', value: 'cn' },
|
||||
{ label: '🇷🇺 Russia', value: 'ru' },
|
||||
],
|
||||
get remarkModel() {
|
||||
rm = this.allSetting.remarkModel;
|
||||
return rm.length > 1 ? rm.substring(1).split('') : [];
|
||||
},
|
||||
set remarkModel(value) {
|
||||
rs = this.allSetting.remarkModel[0];
|
||||
this.allSetting.remarkModel = rs + value.join('');
|
||||
this.changeRemarkSample();
|
||||
},
|
||||
get remarkSeparator() {
|
||||
return this.allSetting.remarkModel.length > 1 ? this.allSetting.remarkModel.charAt(0) : '-';
|
||||
},
|
||||
set remarkSeparator(value) {
|
||||
this.allSetting.remarkModel = value + this.allSetting.remarkModel.substring(1);
|
||||
this.changeRemarkSample();
|
||||
},
|
||||
get datepicker() {
|
||||
return this.allSetting.datepicker ? this.allSetting.datepicker : 'gregorian';
|
||||
},
|
||||
set datepicker(value) {
|
||||
this.allSetting.datepicker = value;
|
||||
},
|
||||
changeRemarkSample() {
|
||||
sample = []
|
||||
this.remarkModel.forEach(r => sample.push(this.remarkModels[r]));
|
||||
this.remarkSample = sample.length == 0 ? '' : sample.join(this.remarkSeparator);
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
loading(spinning = true) {
|
||||
this.spinning = spinning;
|
||||
},
|
||||
async getAllSetting() {
|
||||
this.loading(true);
|
||||
const msg = await HttpUtil.post("/panel/setting/all");
|
||||
this.loading(false);
|
||||
if (msg.success) {
|
||||
this.oldAllSetting = new AllSetting(msg.obj);
|
||||
this.allSetting = new AllSetting(msg.obj);
|
||||
app.changeRemarkSample();
|
||||
this.saveBtnDisable = true;
|
||||
}
|
||||
await this.fetchUserSecret();
|
||||
},
|
||||
async updateAllSetting() {
|
||||
this.loading(true);
|
||||
const msg = await HttpUtil.post("/panel/setting/update", this.allSetting);
|
||||
this.loading(false);
|
||||
if (msg.success) {
|
||||
await this.getAllSetting();
|
||||
}
|
||||
},
|
||||
async updateUser() {
|
||||
this.loading(true);
|
||||
const msg = await HttpUtil.post("/panel/setting/updateUser", this.user);
|
||||
this.loading(false);
|
||||
if (msg.success) {
|
||||
this.user = {};
|
||||
}
|
||||
},
|
||||
async restartPanel() {
|
||||
await new Promise(resolve => {
|
||||
this.$confirm({
|
||||
title: '{{ i18n "pages.settings.restartPanel" }}',
|
||||
content: '{{ i18n "pages.settings.restartPanelDesc" }}',
|
||||
class: themeSwitcher.currentTheme,
|
||||
okText: '{{ i18n "sure" }}',
|
||||
cancelText: '{{ i18n "cancel" }}',
|
||||
onOk: () => resolve(),
|
||||
});
|
||||
});
|
||||
this.loading(true);
|
||||
const msg = await HttpUtil.post("/panel/setting/restartPanel");
|
||||
this.loading(false);
|
||||
if (msg.success) {
|
||||
this.loading(true);
|
||||
await PromiseUtil.sleep(5000);
|
||||
let { webCertFile, webKeyFile, webDomain: host, webPort: port, webBasePath: base } = this.allSetting;
|
||||
const isTLS = webCertFile !== "" || webKeyFile !== "";
|
||||
const url = buildURL({ host, port, isTLS, base, path: "panel/settings" });
|
||||
window.location.replace(url);
|
||||
}
|
||||
},
|
||||
async fetchUserSecret() {
|
||||
this.loading(true);
|
||||
const userMessage = await HttpUtil.post("/panel/setting/getUserSecret", this.user);
|
||||
if (userMessage.success) {
|
||||
this.user = userMessage.obj;
|
||||
}
|
||||
this.loading(false);
|
||||
},
|
||||
async updateSecret() {
|
||||
this.loading(true);
|
||||
const msg = await HttpUtil.post("/panel/setting/updateUserSecret", this.user);
|
||||
if (msg && msg.obj) {
|
||||
this.user = msg.obj;
|
||||
}
|
||||
this.loading(false);
|
||||
await this.updateAllSetting();
|
||||
},
|
||||
generateRandomString(length) {
|
||||
var chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890";
|
||||
let randomString = "";
|
||||
for (let i = 0; i < length; i++) {
|
||||
randomString += chars[Math.floor(Math.random() * chars.length)];
|
||||
}
|
||||
return randomString;
|
||||
},
|
||||
async getNewSecret() {
|
||||
if (!this.changeSecret) {
|
||||
this.changeSecret = true;
|
||||
this.user.loginSecret = '';
|
||||
const newSecret = this.generateRandomString(64);
|
||||
await PromiseUtil.sleep(1000);
|
||||
this.user.loginSecret = newSecret;
|
||||
this.changeSecret = false;
|
||||
}
|
||||
},
|
||||
async toggleToken(value) {
|
||||
if (value) {
|
||||
await this.getNewSecret();
|
||||
} else {
|
||||
this.user.loginSecret = "";
|
||||
}
|
||||
},
|
||||
},
|
||||
computed: {
|
||||
fragment: {
|
||||
get: function () { return this.allSetting?.subJsonFragment != ""; },
|
||||
set: function (v) {
|
||||
this.allSetting.subJsonFragment = v ? JSON.stringify(this.defaultFragment) : "";
|
||||
}
|
||||
},
|
||||
fragmentPackets: {
|
||||
get: function () { return this.fragment ? JSON.parse(this.allSetting.subJsonFragment).settings.fragment.packets : ""; },
|
||||
set: function (v) {
|
||||
if (v != "") {
|
||||
newFragment = JSON.parse(this.allSetting.subJsonFragment);
|
||||
newFragment.settings.fragment.packets = v;
|
||||
this.allSetting.subJsonFragment = JSON.stringify(newFragment);
|
||||
}
|
||||
}
|
||||
},
|
||||
fragmentLength: {
|
||||
get: function () { return this.fragment ? JSON.parse(this.allSetting.subJsonFragment).settings.fragment.length : ""; },
|
||||
set: function (v) {
|
||||
if (v != "") {
|
||||
newFragment = JSON.parse(this.allSetting.subJsonFragment);
|
||||
newFragment.settings.fragment.length = v;
|
||||
this.allSetting.subJsonFragment = JSON.stringify(newFragment);
|
||||
}
|
||||
}
|
||||
},
|
||||
fragmentInterval: {
|
||||
get: function () { return this.fragment ? JSON.parse(this.allSetting.subJsonFragment).settings.fragment.interval : ""; },
|
||||
set: function (v) {
|
||||
if (v != "") {
|
||||
newFragment = JSON.parse(this.allSetting.subJsonFragment);
|
||||
newFragment.settings.fragment.interval = v;
|
||||
this.allSetting.subJsonFragment = JSON.stringify(newFragment);
|
||||
}
|
||||
}
|
||||
},
|
||||
enableMux: {
|
||||
get: function () { return this.allSetting?.subJsonMux != ""; },
|
||||
set: function (v) {
|
||||
this.allSetting.subJsonMux = v ? JSON.stringify(this.defaultMux) : "";
|
||||
}
|
||||
},
|
||||
muxConcurrency: {
|
||||
get: function () { return this.enableMux ? JSON.parse(this.allSetting.subJsonMux).concurrency : -1; },
|
||||
set: function (v) {
|
||||
newMux = JSON.parse(this.allSetting.subJsonMux);
|
||||
newMux.concurrency = v;
|
||||
this.allSetting.subJsonMux = JSON.stringify(newMux);
|
||||
}
|
||||
},
|
||||
muxXudpConcurrency: {
|
||||
get: function () { return this.enableMux ? JSON.parse(this.allSetting.subJsonMux).xudpConcurrency : -1; },
|
||||
set: function (v) {
|
||||
newMux = JSON.parse(this.allSetting.subJsonMux);
|
||||
newMux.xudpConcurrency = v;
|
||||
this.allSetting.subJsonMux = JSON.stringify(newMux);
|
||||
}
|
||||
},
|
||||
muxXudpProxyUDP443: {
|
||||
get: function () { return this.enableMux ? JSON.parse(this.allSetting.subJsonMux).xudpProxyUDP443 : "reject"; },
|
||||
set: function (v) {
|
||||
newMux = JSON.parse(this.allSetting.subJsonMux);
|
||||
newMux.xudpProxyUDP443 = v;
|
||||
this.allSetting.subJsonMux = JSON.stringify(newMux);
|
||||
}
|
||||
},
|
||||
enableDirect: {
|
||||
get: function () { return this.allSetting?.subJsonRules != ""; },
|
||||
set: function (v) {
|
||||
this.allSetting.subJsonRules = v ? JSON.stringify(this.defaultRules) : "";
|
||||
}
|
||||
},
|
||||
directCountries: {
|
||||
get: function () {
|
||||
if (!this.enableDirect) return [];
|
||||
rules = JSON.parse(this.allSetting.subJsonRules);
|
||||
return Array.isArray(rules) ? rules[1].ip.map(d => d.replace("geoip:", "")) : [];
|
||||
},
|
||||
set: function (v) {
|
||||
rules = JSON.parse(this.allSetting.subJsonRules);
|
||||
if (!Array.isArray(rules)) return;
|
||||
rules[0].domain = [];
|
||||
rules[1].ip = [];
|
||||
v.forEach(d => {
|
||||
let category = '';
|
||||
if (["cn", "private"].includes(d)) {
|
||||
category = "";
|
||||
} else if (d === 'ru') {
|
||||
category = "category-gov-";
|
||||
} else {
|
||||
category = "category-";
|
||||
}
|
||||
rules[0].domain.push("geosite:" + category + d);
|
||||
rules[1].ip.push("geoip:" + d);
|
||||
});
|
||||
this.allSetting.subJsonRules = JSON.stringify(rules);
|
||||
}
|
||||
},
|
||||
confAlerts: {
|
||||
get: function () {
|
||||
if (!this.allSetting) return [];
|
||||
var alerts = []
|
||||
if (window.location.protocol !== "https:") alerts.push('{{ i18n "secAlertSSL" }}');
|
||||
if (this.allSetting.webPort == 54321) alerts.push('{{ i18n "secAlertPanelPort" }}');
|
||||
panelPath = window.location.pathname.split('/').length < 4
|
||||
if (panelPath && this.allSetting.webBasePath == '/') alerts.push('{{ i18n "secAlertPanelURI" }}');
|
||||
if (this.allSetting.subEnable) {
|
||||
subPath = this.allSetting.subURI.length > 0 ? new URL(this.allSetting.subURI).pathname : this.allSetting.subPath;
|
||||
if (subPath == '/sub/') alerts.push('{{ i18n "secAlertSubURI" }}');
|
||||
subJsonPath = this.allSetting.subJsonURI.length > 0 ? new URL(this.allSetting.subJsonURI).pathname : this.allSetting.subJsonPath;
|
||||
if (subJsonPath == '/json/') alerts.push('{{ i18n "secAlertSubJsonURI" }}');
|
||||
}
|
||||
return alerts
|
||||
}
|
||||
}
|
||||
},
|
||||
async mounted() {
|
||||
await this.getAllSetting();
|
||||
while (true) {
|
||||
await PromiseUtil.sleep(1000);
|
||||
this.saveBtnDisable = this.oldAllSetting.equals(this.allSetting);
|
||||
}
|
||||
}
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -572,9 +572,9 @@
|
||||
<a-tab-pane key="tpl-dns" tab='DNS' style="padding-top: 20px;" force-render="true">
|
||||
<setting-list-item type="switch" title='{{ i18n "pages.xray.dns.enable" }}' desc='{{ i18n "pages.xray.dns.enableDesc" }}' v-model="enableDNS"></setting-list-item>
|
||||
<template v-if="enableDNS">
|
||||
<setting-list-item type="text" title='{{ i18n "pages.xray.dns.tag" }}' desc='{{ i18n "pages.xray.dns.tagDesc" }}' v-model="dnsTag"></setting-list-item>
|
||||
<a-list-item>
|
||||
<a-row style="padding: 20px">
|
||||
<setting-list-item style="padding: 10px 20px" type="text" title='{{ i18n "pages.xray.dns.tag" }}' desc='{{ i18n "pages.xray.dns.tagDesc" }}' v-model="dnsTag"></setting-list-item>
|
||||
<a-list-item style="padding: 10px 20px">
|
||||
<a-row>
|
||||
<a-col :lg="24" :xl="12">
|
||||
<a-list-item-meta title='{{ i18n "pages.xray.dns.strategy" }}' description='{{ i18n "pages.xray.dns.strategyDesc" }}' />
|
||||
</a-col>
|
||||
@@ -632,8 +632,7 @@
|
||||
<template slot="action" slot-scope="text,fakedns,index">
|
||||
[[ index+1 ]]
|
||||
<a-dropdown :trigger="['click']">
|
||||
<a-icon @click="e => e.preventDefault()" type="more"
|
||||
style="font-size: 16px; text-decoration: bold;"></a-icon>
|
||||
<a-icon @click="e => e.preventDefault()" type="more" style="font-size: 16px; text-decoration: bold;"></a-icon>
|
||||
<a-menu slot="overlay" :theme="themeSwitcher.currentTheme">
|
||||
<a-menu-item @click="editFakedns(index)">
|
||||
<a-icon type="edit"></a-icon>
|
||||
@@ -1101,7 +1100,7 @@
|
||||
serverObj = o.settings.servers;
|
||||
break;
|
||||
case Protocols.DNS:
|
||||
return [o.settings.address + ':' + o.settings.port];
|
||||
return [o.settings?.address + ':' + o.settings?.port];
|
||||
case Protocols.Wireguard:
|
||||
return o.settings.peers.map(peer => peer.endpoint);
|
||||
default:
|
||||
|
||||
@@ -21,8 +21,8 @@
|
||||
<a-select v-model="balancerModal.balancer.strategy" :dropdown-class-name="themeSwitcher.currentTheme">
|
||||
<a-select-option value="random">Random</a-select-option>
|
||||
<a-select-option value="roundRobin">Round Robin</a-select-option>
|
||||
<a-select-option value="leastload">Least Load</a-select-option>
|
||||
<a-select-option value="leastping">Least Ping</a-select-option>
|
||||
<a-select-option value="leastLoad">Least Load</a-select-option>
|
||||
<a-select-option value="leastPing">Least Ping</a-select-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
<a-form-item label='{{ i18n "pages.xray.balancer.balancerSelectors" }}' has-feedback
|
||||
|
||||
+15
-3
@@ -3,6 +3,7 @@ package service
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
@@ -1186,7 +1187,7 @@ func (s *InboundService) GetClientByEmail(clientEmail string) (*xray.ClientTraff
|
||||
return nil, nil, common.NewError("Client Not Found In Inbound For Email:", clientEmail)
|
||||
}
|
||||
|
||||
func (s *InboundService) SetClientTelegramUserID(trafficId int, tgId string) (bool, error) {
|
||||
func (s *InboundService) SetClientTelegramUserID(trafficId int, tgId int64) (bool, error) {
|
||||
traffic, inbound, err := s.GetClientInboundByTrafficID(trafficId)
|
||||
if err != nil {
|
||||
return false, err
|
||||
@@ -1687,10 +1688,10 @@ func (s *InboundService) DelDepletedClients(id int) (err error) {
|
||||
return err
|
||||
}
|
||||
|
||||
func (s *InboundService) GetClientTrafficTgBot(tgId string) ([]*xray.ClientTraffic, error) {
|
||||
func (s *InboundService) GetClientTrafficTgBot(tgId int64) ([]*xray.ClientTraffic, error) {
|
||||
db := database.GetDB()
|
||||
var inbounds []*model.Inbound
|
||||
err := db.Model(model.Inbound{}).Where("settings like ?", fmt.Sprintf(`%%"tgId": "%s"%%`, tgId)).Find(&inbounds).Error
|
||||
err := db.Model(model.Inbound{}).Where("settings like ?", fmt.Sprintf(`%%"tgId": %d%%`, tgId)).Find(&inbounds).Error
|
||||
if err != nil && err != gorm.ErrRecordNotFound {
|
||||
return nil, err
|
||||
}
|
||||
@@ -1838,6 +1839,17 @@ func (s *InboundService) MigrationRequirements() {
|
||||
c["email"] = ""
|
||||
}
|
||||
|
||||
// Convert string tgId to int64
|
||||
if _, ok := c["tgId"]; ok {
|
||||
var tgId interface{} = c["tgId"]
|
||||
if tgIdStr, ok2 := tgId.(string); ok2 {
|
||||
tgIdInt64, err := strconv.ParseInt(strings.ReplaceAll(tgIdStr, " ", ""), 10, 64)
|
||||
if err == nil {
|
||||
c["tgId"] = tgIdInt64
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Remove "flow": "xtls-rprx-direct"
|
||||
if _, ok := c["flow"]; ok {
|
||||
if c["flow"] == "xtls-rprx-direct" {
|
||||
|
||||
+41
-34
@@ -6,7 +6,6 @@ import (
|
||||
"net"
|
||||
"net/url"
|
||||
"os"
|
||||
"slices"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
@@ -39,8 +38,9 @@ var (
|
||||
type LoginStatus byte
|
||||
|
||||
const (
|
||||
LoginSuccess LoginStatus = 1
|
||||
LoginFail LoginStatus = 0
|
||||
LoginSuccess LoginStatus = 1
|
||||
LoginFail LoginStatus = 0
|
||||
EmptyTelegramUserID = int64(0)
|
||||
)
|
||||
|
||||
type Tgbot struct {
|
||||
@@ -207,21 +207,20 @@ func (t *Tgbot) OnReceive() {
|
||||
botHandler.HandleMessage(func(_ *telego.Bot, message telego.Message) {
|
||||
if message.UsersShared != nil {
|
||||
if checkAdmin(message.From.ID) {
|
||||
userIDsStr := ""
|
||||
for _, userID := range message.UsersShared.UserIDs {
|
||||
userIDsStr += strconv.FormatInt(userID, 10) + " "
|
||||
for _, sharedUser := range message.UsersShared.Users {
|
||||
userID := sharedUser.UserID
|
||||
needRestart, err := t.inboundService.SetClientTelegramUserID(message.UsersShared.RequestID, userID)
|
||||
if needRestart {
|
||||
t.xrayService.SetToNeedRestart()
|
||||
}
|
||||
output := ""
|
||||
if err != nil {
|
||||
output += t.I18nBot("tgbot.messages.selectUserFailed")
|
||||
} else {
|
||||
output += t.I18nBot("tgbot.messages.userSaved")
|
||||
}
|
||||
t.SendMsgToTgbot(message.Chat.ID, output, tu.ReplyKeyboardRemove())
|
||||
}
|
||||
needRestart, err := t.inboundService.SetClientTelegramUserID(message.UsersShared.RequestID, userIDsStr)
|
||||
if needRestart {
|
||||
t.xrayService.SetToNeedRestart()
|
||||
}
|
||||
output := ""
|
||||
if err != nil {
|
||||
output += t.I18nBot("tgbot.messages.selectUserFailed")
|
||||
} else {
|
||||
output += t.I18nBot("tgbot.messages.userSaved")
|
||||
}
|
||||
t.SendMsgToTgbot(message.Chat.ID, output, tu.ReplyKeyboardRemove())
|
||||
} else {
|
||||
t.SendMsgToTgbot(message.Chat.ID, t.I18nBot("tgbot.noResult"), tu.ReplyKeyboardRemove())
|
||||
}
|
||||
@@ -259,7 +258,9 @@ func (t *Tgbot) answerCommand(message *telego.Message, chatId int64, isAdmin boo
|
||||
if isAdmin {
|
||||
t.searchClient(chatId, commandArgs[0])
|
||||
} else {
|
||||
t.getClientUsage(chatId, strconv.FormatInt(message.From.ID, 10), commandArgs[0])
|
||||
// Convert message.From.ID to int64
|
||||
fromID := int64(message.From.ID)
|
||||
t.getClientUsage(chatId, fromID, commandArgs[0])
|
||||
}
|
||||
} else {
|
||||
msg += t.I18nBot("tgbot.commands.usage")
|
||||
@@ -726,7 +727,7 @@ func (t *Tgbot) asnwerCallback(callbackQuery *telego.CallbackQuery, isAdmin bool
|
||||
t.sendCallbackAnswerTgBot(callbackQuery.ID, t.I18nBot("tgbot.answers.errorOperation"))
|
||||
return
|
||||
}
|
||||
needRestart, err := t.inboundService.SetClientTelegramUserID(traffic.Id, "")
|
||||
needRestart, err := t.inboundService.SetClientTelegramUserID(traffic.Id, EmptyTelegramUserID)
|
||||
if needRestart {
|
||||
t.xrayService.SetToNeedRestart()
|
||||
}
|
||||
@@ -783,8 +784,9 @@ func (t *Tgbot) asnwerCallback(callbackQuery *telego.CallbackQuery, isAdmin bool
|
||||
t.sendCallbackAnswerTgBot(callbackQuery.ID, t.I18nBot("tgbot.buttons.getBanLogs"))
|
||||
t.sendBanLogs(chatId, true)
|
||||
case "client_traffic":
|
||||
tgUserID := callbackQuery.From.ID
|
||||
t.sendCallbackAnswerTgBot(callbackQuery.ID, t.I18nBot("tgbot.buttons.clientUsage"))
|
||||
t.getClientUsage(chatId, strconv.FormatInt(callbackQuery.From.ID, 10))
|
||||
t.getClientUsage(chatId, tgUserID)
|
||||
case "client_commands":
|
||||
t.sendCallbackAnswerTgBot(callbackQuery.ID, t.I18nBot("tgbot.buttons.commands"))
|
||||
t.SendMsgToTgbot(chatId, t.I18nBot("tgbot.commands.helpClientCommands"))
|
||||
@@ -1135,7 +1137,7 @@ func (t *Tgbot) clientInfoMsg(
|
||||
return output
|
||||
}
|
||||
|
||||
func (t *Tgbot) getClientUsage(chatId int64, tgUserID string, email ...string) {
|
||||
func (t *Tgbot) getClientUsage(chatId int64, tgUserID int64, email ...string) {
|
||||
traffics, err := t.inboundService.GetClientTrafficTgBot(tgUserID)
|
||||
if err != nil {
|
||||
logger.Warning(err)
|
||||
@@ -1145,7 +1147,7 @@ func (t *Tgbot) getClientUsage(chatId int64, tgUserID string, email ...string) {
|
||||
}
|
||||
|
||||
if len(traffics) == 0 {
|
||||
t.SendMsgToTgbot(chatId, t.I18nBot("tgbot.answers.askToAddUserId", "TgUserID=="+tgUserID))
|
||||
t.SendMsgToTgbot(chatId, t.I18nBot("tgbot.answers.askToAddUserId", "TgUserID=="+strconv.FormatInt(tgUserID, 10)))
|
||||
return
|
||||
}
|
||||
|
||||
@@ -1218,8 +1220,8 @@ func (t *Tgbot) clientTelegramUserInfo(chatId int64, email string, messageID ...
|
||||
return
|
||||
}
|
||||
tgId := "None"
|
||||
if len(client.TgID) > 0 {
|
||||
tgId = client.TgID
|
||||
if client.TgID != 0 {
|
||||
tgId = strconv.FormatInt(client.TgID, 10)
|
||||
}
|
||||
|
||||
output := ""
|
||||
@@ -1452,24 +1454,20 @@ func (t *Tgbot) notifyExhausted() {
|
||||
logger.Warning("Unable to load Inbounds", err)
|
||||
}
|
||||
|
||||
var chatIDsDone []string
|
||||
var chatIDsDone []int64
|
||||
for _, inbound := range inbounds {
|
||||
if inbound.Enable {
|
||||
if len(inbound.ClientStats) > 0 {
|
||||
clients, err := t.inboundService.GetClients(inbound)
|
||||
if err == nil {
|
||||
for _, client := range clients {
|
||||
if client.TgID != "" {
|
||||
chatID, err := strconv.ParseInt(client.TgID, 10, 64)
|
||||
if err != nil {
|
||||
logger.Warning("TgID is not a number: ", client.TgID)
|
||||
continue
|
||||
}
|
||||
if !slices.Contains(chatIDsDone, client.TgID) && !checkAdmin(chatID) {
|
||||
if client.TgID != 0 {
|
||||
chatID := client.TgID
|
||||
if !int64Contains(chatIDsDone, chatID) && !checkAdmin(chatID) {
|
||||
var disabledClients []xray.ClientTraffic
|
||||
var exhaustedClients []xray.ClientTraffic
|
||||
traffics, err := t.inboundService.GetClientTrafficTgBot(client.TgID)
|
||||
if err == nil && len(traffics) > 0 {
|
||||
if err == nil && len(traffics) > 0 {
|
||||
output := t.I18nBot("tgbot.messages.exhaustedCount", "Type=="+t.I18nBot("tgbot.clients"))
|
||||
for _, traffic := range traffics {
|
||||
if traffic.Enable {
|
||||
@@ -1498,7 +1496,7 @@ func (t *Tgbot) notifyExhausted() {
|
||||
}
|
||||
t.SendMsgToTgbot(chatID, output)
|
||||
}
|
||||
chatIDsDone = append(chatIDsDone, client.TgID)
|
||||
chatIDsDone = append(chatIDsDone, chatID)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1509,6 +1507,15 @@ func (t *Tgbot) notifyExhausted() {
|
||||
}
|
||||
}
|
||||
|
||||
func int64Contains(slice []int64, item int64) bool {
|
||||
for _, s := range slice {
|
||||
if s == item {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (t *Tgbot) onlineClients(chatId int64, messageID ...int) {
|
||||
if !p.IsRunning() {
|
||||
return
|
||||
|
||||
@@ -180,7 +180,7 @@
|
||||
"setDefaultCert" = "Set Cert from Panel"
|
||||
"xtlsDesc" = "Xray must be v1.7.5"
|
||||
"realityDesc" = "Xray must be v1.8.0+"
|
||||
"telegramDesc" = "Please provide Telegram or chat ID(s) without using the '@'. (get it here @userinfobot) or (use '/id' command in the bot)"
|
||||
"telegramDesc" = "Please provide Telegram Chat ID. (use '/id' command in the bot) or (@userinfobot)"
|
||||
"subscriptionDesc" = "To find your subscription URL, navigate to the 'Details'. Additionally, you can use the same name for several clients."
|
||||
"info" = "Info"
|
||||
"same" = "Same"
|
||||
@@ -536,8 +536,8 @@
|
||||
"status" = "✅ Bot is OK!"
|
||||
"usage" = "❗ Please provide a text to search!"
|
||||
"getID" = "🆔 Your ID: <code>{{ .ID }}</code>"
|
||||
"helpAdminCommands" = "To search for a client email:\r\n<code>/usage [Email]</code>\r\n\r\nTo search for inbounds (with client stats):\r\n<code>/inbound [Remark]</code>"
|
||||
"helpClientCommands" = "To search for statistics, use the following command:\r\n\r\n<code>/usage [Email]</code>"
|
||||
"helpAdminCommands" = "To search for a client email:\r\n<code>/usage [Email]</code>\r\n\r\nTo search for inbounds (with client stats):\r\n<code>/inbound [Remark]</code>\r\n\r\nTelegram Chat ID:\r\n<code>/id</code>"
|
||||
"helpClientCommands" = "To search for statistics, use the following command:\r\n\r\n<code>/usage [Email]</code>\r\n\r\nTelegram Chat ID:\r\n<code>/id</code>"
|
||||
|
||||
[tgbot.messages]
|
||||
"cpuThreshold" = "🔴 CPU Load {{ .Percent }}% exceeds the threshold of {{ .Threshold }}%"
|
||||
|
||||
@@ -180,7 +180,7 @@
|
||||
"setDefaultCert" = "Establecer certificado desde el panel"
|
||||
"xtlsDesc" = "La versión del núcleo de Xray debe ser 1.7.5"
|
||||
"realityDesc" = "La versión del núcleo de Xray debe ser 1.8.0 o superior."
|
||||
"telegramDesc" = "Utiliza únicamente IDs de chat (puedes obtenerlo aquí @userinfobot o usando el comando '/id' en el bot)."
|
||||
"telegramDesc" = "Por favor, proporciona el ID de Chat de Telegram. (usa el comando '/id' en el bot) o (@userinfobot)"
|
||||
"subscriptionDesc" = "Puedes encontrar tu enlace de suscripción en Detalles, también puedes usar el mismo nombre para varias configuraciones."
|
||||
"info" = "Info"
|
||||
"same" = "misma"
|
||||
@@ -534,8 +534,8 @@
|
||||
"status" = "✅ ¡El bot está bien!"
|
||||
"usage" = "❗ ¡Por favor proporciona un texto para buscar!"
|
||||
"getID" = "🆔 Tu ID: <code>{{ .ID }}</code>"
|
||||
"helpAdminCommands" = "Buscar un correo electrónico de cliente:\r\n<code>/usage [Email]</code>\r\n\r\nBuscar entradas (con estadísticas de cliente):\r\n<code>/inbound [Nota]</code>"
|
||||
"helpClientCommands" = "Para buscar estadísticas, simplemente usa el siguiente comando:\r\n\r\n<code>/usage [UUID|Contraseña]</code>"
|
||||
"helpAdminCommands" = "Para buscar un correo electrónico de cliente:\r\n<code>/usage [Correo electrónico]</code>\r\n\r\nPara buscar entradas (con estadísticas de cliente):\r\n<code>/inbound [Observación]</code>\r\n\r\nID de Chat de Telegram:\r\n<code>/id</code>"
|
||||
"helpClientCommands" = "Para buscar estadísticas, utiliza el siguiente comando:\r\n<code>/usage [Correo electrónico]</code>\r\n\r\nID de Chat de Telegram:\r\n<code>/id</code>"
|
||||
|
||||
[tgbot.messages]
|
||||
"cpuThreshold" = "🔴 El uso de CPU {{ .Percent }}% es mayor que el umbral {{ .Threshold }}%"
|
||||
|
||||
@@ -180,7 +180,7 @@
|
||||
"setDefaultCert" = "استفاده از گواهی پنل"
|
||||
"xtlsDesc" = "ایکسری باید 1.7.5 باشد"
|
||||
"realityDesc" = "ایکسری باید +1.8.0 باشد"
|
||||
"telegramDesc" = "دریافت کنید ('/id'یا (دستور (@userinfobot) آیدی(های) چت تلگرام مدیر، از"
|
||||
"telegramDesc" = "لطفا شناسه گفتگوی تلگرام را وارد کنید. (از دستور '/id' در ربات استفاده کنید) یا (@userinfobot)"
|
||||
"subscriptionDesc" = "شما میتوانید لینک سابسکربپشن خودرا در 'جزئیات' پیدا کنید، همچنین میتوانید از همین نام برای چندین کاربر استفادهکنید"
|
||||
"info" = "اطلاعات"
|
||||
"same" = "همسان"
|
||||
@@ -536,8 +536,8 @@
|
||||
"status" = "✅ ربات در حالت عادی است!"
|
||||
"usage" = "❗ لطفاً یک متن برای جستجو وارد کنید!"
|
||||
"getID" = "🆔 شناسه شما: <code>{{ .ID }}</code>"
|
||||
"helpAdminCommands" = "برای جستجوی ایمیل مشتری:\r\n<code>/usage [ایمیل]</code>\r\n\r\nبرای جستجوی ورودیها (با آمار مشتری):\r\n<code>/inbound [توضیح]</code>"
|
||||
"helpClientCommands" = "برای جستجوی آمار، فقط از دستور زیر استفاده کنید:\r\n\r\n<code>/usage [Email]</code>"
|
||||
"helpAdminCommands" = "برای جستجوی ایمیل مشتری:\r\n<code>/usage [ایمیل]</code>\r\n\r\nبرای جستجوی ورودیها (با آمار مشتری):\r\n<code>/inbound [توضیحات]</code>\r\n\r\nشناسه گفتگوی تلگرام:\r\n<code>/id</code>"
|
||||
"helpClientCommands" = "برای جستجوی آمار، از دستور زیر استفاده کنید:\r\n<code>/usage [ایمیل]</code>\r\n\r\nشناسه گفتگوی تلگرام:\r\n<code>/id</code>"
|
||||
|
||||
[tgbot.messages]
|
||||
"cpuThreshold" = "🔴 بار پردازنده {{ .Percent }}% بیشتر از آستانه است {{ .Threshold }}%"
|
||||
|
||||
@@ -180,7 +180,7 @@
|
||||
"setDefaultCert" = "Atur Sertifikat dari Panel"
|
||||
"xtlsDesc" = "Xray harus versi 1.7.5"
|
||||
"realityDesc" = "Xray harus versi 1.8.0+"
|
||||
"telegramDesc" = "Harap berikan ID Telegram atau obrolan tanpa menggunakan '@'. (dapatkan di sini @userinfobot) atau (gunakan perintah '/id' di bot)"
|
||||
"telegramDesc" = "Harap berikan ID Obrolan Telegram. (gunakan perintah '/id' di bot) atau (@userinfobot)"
|
||||
"subscriptionDesc" = "Untuk menemukan URL langganan Anda, buka 'Rincian'. Selain itu, Anda dapat menggunakan nama yang sama untuk beberapa klien."
|
||||
"info" = "Info"
|
||||
"same" = "Sama"
|
||||
@@ -536,8 +536,8 @@
|
||||
"status" = "✅ Bot dalam keadaan baik!"
|
||||
"usage" = "❗ Harap berikan teks untuk mencari!"
|
||||
"getID" = "🆔 ID Anda:<code>{{.ID }}</code>"
|
||||
"helpAdminCommands" = "Untuk mencari email klien:\r\n<code>/usage [Email]</code>\r\n\r\nUntuk mencari masuk (dengan statistik klien):\r\n<code>/inbound [Remark]</code>"
|
||||
"helpClientCommands" = "Untuk mencari statistik, gunakan perintah berikut:\r\n\r\n<code>/usage [Email]</code>"
|
||||
"helpAdminCommands" = "Untuk mencari email klien:\r\n<code>/usage [Email]</code>\r\n\r\nUntuk mencari inbound (dengan statistik klien):\r\n<code>/inbound [Catatan]</code>\r\n\r\nID Obrolan Telegram:\r\n<code>/id</code>"
|
||||
"helpClientCommands" = "Untuk mencari statistik, gunakan perintah berikut:\r\n<code>/usage [Email]</code>\r\n\r\nID Obrolan Telegram:\r\n<code>/id</code>"
|
||||
|
||||
[tgbot.messages]
|
||||
"cpuThreshold" = "🔴 Beban CPU {{ .Percent }}% melebihi batas {{ .Threshold }}%"
|
||||
|
||||
@@ -180,7 +180,7 @@
|
||||
"setDefaultCert" = "Установить сертификат с панели"
|
||||
"xtlsDesc" = "Версия Xray должна быть не ниже 1.7.5"
|
||||
"realityDesc" = "Версия Xray должна быть не ниже 1.8.0"
|
||||
"telegramDesc" = "Используйте только ID чата (можно получить его здесь @userinfobot или использовать команду '/id' в боте)"
|
||||
"telegramDesc" = "Пожалуйста, укажите ID чата Telegram. (используйте команду '/id' в боте) или (@userinfobot)"
|
||||
"subscriptionDesc" = "Вы можете найти свою ссылку подписки в разделе 'Подробнее', также вы можете использовать одно и то же имя для нескольких конфигураций"
|
||||
"info" = "Информация"
|
||||
"same" = "Тот же"
|
||||
@@ -536,8 +536,8 @@
|
||||
"status" = "✅ Бот работает нормально!"
|
||||
"usage" = "❗ Пожалуйста, укажите текст для поиска!"
|
||||
"getID" = "🆔 Ваш ID: <code>{{ .ID }}</code>"
|
||||
"helpAdminCommands" = "Поиск по электронной почте клиента:\r\n<code>/usage [Email]</code>\r\n\r\nПоиск входящих соединений (со статистикой клиента):\r\n<code>/inbound [Remark]</code>"
|
||||
"helpClientCommands" = "Для получения статистики используйте следующую команду:\r\n\r\n<code>/usage [Email]</code>"
|
||||
"helpAdminCommands" = "Для поиска электронной почты клиента:\r\n<code>/usage [Email]</code>\r\n\r\nДля поиска входящих (со статистикой клиента):\r\n<code>/inbound [Примечание]</code>\r\n\r\nID чата Telegram:\r\n<code>/id</code>"
|
||||
"helpClientCommands" = "Для поиска статистики используйте следующую команду:\r\n<code>/usage [Email]</code>\r\n\r\nID чата Telegram:\r\n<code>/id</code>"
|
||||
|
||||
[tgbot.messages]
|
||||
"cpuThreshold" = "🔴 Загрузка процессора составляет {{ .Percent }}%, что превышает пороговое значение {{ .Threshold }}%"
|
||||
|
||||
@@ -180,7 +180,7 @@
|
||||
"setDefaultCert" = "Установити сертифікат з панелі"
|
||||
"xtlsDesc" = "Xray має бути v1.7.5"
|
||||
"realityDesc" = "Xray має бути v1.8.0+"
|
||||
"telegramDesc" = "Будь ласка, надайте ідентифікатори Telegram або чату без використання '@'. (отримайте його тут @userinfobot) або (використайте команду '/id' у боті)"
|
||||
"telegramDesc" = "Будь ласка, вкажіть ID чату Telegram. (використовуйте команду '/id' у боті) або (@userinfobot)"
|
||||
"subscriptionDesc" = "Щоб знайти URL-адресу вашої підписки, перейдіть до «Деталі». Крім того, ви можете використовувати одне ім'я для кількох клієнтів."
|
||||
"info" = "Інформація"
|
||||
"same" = "Те саме"
|
||||
@@ -536,8 +536,8 @@
|
||||
"status" = "✅ Бот в порядку!"
|
||||
"usage" = "❗ Введіть текст для пошуку!"
|
||||
"getID" = "🆔 Ваш ідентифікатор: <code>{{ .ID }}</code>"
|
||||
"helpAdminCommands" = "Для пошуку електронної пошти клієнта:\r\n<code>/usage [Email]</code>\r\n\r\nДля пошуку вхідних листів (зі статистикою клієнта):\r\n<code>/inbound [Примітка]</code>"
|
||||
"helpClientCommands" = "Для пошуку статистики скористайтеся такою командою:\r\n\r\n<code>/usage [Email]</code>"
|
||||
"helpAdminCommands" = "Для пошуку електронної пошти клієнта:\r\n<code>/usage [Електронна пошта]</code>\r\n\r\nДля пошуку вхідних (зі статистикою клієнта):\r\n<code>/inbound [Примітка]</code>\r\n\r\nID чату Telegram:\r\n<code>/id</code>"
|
||||
"helpClientCommands" = "Для пошуку статистики використовуйте наступну команду:\r\n<code>/usage [Електронна пошта]</code>\r\n\r\nID чату Telegram:\r\n<code>/id</code>"
|
||||
|
||||
[tgbot.messages]
|
||||
"cpuThreshold" = "🔴 Навантаження ЦП {{ .Percent }}% перевищує порогове значення {{ .Threshold }}%"
|
||||
|
||||
@@ -180,7 +180,7 @@
|
||||
"setDefaultCert" = "Đặt chứng chỉ từ bảng điều khiển"
|
||||
"xtlsDesc" = "Xray core cần phiên bản 1.7.5"
|
||||
"realityDesc" = "Xray core cần phiên bản 1.8.0 hoặc cao hơn."
|
||||
"telegramDesc" = "Chỉ sử dụng ID trò chuyện (bạn có thể nhận được nó ở đây @userinfobot hoặc sử dụng lệnh '/id' trong bot)"
|
||||
"telegramDesc" = "Vui lòng cung cấp ID Trò chuyện Telegram. (sử dụng lệnh '/id' trong bot) hoặc (@userinfobot)"
|
||||
"subscriptionDesc" = "Bạn có thể tìm liên kết gói đăng ký của mình trong Chi tiết, cũng như bạn có thể sử dụng cùng tên cho nhiều cấu hình khác nhau"
|
||||
"info" = "Thông tin"
|
||||
"same" = "Giống nhau"
|
||||
@@ -536,8 +536,8 @@
|
||||
"status" = "✅ Bot hoạt động bình thường!"
|
||||
"usage" = "❗ Vui lòng cung cấp văn bản để tìm kiếm!"
|
||||
"getID" = "🆔 ID của bạn: <code>{{ .ID }}</code>"
|
||||
"helpAdminCommands" = "Tìm kiếm email của khách hàng:\r\n<code>/usage [Email]</code>\r\n\r\nTìm kiếm inbounds (với thống kê của khách hàng):\r\n<code>/inbound [Ghi chú]</code>"
|
||||
"helpClientCommands" = "Để tìm kiếm thống kê, hãy sử dụng lệnh sau:\r\n\r\n<code>/usage [Email]</code>"
|
||||
"helpAdminCommands" = "Để tìm kiếm email của khách hàng:\r\n<code>/usage [Email]</code>\r\n\r\nĐể tìm kiếm các nhập (với số liệu thống kê của khách hàng):\r\n<code>/inbound [Ghi chú]</code>\r\n\r\nID Trò chuyện Telegram:\r\n<code>/id</code>"
|
||||
"helpClientCommands" = "Để tìm kiếm thống kê, sử dụng lệnh sau:\r\n<code>/usage [Email]</code>\r\n\r\nID Trò chuyện Telegram:\r\n<code>/id</code>"
|
||||
|
||||
[tgbot.messages]
|
||||
"cpuThreshold" = "🔴 Sử dụng CPU {{ .Percent }}% vượt quá ngưỡng {{ .Threshold }}%"
|
||||
|
||||
@@ -180,7 +180,7 @@
|
||||
"setDefaultCert" = "从面板设置证书"
|
||||
"xtlsDesc" = "Xray 核心需要 1.7.5"
|
||||
"realityDesc" = "Xray 核心需要 1.8.0 及以上版本"
|
||||
"telegramDesc" = "请输入电报 (Telegram) 或聊天 ID,无需添加 '@' 符号。(可通过 @userinfobot 获取,或在机器人中使用 '/id' 命令)"
|
||||
"telegramDesc" = "请提供Telegram聊天ID。(在机器人中使用'/id'命令)或(@userinfobot"
|
||||
"subscriptionDesc" = "要找到你的订阅 URL,请导航到“详细信息”。此外,你可以为多个客户端使用相同的名称。"
|
||||
"info" = "信息"
|
||||
"same" = "相同"
|
||||
@@ -536,8 +536,8 @@
|
||||
"status" = "✅ 机器人正常运行!"
|
||||
"usage" = "❗ 请输入要搜索的文本!"
|
||||
"getID" = "🆔 您的 ID 为:<code>{{ .ID }}</code>"
|
||||
"helpAdminCommands" = "搜索客户端邮箱:\r\n<code>/usage [Email]</code>\r\n\r\n搜索入站连接(包含客户端统计信息):\r\n<code>/inbound [Remark]</code>"
|
||||
"helpClientCommands" = "要搜索统计信息,请使用以下命令:\r\n\r\n<code>/usage [Email]</code>"
|
||||
"helpAdminCommands" = "要搜索客户电子邮件:\r\n<code>/usage [电子邮件]</code>\r\n\r\n要搜索入站(带有客户统计数据):\r\n<code>/inbound [备注]</code>\r\n\r\nTelegram聊天ID:\r\n<code>/id</code>"
|
||||
"helpClientCommands" = "要搜索统计数据,请使用以下命令:\r\n<code>/usage [电子邮件]</code>\r\n\r\nTelegram聊天ID:\r\n<code>/id</code>"
|
||||
|
||||
[tgbot.messages]
|
||||
"cpuThreshold" = "🔴 CPU 使用率为 {{ .Percent }}%,超过阈值 {{ .Threshold }}%"
|
||||
|
||||
@@ -422,7 +422,7 @@ enable_bbr() {
|
||||
fedora)
|
||||
dnf -y update && dnf -y install ca-certificates
|
||||
;;
|
||||
arch | manjaro)
|
||||
arch | manjaro | parch)
|
||||
pacman -Sy --noconfirm ca-certificates
|
||||
;;
|
||||
*)
|
||||
@@ -749,7 +749,7 @@ ssl_cert_issue() {
|
||||
fedora)
|
||||
dnf -y update && dnf -y install socat
|
||||
;;
|
||||
arch | manjaro)
|
||||
arch | manjaro | parch)
|
||||
pacman -Sy --noconfirm socat
|
||||
;;
|
||||
*)
|
||||
@@ -1117,7 +1117,7 @@ install_iplimit() {
|
||||
fedora)
|
||||
dnf -y update && dnf -y install fail2ban
|
||||
;;
|
||||
arch | manjaro)
|
||||
arch | manjaro | parch)
|
||||
pacman -Syu --noconfirm fail2ban
|
||||
;;
|
||||
*)
|
||||
@@ -1199,7 +1199,7 @@ remove_iplimit() {
|
||||
dnf remove fail2ban -y
|
||||
dnf autoremove -y
|
||||
;;
|
||||
arch | manjaro)
|
||||
arch | manjaro | parch)
|
||||
pacman -Rns --noconfirm fail2ban
|
||||
;;
|
||||
*)
|
||||
|
||||
Reference in New Issue
Block a user