├── .gitignore ├── .travis.yml ├── Makefile ├── README.md ├── controller ├── common.go ├── delete.go ├── download.go ├── files.go ├── move.go ├── preview.go ├── rename.go └── upload.go ├── example ├── admin.db ├── book │ ├── fiction │ │ └── a.txt │ ├── funny │ │ ├── a.txt │ │ └── dir_dir1 │ │ │ └── a.txt │ ├── robot.gif │ ├── suspense │ │ └── a.txt │ └── tech │ │ ├── a.txt │ │ └── dir_dir1 │ │ └── a.txt ├── code │ └── golang │ │ ├── a.txt │ │ └── main.go ├── go.mod ├── go.sum ├── main.go └── picture │ ├── animal │ └── cat │ │ └── 111.jpeg │ └── landscape │ └── a.txt ├── filemanager.go ├── go.mod ├── go.sum ├── guard ├── delete.go ├── files.go ├── guard.go ├── move.go ├── preview.go ├── rename.go └── upload.go ├── installation.go ├── models └── file.go ├── modules ├── constant │ └── constant.go ├── error │ └── error.go ├── language │ ├── cn.go │ ├── en.go │ └── language.go ├── permission │ └── permission.go ├── root │ └── root.go └── util │ └── util.go ├── previewer ├── code.go ├── image.go ├── pdf.go └── previewer.go ├── router.go └── tests ├── admin.db └── common_test.go /.gitignore: -------------------------------------------------------------------------------- 1 | .idea 2 | DS_Store -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: go 2 | sudo: true 3 | 4 | go: 5 | - 1.13.x 6 | 7 | env: 8 | - GO111MODULE=on PGPASSWORD=root GOPROXY=https://goproxy.io,https://goproxy.cn,direct 9 | 10 | addons: 11 | chrome: stable 12 | apt: 13 | packages: 14 | - chromium-chromedriver 15 | 16 | services: 17 | - mysql 18 | - postgresql 19 | - docker 20 | 21 | before_install: 22 | - mysql -e 'create database `go-admin-test`;' 23 | - createdb -U postgres go-admin-test 24 | 25 | before_script: 26 | - ln --symbolic /usr/lib/chromium-browser/chromedriver "${HOME}/bin/chromedriver" 27 | - google-chrome-stable --headless --disable-gpu --remote-debugging-port=9222 http://localhost & 28 | - echo "USE mysql;\nUPDATE user SET authentication_string=PASSWORD('root') WHERE user='root';\nFLUSH PRIVILEGES;\n" | mysql -u root 29 | - psql -c "ALTER USER postgres WITH PASSWORD 'root';" -U postgres 30 | - go get -u github.com/rakyll/gotest 31 | - go get -u -v github.com/gogf/gf@v1.12.1 32 | - sudo chmod -R 777 $GOPATH/pkg/mod/github.com/gogf/gf@v1.12.1/net/ghttp/ghttp_server_handler.go 33 | - sudo echo -e "\nfunc (s *Server) DefaultHttpHandle(w http.ResponseWriter, r *http.Request) { \n s.handleRequest(w, r) \n}\n" >> $GOPATH/pkg/mod/github.com/gogf/gf@v1.12.1/net/ghttp/ghttp_server_handler.go 34 | - docker run -e "ACCEPT_EULA=Y" -e "SA_PASSWORD=Aa123456" -v /home/travis/gopath/src/github.com/GoAdminGroup/go-admin/tests/data:/home/data -p 1433:1433 --name mssql -d mcr.microsoft.com/mssql/server:2017-latest 35 | - cd /home/travis/gopath/src/github.com/GoAdminGroup/go-admin && go get github.com/GoAdminGroup/themes@master 36 | 37 | script: 38 | - chromedriver --version 39 | - cd /home/travis/gopath/src/github.com/GoAdminGroup/go-admin && make test -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | GOCMD = go 2 | 3 | all: fmt 4 | 5 | fmt: 6 | GO111MODULE=off go fmt ./... 7 | GO111MODULE=off goimports -l -w . 8 | 9 | test: 10 | gotest -v ./tests -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # File Manager 2 | 3 | A GoAdmin plugin which help you build a file cloud disk. 4 | 5 | ![](http://quick.go-admin.cn/docs/filemanager_interface_2.png) 6 | 7 | ## How To 8 | 9 | An example: 10 | 11 | ``` 12 | cd example 13 | GO111MODULE=on go run main.go 14 | ``` 15 | 16 | login and then visit: [http://localhost:9033/admin/fm/def/list](http://localhost:9033/admin/fm/def/list) 17 | 18 | ## TODO 19 | 20 | - [ ] Customize previewer / 自定义previewer 21 | - [ ] Get permanent/temporary link / 获取永久/临时连接 22 | - [ ] Add shortcuts / 键盘快捷键 23 | - [ ] Check weather override / 检查是否覆盖 24 | - [ ] File encryption / 文件加密 25 | - [ ] Cloud deployment processes / 云部署流程 26 | - [ ] Operation rbac permission check / rbac权限判断 27 | - [ ] Support oss/qiniu/..., make a local driver / 支持oss/七牛等 28 | - [ ] CLI / cli工具 29 | - [ ] New Name: diskgo/diskcool(盘古)/magnego(万磁王) -------------------------------------------------------------------------------- /controller/common.go: -------------------------------------------------------------------------------- 1 | package controller 2 | 3 | import ( 4 | template2 "html/template" 5 | "net/url" 6 | "path/filepath" 7 | "strings" 8 | "time" 9 | 10 | "github.com/GoAdminGroup/filemanager/models" 11 | "github.com/GoAdminGroup/filemanager/modules/constant" 12 | "github.com/GoAdminGroup/filemanager/modules/language" 13 | "github.com/GoAdminGroup/filemanager/modules/permission" 14 | "github.com/GoAdminGroup/filemanager/modules/root" 15 | "github.com/GoAdminGroup/filemanager/modules/util" 16 | "github.com/GoAdminGroup/go-admin/context" 17 | "github.com/GoAdminGroup/go-admin/modules/config" 18 | "github.com/GoAdminGroup/go-admin/plugins/admin/modules/paginator" 19 | "github.com/GoAdminGroup/go-admin/plugins/admin/modules/parameter" 20 | "github.com/GoAdminGroup/go-admin/template" 21 | "github.com/GoAdminGroup/go-admin/template/icon" 22 | "github.com/GoAdminGroup/go-admin/template/types" 23 | "github.com/GoAdminGroup/go-admin/template/types/action" 24 | "github.com/GoAdminGroup/html" 25 | ) 26 | 27 | type Handler struct { 28 | roots root.Roots 29 | permissions permission.Permission 30 | 31 | HTML func(ctx *context.Context, panel types.Panel, options ...template.ExecuteOptions) 32 | } 33 | 34 | func NewHandler(root root.Roots, p permission.Permission) *Handler { 35 | return &Handler{ 36 | roots: root, 37 | permissions: p, 38 | } 39 | } 40 | 41 | func (h *Handler) Update(root root.Roots, p permission.Permission) { 42 | h.roots = root 43 | h.permissions = p 44 | } 45 | 46 | func (h *Handler) Prefix(ctx *context.Context) string { 47 | prefix := ctx.Query(constant.PrefixKey) 48 | if prefix == "" { 49 | return "def" 50 | } 51 | return prefix 52 | } 53 | 54 | func (h *Handler) preview(ctx *context.Context, content template2.HTML, relativePath, path string, err error) { 55 | 56 | comp := template.Default() 57 | 58 | alert := template.HTML("") 59 | if err != nil { 60 | alert = comp.Alert().Warning(err.Error()) 61 | } 62 | 63 | isSubDir := relativePath != "" && err == nil 64 | lastDir := "" 65 | if isSubDir { 66 | dir := filepath.Dir(relativePath) 67 | if dir != "." && dir != "/" { 68 | lastDir = filepath.ToSlash(dir) 69 | } 70 | } 71 | 72 | btns := make(types.Buttons, 0) 73 | prefix := h.Prefix(ctx) 74 | 75 | if isSubDir { 76 | homeBtn := types.GetDefaultButtonGroup(language.GetHTML("home"), icon.Home, action.Jump(GetUrl(prefix, "/list"))) 77 | btns = append(btns, homeBtn) 78 | if lastDir != "" { 79 | lastBtn := types.GetDefaultButtonGroup(language.GetHTML("last"), icon.Backward, action.Jump(GetUrl(prefix, "/list?path="+url.QueryEscape(lastDir)))) 80 | btns = append(btns, lastBtn) 81 | } 82 | } 83 | 84 | btnHTML, _ := btns.Content(ctx) 85 | 86 | table := comp.DataTable(). 87 | SetHideRowSelector(true). 88 | SetButtons(btnHTML + btns.FooterContent(ctx)) 89 | 90 | h.HTML(ctx, types.Panel{ 91 | Content: alert + comp.Box(). 92 | SetBody(content). 93 | SetHeader(table.GetDataTableHeader()). 94 | SetNoPadding(). 95 | WithHeadBorder(). 96 | GetContent(), 97 | Title: language.GetHTML(h.roots.GetTitleFromPrefix(ctx)), 98 | Description: fixedDescription(relativePath), 99 | }, template.ExecuteOptions{ 100 | Animation: false, 101 | NoCompress: true, 102 | }) 103 | } 104 | 105 | func fixedDescription(des string) template2.HTML { 106 | return html.SpanEl().SetAttr("title", des).SetContent(template2.HTML(des)).Get() 107 | } 108 | 109 | func (h *Handler) table(ctx *context.Context, files models.Files, err error) { 110 | h.HTML(ctx, h.tablePanel(ctx, files, err)) 111 | } 112 | 113 | func link(u string, c template2.HTML, pjax bool) template2.HTML { 114 | if pjax { 115 | return template.Default().Link().SetURL(u).SetContent(c).GetContent() 116 | } 117 | return template.Default().Link().NoPjax().SetURL(u).SetContent(c).GetContent() 118 | } 119 | 120 | func linkWithAttr(class, c template2.HTML, pjax bool, attr template2.HTMLAttr) template2.HTML { 121 | if pjax { 122 | return template.Default().Link().SetClass(class).SetAttributes(attr).SetContent(c).GetContent() 123 | } 124 | return template.Default().Link().NoPjax().SetClass(class).SetAttributes(attr).SetContent(c).GetContent() 125 | } 126 | 127 | func (h *Handler) hasOperation() bool { 128 | return h.permissions.HasOperation() 129 | } 130 | 131 | func GetUrl(prefix string, suffix string) string { 132 | return config.Url("/fm/" + prefix + suffix) 133 | } 134 | 135 | func (h *Handler) tablePanel(ctx *context.Context, files models.Files, err error) types.Panel { 136 | comp := template.Default() 137 | path, _ := url.QueryUnescape(ctx.Query("path")) 138 | defaultPageSize := 10 139 | param := parameter.GetParam(ctx.Request.URL, defaultPageSize) 140 | total := len(files) 141 | prefix := h.Prefix(ctx) 142 | 143 | if len(files) > param.PageSizeInt { 144 | if len(files) > param.PageSizeInt*param.PageInt { 145 | files = files[param.PageSizeInt*(param.PageInt-1) : param.PageSizeInt*param.PageInt] 146 | } else { 147 | files = files[param.PageSizeInt*(param.PageInt-1):] 148 | } 149 | } 150 | 151 | length := len(files) 152 | 153 | isSubDir := path != "" && err == nil 154 | lastDir := "" 155 | if isSubDir { 156 | length++ 157 | dir := filepath.Dir(path) 158 | if dir != "." && dir != "/" { 159 | length++ 160 | lastDir = filepath.ToSlash(dir) 161 | } 162 | } 163 | if path == "" { 164 | path = "." 165 | } 166 | list := make([]map[string]types.InfoItem, length) 167 | 168 | name := template2.HTML("") 169 | op := template2.HTML("") 170 | 171 | var ( 172 | movePopUp = new(action.PopUpAction) 173 | movePopUpJs = template2.JS("") 174 | moveFooter = template2.HTML("") 175 | 176 | renamePopUp = new(action.PopUpAction) 177 | renamePopUpJs = template2.JS("") 178 | renameFooter = template2.HTML("") 179 | ) 180 | 181 | if h.permissions.AllowMove && len(files) > 0 { 182 | movePopUp = action.PopUp("_", language.Get("move"), nil). 183 | SetBtnTitle(language.GetHTML("move")). 184 | SetUrl(GetUrl(prefix, "/move/popup?path="+ctx.Query("path"))) 185 | movePopUp.SetBtnId("fm-move-btn") 186 | movePopUpJs = movePopUp.Js() 187 | moveFooter = movePopUp.FooterContent(ctx) 188 | 189 | renamePopUp = action.PopUp("_", language.Get("rename"), nil). 190 | SetBtnTitle(language.GetHTML("rename")). 191 | SetUrl(GetUrl(prefix, "/rename/popup?path="+ctx.Query("path"))) 192 | renamePopUp.SetBtnId("fm-rename-btn") 193 | renamePopUpJs = renamePopUp.Js() 194 | renameFooter = renamePopUp.FooterContent(ctx) 195 | } 196 | 197 | for k, f := range files { 198 | f.Path = filepath.ToSlash(f.Path) 199 | if f.Path[0] != '/' { 200 | f.Path = "/" + f.Path 201 | } 202 | 203 | if f.IsDirectory { 204 | name = icon.Icon(icon.FolderO, 2) + link(GetUrl(prefix, "/list?path="+url.QueryEscape(f.Path)), template2.HTML(f.Name), true) 205 | } else { 206 | name = icon.Icon(icon.File, 2) + link(GetUrl(prefix, "/preview?path="+url.QueryEscape(f.Path)), template2.HTML(f.Name), true) 207 | } 208 | 209 | list[k] = map[string]types.InfoItem{ 210 | "name": {Content: name}, 211 | "size": {Content: template.HTML(util.ByteCountIEC(f.Size))}, 212 | "modify_time": {Content: template.HTML(time.Unix(f.LastModified, 0).Format("2006-01-02 15:04:05"))}, 213 | "path": {Content: template.HTML(f.Path)}, 214 | } 215 | 216 | if h.hasOperation() { 217 | 218 | sep := template2.HTML(" | ") 219 | 220 | del := template.HTML("") 221 | if h.permissions.AllowDelete { 222 | del = sep + linkWithAttr("grid-row-delete", language.GetHTML("delete"), false, template2.HTMLAttr("data-id="+f.Path)) + sep 223 | } 224 | move := template.HTML("") 225 | if h.permissions.AllowMove { 226 | move = sep + linkWithAttr("fm-move-btn", language.GetHTML("move"), false, 227 | template2.HTMLAttr(`data-toggle="modal" data-target="#`+movePopUp.Id+`" data-id="`+f.Path+`"`)) + sep 228 | } 229 | download := template.HTML("") 230 | if h.permissions.AllowDownload { 231 | download = sep + link(GetUrl(prefix, "/download?path="+url.QueryEscape(f.Path)), template.HTML(language.Get("download")), false) + sep 232 | } 233 | rename := template.HTML("") 234 | if h.permissions.AllowRename { 235 | rename = sep + linkWithAttr("fm-rename-btn", language.GetHTML("rename"), false, 236 | template2.HTMLAttr(`data-toggle="modal" data-target="#`+renamePopUp.Id+`" data-id="`+f.Path+`"`)) + sep 237 | } 238 | 239 | if f.IsDirectory { 240 | op = del + move + rename 241 | } else { 242 | op = download + del + move + rename 243 | } 244 | 245 | if op == "" { 246 | op = "-" 247 | } else { 248 | o := strings.Replace(string(op), " | | ", " | ", -1) 249 | op = template.HTML(o[3 : len(o)-3]) 250 | } 251 | 252 | list[k]["operation"] = types.InfoItem{Content: op} 253 | } 254 | } 255 | 256 | if isSubDir { 257 | list[length-1] = map[string]types.InfoItem{ 258 | "name": {Content: link(GetUrl(prefix, "/list"), template2.HTML("."), true)}, 259 | "size": {Content: "-"}, 260 | "modify_time": {Content: "-"}, 261 | } 262 | 263 | if h.hasOperation() { 264 | list[length-1]["operation"] = types.InfoItem{Content: "-"} 265 | } 266 | 267 | if lastDir != "" { 268 | list[length-2] = map[string]types.InfoItem{ 269 | "name": {Content: link(GetUrl(prefix, "/list?path="+url.QueryEscape(lastDir)), template2.HTML("..."), true)}, 270 | "size": {Content: "-"}, 271 | "modify_time": {Content: "-"}, 272 | } 273 | 274 | if h.hasOperation() { 275 | list[length-2]["operation"] = types.InfoItem{Content: "-"} 276 | } 277 | } 278 | } 279 | 280 | escapeLastDir := url.QueryEscape(lastDir) 281 | 282 | btns := make(types.Buttons, 0) 283 | 284 | if h.permissions.AllowCreateDir { 285 | btns = append(btns, types.GetDefaultButtonGroup(language.GetHTML("new directory"), icon.Plus, 286 | action.PopUp("_", language.Get("new directory"), nil). 287 | SetBtnTitle(language.GetHTML("create")). 288 | SetUrl(GetUrl(prefix, "/create/dir/popup?path="+escapeLastDir)))) 289 | } 290 | 291 | if h.permissions.AllowUpload { 292 | btns = append(btns, types.GetDefaultButtonGroup(language.GetHTML("upload"), icon.Upload, 293 | action.FileUpload("_", nil).SetUrl(GetUrl(prefix, "/upload?path="+ctx.Query("path"))))) 294 | } 295 | 296 | if isSubDir { 297 | homeBtn := types.GetDefaultButtonGroup(language.GetHTML("home"), icon.Home, action.Jump(GetUrl(prefix, "/list"))) 298 | btns = append(btns, homeBtn) 299 | if lastDir != "" { 300 | lastBtn := types.GetDefaultButtonGroup(language.GetHTML("last"), icon.Backward, action.Jump(GetUrl(prefix, "/list?path="+url.QueryEscape(lastDir)))) 301 | btns = append(btns, lastBtn) 302 | } 303 | } 304 | 305 | btnHTML, btnsJs := btns.Content(ctx) 306 | 307 | thead := types.Thead{ 308 | {Head: language.Get("filename"), Field: "name"}, 309 | {Head: language.Get("size"), Field: "size"}, 310 | {Head: language.Get("last modify time"), Field: "modify_time"}, 311 | } 312 | 313 | if h.hasOperation() { 314 | thead = append(thead, types.TheadItem{Head: language.Get("operation"), Field: "operation"}) 315 | } 316 | 317 | delUrl := "" 318 | 319 | if h.permissions.AllowDelete { 320 | delUrl = GetUrl(prefix, "/delete") 321 | } 322 | 323 | table := comp.DataTable(). 324 | SetHideFilterArea(true). 325 | SetButtons(btnHTML + btns.FooterContent(ctx) + moveFooter + renameFooter). 326 | SetDeleteUrl(delUrl). 327 | SetActionJs(btnsJs + movePopUpJs + renamePopUpJs). 328 | SetPrimaryKey("path"). 329 | SetNoAction(). 330 | SetHideRowSelector(true). 331 | SetInfoList(list). 332 | SetThead(thead) 333 | 334 | return h.panel(ctx, path, err, table, total, defaultPageSize) 335 | } 336 | 337 | func (h *Handler) panel(ctx *context.Context, path string, err error, table types.DataTableAttribute, total, defaultPageSize int) types.Panel { 338 | alert := template.HTML("") 339 | if err != nil { 340 | alert = template.Default().Alert().Warning(err.Error()) 341 | } 342 | 343 | return types.Panel{ 344 | Content: alert + template.Default().Box(). 345 | SetBody(table.GetContent()). 346 | SetNoPadding(). 347 | SetHeader(table.GetDataTableHeader()). 348 | WithHeadBorder(). 349 | SetFooter(paginator.Get(ctx, paginator.Config{ 350 | Size: total, 351 | PageSizeList: []string{"10", "20", "30", "50"}, 352 | Param: parameter.GetParam(ctx.Request.URL, defaultPageSize), 353 | }).GetContent()). 354 | GetContent(), 355 | Title: language.GetHTML(h.roots.GetTitleFromPrefix(ctx)), 356 | Description: fixedDescription(path), 357 | } 358 | } 359 | -------------------------------------------------------------------------------- /controller/delete.go: -------------------------------------------------------------------------------- 1 | package controller 2 | 3 | import ( 4 | "net/http" 5 | "os" 6 | "path/filepath" 7 | 8 | "github.com/GoAdminGroup/filemanager/guard" 9 | "github.com/GoAdminGroup/go-admin/context" 10 | ) 11 | 12 | func (h *Handler) Delete(ctx *context.Context) { 13 | param := guard.GetDeleteParam(ctx) 14 | 15 | if param.Error != nil { 16 | ctx.JSON(http.StatusBadRequest, map[string]interface{}{ 17 | "code": http.StatusBadRequest, 18 | "msg": param.Error.Error(), 19 | }) 20 | return 21 | } 22 | 23 | for _, path := range param.Paths { 24 | err := os.RemoveAll(filepath.FromSlash(path)) 25 | 26 | if err != nil { 27 | ctx.JSON(http.StatusInternalServerError, map[string]interface{}{ 28 | "code": http.StatusInternalServerError, 29 | "msg": err.Error(), 30 | }) 31 | return 32 | } 33 | } 34 | 35 | ctx.JSON(http.StatusOK, map[string]interface{}{ 36 | "code": 200, 37 | "msg": "ok", 38 | }) 39 | } 40 | -------------------------------------------------------------------------------- /controller/download.go: -------------------------------------------------------------------------------- 1 | package controller 2 | 3 | import ( 4 | "net/url" 5 | "path/filepath" 6 | "strings" 7 | 8 | "github.com/GoAdminGroup/filemanager/models" 9 | errors "github.com/GoAdminGroup/filemanager/modules/error" 10 | "github.com/GoAdminGroup/filemanager/modules/util" 11 | "github.com/GoAdminGroup/go-admin/context" 12 | ) 13 | 14 | func (h *Handler) Download(ctx *context.Context) { 15 | 16 | var ( 17 | relativePath, _ = url.QueryUnescape(ctx.Query("path")) 18 | raw = ctx.Query("raw") == "true" 19 | path = filepath.Join(h.roots.GetPathFromPrefix(ctx), relativePath) 20 | ) 21 | 22 | var filesOfDir = make(models.Files, 0) 23 | 24 | if !strings.Contains(path, h.roots.GetPathFromPrefix(ctx)) { 25 | h.table(ctx, filesOfDir, errors.DirIsNotExist) 26 | return 27 | } 28 | 29 | if !util.FileExist(path) { 30 | h.table(ctx, filesOfDir, errors.DirIsNotExist) 31 | return 32 | } 33 | 34 | if util.IsDirectory(path) { 35 | h.table(ctx, filesOfDir, errors.IsNotFile) 36 | return 37 | } 38 | 39 | filename := filepath.Base(path) 40 | 41 | agent := ctx.Request.Header.Get("User-Agent") 42 | if strings.Contains(agent, "MSIE") { 43 | filename = url.QueryEscape(filename) 44 | filename = strings.Replace(filename, "+", "%20", -1) 45 | } 46 | if strings.Contains(agent, "Edge") && strings.Contains(agent, "Gecko") { 47 | filename = url.QueryEscape(filename) 48 | filename = strings.Replace(filename, "+", "%20", -1) 49 | } 50 | 51 | contentType := util.ParseFileContentType(filename) 52 | ctx.SetContentType(contentType) 53 | 54 | if !raw { 55 | ctx.AddHeader("content-disposition", `attachment; filename=`+filename) 56 | } 57 | 58 | _ = ctx.ServeFile(filepath.FromSlash(path), false) 59 | } 60 | -------------------------------------------------------------------------------- /controller/files.go: -------------------------------------------------------------------------------- 1 | package controller 2 | 3 | import ( 4 | "io/ioutil" 5 | "mime" 6 | "path/filepath" 7 | "strings" 8 | 9 | "github.com/GoAdminGroup/filemanager/guard" 10 | "github.com/GoAdminGroup/filemanager/models" 11 | "github.com/GoAdminGroup/filemanager/modules/util" 12 | "github.com/GoAdminGroup/go-admin/context" 13 | ) 14 | 15 | func (h *Handler) ListFiles(ctx *context.Context) { 16 | 17 | var ( 18 | param = guard.GetFilesParam(ctx) 19 | filesOfDir = make(models.Files, 0) 20 | ) 21 | 22 | if param.Error != nil { 23 | h.table(ctx, filesOfDir, param.Error) 24 | return 25 | } 26 | 27 | fileInfos, err := ioutil.ReadDir(filepath.FromSlash(param.FullPath)) 28 | 29 | if err != nil { 30 | h.table(ctx, filesOfDir, err) 31 | return 32 | } 33 | 34 | for _, fileInfo := range fileInfos { 35 | 36 | if util.IsHiddenFile(fileInfo.Name()) { 37 | continue 38 | } 39 | 40 | file := models.File{ 41 | IsDirectory: fileInfo.IsDir(), 42 | Name: fileInfo.Name(), 43 | Size: int(fileInfo.Size()), 44 | Extension: strings.TrimLeft(filepath.Ext(fileInfo.Name()), "."), 45 | Path: filepath.Join(param.Path, fileInfo.Name()), 46 | Mime: mime.TypeByExtension(filepath.Ext(fileInfo.Name())), 47 | LastModified: fileInfo.ModTime().Unix(), 48 | } 49 | 50 | filesOfDir = append(filesOfDir, file) 51 | } 52 | 53 | h.table(ctx, filesOfDir, nil) 54 | return 55 | } 56 | -------------------------------------------------------------------------------- /controller/move.go: -------------------------------------------------------------------------------- 1 | package controller 2 | 3 | import ( 4 | "io/ioutil" 5 | "net/http" 6 | "net/url" 7 | "os" 8 | "path/filepath" 9 | 10 | "github.com/GoAdminGroup/filemanager/guard" 11 | "github.com/GoAdminGroup/filemanager/modules/language" 12 | "github.com/GoAdminGroup/filemanager/modules/util" 13 | "github.com/GoAdminGroup/go-admin/context" 14 | ) 15 | 16 | func (h *Handler) Move(ctx *context.Context) { 17 | 18 | param := guard.GetMoveParam(ctx) 19 | 20 | if param.Error != nil { 21 | ctx.JSON(http.StatusBadRequest, map[string]interface{}{ 22 | "code": http.StatusBadRequest, 23 | "msg": param.Error.Error(), 24 | }) 25 | return 26 | } 27 | 28 | err := os.Rename(filepath.FromSlash(param.Src), filepath.FromSlash(param.Dist)) 29 | 30 | if err != nil { 31 | ctx.JSON(http.StatusInternalServerError, map[string]interface{}{ 32 | "code": http.StatusInternalServerError, 33 | "msg": err.Error(), 34 | }) 35 | return 36 | } 37 | 38 | ctx.JSON(http.StatusOK, map[string]interface{}{ 39 | "code": 0, 40 | "msg": language.Get("move success"), 41 | }) 42 | } 43 | 44 | func (h *Handler) MovePopup(ctx *context.Context) { 45 | 46 | var ( 47 | popupID = ctx.FormValue("popup_id") 48 | fileName = ctx.FormValue("id") 49 | 50 | relativePath, _ = url.QueryUnescape(ctx.Query("path")) 51 | 52 | path = filepath.Join(h.roots.GetPathFromPrefix(ctx), relativePath) 53 | options = "" 54 | prefix = h.Prefix(ctx) 55 | 56 | fileInfos, err = ioutil.ReadDir(filepath.FromSlash(path)) 57 | ) 58 | 59 | if err != nil { 60 | ctx.JSON(http.StatusBadRequest, map[string]interface{}{ 61 | "code": http.StatusBadRequest, 62 | "msg": err.Error(), 63 | }) 64 | return 65 | } 66 | 67 | if relativePath == "" { 68 | relativePath = "/" 69 | } 70 | 71 | for _, fileInfo := range fileInfos { 72 | 73 | if util.IsHiddenFile(fileInfo.Name()) { 74 | continue 75 | } 76 | 77 | if fileInfo.IsDir() { 78 | filePath := filepath.Join(relativePath, fileInfo.Name()) 79 | if filePath != fileName { 80 | options += `` 81 | } 82 | } 83 | } 84 | 85 | if relativePath != "." && relativePath != "/" { 86 | parentDir := filepath.Dir(relativePath) 87 | options += `` 88 | } 89 | 90 | popupForm := `
91 |
92 | 97 |
98 |
99 | ` 136 | 137 | ctx.JSON(http.StatusOK, map[string]interface{}{ 138 | "code": 0, 139 | "msg": "ok", 140 | "data": popupForm, 141 | }) 142 | } 143 | -------------------------------------------------------------------------------- /controller/preview.go: -------------------------------------------------------------------------------- 1 | package controller 2 | 3 | import ( 4 | "github.com/GoAdminGroup/filemanager/guard" 5 | "github.com/GoAdminGroup/filemanager/previewer" 6 | "github.com/GoAdminGroup/go-admin/context" 7 | ) 8 | 9 | func (h *Handler) Preview(ctx *context.Context) { 10 | param := guard.GetPreviewParam(ctx) 11 | if param.Error != nil { 12 | h.preview(ctx, "", param.Path, param.FullPath, param.Error) 13 | return 14 | } 15 | content, err := previewer.Preview(param.FullPath) 16 | h.preview(ctx, content, param.Path, param.FullPath, err) 17 | } 18 | -------------------------------------------------------------------------------- /controller/rename.go: -------------------------------------------------------------------------------- 1 | package controller 2 | 3 | import ( 4 | "net/http" 5 | "os" 6 | "path/filepath" 7 | 8 | "github.com/GoAdminGroup/filemanager/guard" 9 | "github.com/GoAdminGroup/filemanager/modules/language" 10 | "github.com/GoAdminGroup/go-admin/context" 11 | ) 12 | 13 | func (h *Handler) Rename(ctx *context.Context) { 14 | 15 | param := guard.GetRenameParam(ctx) 16 | 17 | if param.Error != nil { 18 | ctx.JSON(http.StatusBadRequest, map[string]interface{}{ 19 | "code": http.StatusBadRequest, 20 | "msg": param.Error.Error(), 21 | }) 22 | return 23 | } 24 | 25 | err := os.Rename(filepath.FromSlash(param.Src), filepath.FromSlash(param.Dist)) 26 | 27 | if err != nil { 28 | ctx.JSON(http.StatusInternalServerError, map[string]interface{}{ 29 | "code": http.StatusInternalServerError, 30 | "msg": err.Error(), 31 | }) 32 | return 33 | } 34 | 35 | ctx.JSON(http.StatusOK, map[string]interface{}{ 36 | "code": 0, 37 | "msg": language.Get("rename success"), 38 | }) 39 | } 40 | 41 | func (h *Handler) RenamePopUp(ctx *context.Context) { 42 | 43 | var ( 44 | popupID = ctx.FormValue("popup_id") 45 | path = ctx.FormValue("id") 46 | prefix = h.Prefix(ctx) 47 | ) 48 | 49 | popupForm := `
50 |
51 | 52 |
53 |
54 | ` 93 | 94 | ctx.JSON(http.StatusOK, map[string]interface{}{ 95 | "code": 0, 96 | "msg": "ok", 97 | "data": popupForm, 98 | }) 99 | } 100 | -------------------------------------------------------------------------------- /controller/upload.go: -------------------------------------------------------------------------------- 1 | package controller 2 | 3 | import ( 4 | "net/http" 5 | "net/url" 6 | "os" 7 | "path/filepath" 8 | 9 | "github.com/GoAdminGroup/filemanager/guard" 10 | "github.com/GoAdminGroup/filemanager/modules/language" 11 | "github.com/GoAdminGroup/go-admin/context" 12 | "github.com/GoAdminGroup/go-admin/modules/file" 13 | ) 14 | 15 | func (h *Handler) Upload(ctx *context.Context) { 16 | param := guard.GetUploadParam(ctx) 17 | for k := range param.Files { 18 | for _, fileObj := range param.Files[k] { 19 | 20 | err := file.SaveMultipartFile(fileObj, filepath.FromSlash(param.FullPath+"/"+fileObj.Filename)) 21 | if err != nil { 22 | ctx.JSON(http.StatusInternalServerError, map[string]interface{}{ 23 | "code": http.StatusInternalServerError, 24 | "msg": err.Error(), 25 | }) 26 | } 27 | } 28 | } 29 | ctx.JSON(http.StatusOK, map[string]interface{}{ 30 | "code": 0, 31 | "msg": language.GetHTML("upload success"), 32 | }) 33 | } 34 | 35 | func (h *Handler) CreateDirPopUp(ctx *context.Context) { 36 | 37 | var ( 38 | popupID = ctx.FormValue("popup_id") 39 | path, _ = url.QueryUnescape(ctx.Query("path")) 40 | prefix = h.Prefix(ctx) 41 | ) 42 | 43 | popupForm := `
44 |
45 | 46 |
47 |
48 | ` 87 | 88 | ctx.JSON(http.StatusOK, map[string]interface{}{ 89 | "code": 0, 90 | "msg": "ok", 91 | "data": popupForm, 92 | }) 93 | } 94 | 95 | func (h *Handler) CreateDir(ctx *context.Context) { 96 | 97 | param := guard.GetCreateDirParam(ctx) 98 | 99 | if param.Error != nil { 100 | ctx.JSON(http.StatusBadRequest, map[string]interface{}{ 101 | "code": http.StatusBadRequest, 102 | "msg": param.Error.Error(), 103 | }) 104 | return 105 | } 106 | 107 | err := os.MkdirAll(filepath.FromSlash(param.Dir), os.ModePerm) 108 | if err != nil { 109 | ctx.JSON(http.StatusInternalServerError, map[string]interface{}{ 110 | "code": http.StatusInternalServerError, 111 | "msg": err.Error(), 112 | }) 113 | return 114 | } 115 | 116 | ctx.JSON(http.StatusOK, map[string]interface{}{ 117 | "code": 0, 118 | "msg": language.Get("create success"), 119 | }) 120 | } 121 | -------------------------------------------------------------------------------- /example/admin.db: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GoAdminGroup/filemanager/55d31351ebac516bfe98bc2ae70b0de75cd9b699/example/admin.db -------------------------------------------------------------------------------- /example/book/fiction/a.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GoAdminGroup/filemanager/55d31351ebac516bfe98bc2ae70b0de75cd9b699/example/book/fiction/a.txt -------------------------------------------------------------------------------- /example/book/funny/a.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GoAdminGroup/filemanager/55d31351ebac516bfe98bc2ae70b0de75cd9b699/example/book/funny/a.txt -------------------------------------------------------------------------------- /example/book/funny/dir_dir1/a.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GoAdminGroup/filemanager/55d31351ebac516bfe98bc2ae70b0de75cd9b699/example/book/funny/dir_dir1/a.txt -------------------------------------------------------------------------------- /example/book/robot.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GoAdminGroup/filemanager/55d31351ebac516bfe98bc2ae70b0de75cd9b699/example/book/robot.gif -------------------------------------------------------------------------------- /example/book/suspense/a.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GoAdminGroup/filemanager/55d31351ebac516bfe98bc2ae70b0de75cd9b699/example/book/suspense/a.txt -------------------------------------------------------------------------------- /example/book/tech/a.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GoAdminGroup/filemanager/55d31351ebac516bfe98bc2ae70b0de75cd9b699/example/book/tech/a.txt -------------------------------------------------------------------------------- /example/book/tech/dir_dir1/a.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GoAdminGroup/filemanager/55d31351ebac516bfe98bc2ae70b0de75cd9b699/example/book/tech/dir_dir1/a.txt -------------------------------------------------------------------------------- /example/code/golang/a.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GoAdminGroup/filemanager/55d31351ebac516bfe98bc2ae70b0de75cd9b699/example/code/golang/a.txt -------------------------------------------------------------------------------- /example/code/golang/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "log" 5 | "os" 6 | "os/signal" 7 | 8 | "github.com/GoAdminGroup/filemanager/modules/root" 9 | 10 | _ "github.com/GoAdminGroup/go-admin/adapter/gin" 11 | _ "github.com/GoAdminGroup/go-admin/modules/db/drivers/sqlite" 12 | _ "github.com/GoAdminGroup/themes/sword" 13 | 14 | "github.com/GoAdminGroup/filemanager" 15 | "github.com/GoAdminGroup/go-admin/engine" 16 | "github.com/GoAdminGroup/go-admin/modules/config" 17 | "github.com/GoAdminGroup/go-admin/modules/language" 18 | "github.com/gin-gonic/gin" 19 | ) 20 | 21 | func main() { 22 | r := gin.Default() 23 | 24 | //gin.SetMode(gin.ReleaseMode) 25 | //gin.DefaultWriter = ioutil.Discard 26 | 27 | e := engine.Default() 28 | 29 | dir, err := os.Getwd() 30 | if err != nil { 31 | panic(err) 32 | } 33 | 34 | if err := e.AddConfig(config.Config{ 35 | Databases: config.DatabaseList{ 36 | "default": { 37 | Driver: config.DriverSqlite, 38 | File: "./admin.db", 39 | }, 40 | }, 41 | UrlPrefix: "admin", 42 | Store: config.Store{ 43 | Path: "./uploads", 44 | Prefix: "uploads", 45 | }, 46 | Language: language.EN, 47 | IndexUrl: "/fm/def/list", 48 | Debug: true, 49 | Theme: "sword", 50 | Animation: config.PageAnimation{ 51 | Type: "fadeInUp", 52 | }, 53 | }). 54 | AddPlugins(filemanager. 55 | NewFileManager(dir+"/root1"). 56 | AddRoot("root2", root.Root{Path: dir + "/root2", Title: "root2"}). 57 | AddRoot("root3", root.Root{Path: dir + "/root3", Title: "root3"}), 58 | ). 59 | Use(r); err != nil { 60 | panic(err) 61 | } 62 | 63 | r.Static("/uploads", "./uploads") 64 | 65 | go func() { 66 | _ = r.Run(":9033") 67 | }() 68 | 69 | quit := make(chan os.Signal) 70 | signal.Notify(quit, os.Interrupt) 71 | <-quit 72 | log.Print("closing database connection") 73 | e.SqliteConnection().Close() 74 | } 75 | -------------------------------------------------------------------------------- /example/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/GoAdminGroup/filemanager/example 2 | 3 | go 1.14 4 | 5 | require ( 6 | github.com/GoAdminGroup/filemanager v0.0.2-0.20200501062434-b986d76390e8 7 | github.com/GoAdminGroup/go-admin v1.2.23 8 | github.com/GoAdminGroup/themes v0.0.40 9 | github.com/StackExchange/wmi v0.0.0-20190523213315-cbe66965904d // indirect 10 | github.com/gin-gonic/gin v1.6.2 11 | github.com/go-ole/go-ole v1.2.4 // indirect 12 | github.com/h2non/filetype v1.0.12 // indirect 13 | github.com/shirou/gopsutil v2.20.3+incompatible // indirect 14 | github.com/smartystreets/goconvey v1.6.4 // indirect 15 | ) 16 | -------------------------------------------------------------------------------- /example/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.37.4/go.mod h1:NHPJ89PdicEuT9hdPXMROBD91xc5uRDxsMtSB16k7hw= 4 | gitea.com/xorm/sqlfiddle v0.0.0-20180821085327-62ce714f951a/go.mod h1:EXuID2Zs0pAQhH8yz+DNjUbjppKQzKFAn28TMYPB6IU= 5 | github.com/360EntSecGroup-Skylar/excelize v1.4.1 h1:l55mJb6rkkaUzOpSsgEeKYtS6/0gHwBYyfo5Jcjv/Ks= 6 | github.com/360EntSecGroup-Skylar/excelize v1.4.1/go.mod h1:vnax29X2usfl7HHkBrX5EvSCJcmH3dT9luvxzu8iGAE= 7 | github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= 8 | github.com/GoAdminGroup/filemanager v0.0.0-20200412234012-aa85b38c4745 h1:z4Jn/R5i6N547p3tVIz8ANaNJ7a7/EIT4TqFGEyCQ1A= 9 | github.com/GoAdminGroup/filemanager v0.0.0-20200412234012-aa85b38c4745/go.mod h1:H3161Jm5n7HkUI7AAr9TJYpuxkLN5PrdQXe+4FMoOq4= 10 | github.com/GoAdminGroup/filemanager v0.0.0-20200413010222-678af33b1349 h1:nIhmlATbPnGuh+dujJMw6LFPxNExuTtmex/0oU+ylFY= 11 | github.com/GoAdminGroup/filemanager v0.0.0-20200413010222-678af33b1349/go.mod h1:H3161Jm5n7HkUI7AAr9TJYpuxkLN5PrdQXe+4FMoOq4= 12 | github.com/GoAdminGroup/filemanager v0.0.0-20200413035633-22b491a688de h1:oSprtOqhkl6erhtMzH+y9usLd2ILN5DlMyzj54cjALA= 13 | github.com/GoAdminGroup/filemanager v0.0.0-20200413035633-22b491a688de/go.mod h1:H3161Jm5n7HkUI7AAr9TJYpuxkLN5PrdQXe+4FMoOq4= 14 | github.com/GoAdminGroup/filemanager v0.0.1 h1:jKNApkERtcfU8AGQK35glVhilQoSBUVl0lZ96KSpI6E= 15 | github.com/GoAdminGroup/filemanager v0.0.1/go.mod h1:H3161Jm5n7HkUI7AAr9TJYpuxkLN5PrdQXe+4FMoOq4= 16 | github.com/GoAdminGroup/filemanager v0.0.2-0.20200501062434-b986d76390e8 h1:k+WfWuVZSxi1D61ZrcwUngjhu9sqRA4NY+RTKaP+s1I= 17 | github.com/GoAdminGroup/filemanager v0.0.2-0.20200501062434-b986d76390e8/go.mod h1:H3161Jm5n7HkUI7AAr9TJYpuxkLN5PrdQXe+4FMoOq4= 18 | github.com/GoAdminGroup/go-admin v1.2.8-0.20200412164441-ecd28c80fccb h1:rh0LUbsIbj6ZIAzbblKzgXz/y47wp/TZnjFLY2tyXcQ= 19 | github.com/GoAdminGroup/go-admin v1.2.8-0.20200412164441-ecd28c80fccb/go.mod h1:9Kk8rbrMUUiKQCRaAtdV1aHOTHaqzeyjChq9ykQ76Rg= 20 | github.com/GoAdminGroup/go-admin v1.2.8 h1:Hub/J6LnsUDJc3EEkK7RQX+RReE7cQTX7b8d3RlPl3Q= 21 | github.com/GoAdminGroup/go-admin v1.2.8/go.mod h1:9Kk8rbrMUUiKQCRaAtdV1aHOTHaqzeyjChq9ykQ76Rg= 22 | github.com/GoAdminGroup/go-admin v1.2.9 h1:wLFhbtSmeHaMgN7qdrzo1ZtTcwS3LyZAVEZTfJPRMJ8= 23 | github.com/GoAdminGroup/go-admin v1.2.9/go.mod h1:7T4oDolkEtLJNnkdZqqENr2ehcxzy0XWQUnuZ8Ym0uE= 24 | github.com/GoAdminGroup/go-admin v1.2.10 h1:NsZZGMb16pvYpyIHwPef4SPzGEcmLvPyREjXgOlMAUw= 25 | github.com/GoAdminGroup/go-admin v1.2.10/go.mod h1:I392koJz0AurjYn95iA4PBpI8x0xErC8Vl5Wst4suvA= 26 | github.com/GoAdminGroup/go-admin v1.2.11 h1:lqGP9Voi6cjiJynDX3TG2mUCaUKXiW+y30XrfAL8hxY= 27 | github.com/GoAdminGroup/go-admin v1.2.11/go.mod h1:I392koJz0AurjYn95iA4PBpI8x0xErC8Vl5Wst4suvA= 28 | github.com/GoAdminGroup/go-admin v1.2.12 h1:M4/VO4fpQHoW5HYjxKvEFv2JE1wHdXBnWEG7RRAj/pM= 29 | github.com/GoAdminGroup/go-admin v1.2.12/go.mod h1:I392koJz0AurjYn95iA4PBpI8x0xErC8Vl5Wst4suvA= 30 | github.com/GoAdminGroup/go-admin v1.2.13 h1:OnwuvRMw2smAxss5Bz3veSHv4n5+WvJTm8xGM7tRDU0= 31 | github.com/GoAdminGroup/go-admin v1.2.13/go.mod h1:I392koJz0AurjYn95iA4PBpI8x0xErC8Vl5Wst4suvA= 32 | github.com/GoAdminGroup/go-admin v1.2.14 h1:gl1mJcyyqe5utk2jo1OMeTcE59yjRjloHsLY6ymXFXU= 33 | github.com/GoAdminGroup/go-admin v1.2.14/go.mod h1:I392koJz0AurjYn95iA4PBpI8x0xErC8Vl5Wst4suvA= 34 | github.com/GoAdminGroup/go-admin v1.2.17 h1:uZRL9ewe2ErIBdSnHyfcyOn/2vTLqLPHs0IgrShTrDM= 35 | github.com/GoAdminGroup/go-admin v1.2.17/go.mod h1:EX+fDr3yPIQ8jKoXzjh5A8MbhfCY2KOhcd0rctlxBH4= 36 | github.com/GoAdminGroup/go-admin v1.2.20 h1:2CkhOC9Oy10si/bQ4Euvs7Pq/CnFzX3p1yBPeewTDCo= 37 | github.com/GoAdminGroup/go-admin v1.2.20/go.mod h1:EX+fDr3yPIQ8jKoXzjh5A8MbhfCY2KOhcd0rctlxBH4= 38 | github.com/GoAdminGroup/go-admin v1.2.22 h1:G3TOPKsUVBJDd4kHpS4LqWT6n3e9AbBei07YdnlqHpk= 39 | github.com/GoAdminGroup/go-admin v1.2.22/go.mod h1:EX+fDr3yPIQ8jKoXzjh5A8MbhfCY2KOhcd0rctlxBH4= 40 | github.com/GoAdminGroup/go-admin v1.2.23 h1:myn18AVWNs2U2e2OwzzSDk1QNlOsOvv1t8G4X8UygE4= 41 | github.com/GoAdminGroup/go-admin v1.2.23/go.mod h1:EX+fDr3yPIQ8jKoXzjh5A8MbhfCY2KOhcd0rctlxBH4= 42 | github.com/GoAdminGroup/html v0.0.1 h1:SdWNWl4OKPsvDk2GDp5ZKD6ceWoN8n4Pj6cUYxavUd0= 43 | github.com/GoAdminGroup/html v0.0.1/go.mod h1:A1laTJaOx8sQ64p2dE8IqtstDeCNBHEazrEp7hR5VvM= 44 | github.com/GoAdminGroup/themes v0.0.30-0.20200412131615-60d8ce976795 h1:S1yhf3iarFODRBN6XqjW97HFmuqh8nFSA9krYH2unjY= 45 | github.com/GoAdminGroup/themes v0.0.30-0.20200412131615-60d8ce976795/go.mod h1:ABCOeBeibfg9DxAsGVa1NzYK9/nIbHT/BuFrCRIKo8A= 46 | github.com/GoAdminGroup/themes v0.0.30-0.20200413000940-c9ef15db4348 h1:svCyXLG0TJjUv6o9BV+fE3Vq4oEXHGvH/MWS9j4/x+o= 47 | github.com/GoAdminGroup/themes v0.0.30-0.20200413000940-c9ef15db4348/go.mod h1:ABCOeBeibfg9DxAsGVa1NzYK9/nIbHT/BuFrCRIKo8A= 48 | github.com/GoAdminGroup/themes v0.0.30 h1:rF/++U0o1vH9589uJ22H6OZw+WxuwB8vtSoti9KhdM4= 49 | github.com/GoAdminGroup/themes v0.0.30/go.mod h1:ABCOeBeibfg9DxAsGVa1NzYK9/nIbHT/BuFrCRIKo8A= 50 | github.com/GoAdminGroup/themes v0.0.31 h1:HrvSHY7L4m3XPp9lKg/+GOk65teiPlC0tZa8MO0ZnO8= 51 | github.com/GoAdminGroup/themes v0.0.31/go.mod h1:ABCOeBeibfg9DxAsGVa1NzYK9/nIbHT/BuFrCRIKo8A= 52 | github.com/GoAdminGroup/themes v0.0.32 h1:2JaVjHmwKB6xEQd7M3M+KlV32zoe5blbxk6hT7d5i7o= 53 | github.com/GoAdminGroup/themes v0.0.32/go.mod h1:ABCOeBeibfg9DxAsGVa1NzYK9/nIbHT/BuFrCRIKo8A= 54 | github.com/GoAdminGroup/themes v0.0.33 h1:KvPFk5rMz8bvrwACKrLOtWkl0f5PAeP0EKTXU0fUX24= 55 | github.com/GoAdminGroup/themes v0.0.33/go.mod h1:ABCOeBeibfg9DxAsGVa1NzYK9/nIbHT/BuFrCRIKo8A= 56 | github.com/GoAdminGroup/themes v0.0.35 h1:CurheBkdi60l8U62OfbCnvaAzyLQPYjqDMjRSwaY/S8= 57 | github.com/GoAdminGroup/themes v0.0.35/go.mod h1:ABCOeBeibfg9DxAsGVa1NzYK9/nIbHT/BuFrCRIKo8A= 58 | github.com/GoAdminGroup/themes v0.0.36 h1:V6nIAnQoq2BECcQ6ap5Ojj2moZxqZJS87JYp8JI6RZg= 59 | github.com/GoAdminGroup/themes v0.0.36/go.mod h1:ABCOeBeibfg9DxAsGVa1NzYK9/nIbHT/BuFrCRIKo8A= 60 | github.com/GoAdminGroup/themes v0.0.37 h1:7iwe6Gv8b3vE0bMqIv4yTT+Ed0xQqIhv8kSc2NKBk74= 61 | github.com/GoAdminGroup/themes v0.0.37/go.mod h1:ABCOeBeibfg9DxAsGVa1NzYK9/nIbHT/BuFrCRIKo8A= 62 | github.com/GoAdminGroup/themes v0.0.40 h1:E+x7YtatE1NJ3OXOg5x0mUk+NTpJ/cCgKYnHf7HQQ+c= 63 | github.com/GoAdminGroup/themes v0.0.40/go.mod h1:ABCOeBeibfg9DxAsGVa1NzYK9/nIbHT/BuFrCRIKo8A= 64 | github.com/NebulousLabs/fastrand v0.0.0-20181203155948-6fb6489aac4e h1:n+DcnTNkQnHlwpsrHoQtkrJIO7CBx029fw6oR4vIob4= 65 | github.com/NebulousLabs/fastrand v0.0.0-20181203155948-6fb6489aac4e/go.mod h1:Bdzq+51GR4/0DIhaICZEOm+OHvXGwwB2trKZ8B4Y6eQ= 66 | github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo= 67 | github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI= 68 | github.com/StackExchange/wmi v0.0.0-20190523213315-cbe66965904d h1:G0m3OIz70MZUWq3EgK3CesDbo8upS2Vm9/P3FtgI+Jk= 69 | github.com/StackExchange/wmi v0.0.0-20190523213315-cbe66965904d/go.mod h1:3eOhrUMpNV+6aFIbp5/iudMxNCF27Vw2OZgy4xEx0Fg= 70 | github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= 71 | github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= 72 | github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= 73 | github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= 74 | github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= 75 | github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 76 | github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= 77 | github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 78 | github.com/denisenkom/go-mssqldb v0.0.0-20190707035753-2be1aa521ff4/go.mod h1:zAg7JM8CkOJ43xKXIj7eRO9kmWm/TW578qo+oDO6tuM= 79 | github.com/denisenkom/go-mssqldb v0.0.0-20200206145737-bbfc9a55622e h1:LzwWXEScfcTu7vUZNlDDWDARoSGEtvlDKK2BYHowNeE= 80 | github.com/denisenkom/go-mssqldb v0.0.0-20200206145737-bbfc9a55622e/go.mod h1:xbL0rPBG9cCiLr28tMa8zpbdarY27NDyej4t/EjAShU= 81 | github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs= 82 | github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU= 83 | github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I= 84 | github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= 85 | github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE= 86 | github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI= 87 | github.com/gin-gonic/gin v1.6.2 h1:88crIK23zO6TqlQBt+f9FrPJNKm9ZEr7qjp9vl/d5TM= 88 | github.com/gin-gonic/gin v1.6.2/go.mod h1:75u5sXoLsGZoRN5Sgbi1eraJ4GU3++wFwWzhwvtwp4M= 89 | github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= 90 | github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= 91 | github.com/go-ole/go-ole v1.2.4 h1:nNBDSCOigTSiarFpYE9J/KtEA1IOW4CNeqT9TQDqCxI= 92 | github.com/go-ole/go-ole v1.2.4/go.mod h1:XCwSNxSkXRo4vlyPy93sltvi/qJq0jqQhjqQNIwKuxM= 93 | github.com/go-playground/assert/v2 v2.0.1 h1:MsBgLAaY856+nPRTKrp3/OZK38U/wa0CcBYNjji3q3A= 94 | github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= 95 | github.com/go-playground/locales v0.13.0 h1:HyWk6mgj5qFqCT5fjGBuRArbVDfE4hi8+e8ceBS/t7Q= 96 | github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8= 97 | github.com/go-playground/universal-translator v0.17.0 h1:icxd5fm+REJzpZx7ZfpaD876Lmtgy7VtROAbHHXk8no= 98 | github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA= 99 | github.com/go-playground/validator/v10 v10.2.0 h1:KgJ0snyC2R9VXYN2rneOtQcw5aHQB1Vv0sFl1UcHBOY= 100 | github.com/go-playground/validator/v10 v10.2.0/go.mod h1:uOYAAleCW8F/7oMFd6aG0GOhaH6EGOAJShg8Id5JGkI= 101 | github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= 102 | github.com/go-sql-driver/mysql v1.5.0 h1:ozyZYNQW3x3HtqT1jira07DN2PArx2v7/mN66gGcHOs= 103 | github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= 104 | github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= 105 | github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= 106 | github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= 107 | github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe h1:lXe2qZdvpiX5WZkZR4hgp4KJVfY3nMkvmwbVkpv1rVY= 108 | github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0= 109 | github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= 110 | github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= 111 | github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= 112 | github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= 113 | github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= 114 | github.com/golang/protobuf v1.3.3 h1:gyjaxf+svBWX08ZjK86iN9geUJF0H6gp2IRKX6Nf6/I= 115 | github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= 116 | github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= 117 | github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= 118 | github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= 119 | github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= 120 | github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= 121 | github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= 122 | github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= 123 | github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= 124 | github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8= 125 | github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= 126 | github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg= 127 | github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= 128 | github.com/h2non/filetype v1.0.12 h1:yHCsIe0y2cvbDARtJhGBTD2ecvqMSTvlIcph9En/Zao= 129 | github.com/h2non/filetype v1.0.12/go.mod h1:319b3zT68BvV+WRj7cwy856M2ehB3HqNOt6sy1HndBY= 130 | github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= 131 | github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= 132 | github.com/json-iterator/go v1.1.9 h1:9yzud/Ht36ygwatGx56VwCZtlI/2AD15T1X2sjSuGns= 133 | github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= 134 | github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= 135 | github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo= 136 | github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= 137 | github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= 138 | github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= 139 | github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= 140 | github.com/konsorten/go-windows-terminal-sequences v1.0.2 h1:DB17ag19krx9CFsz4o3enTrPXyIXCl+2iCXH/aMAp9s= 141 | github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= 142 | github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= 143 | github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= 144 | github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= 145 | github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= 146 | github.com/leodido/go-urn v1.2.0 h1:hpXL4XnriNwQ/ABnpepYM/1vCLWNDfUNts8dX3xTG6Y= 147 | github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII= 148 | github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= 149 | github.com/lib/pq v1.3.0 h1:/qkRGz8zljWiDcFvgpwUpwIAPu3r07TDvs3Rws+o/pU= 150 | github.com/lib/pq v1.3.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= 151 | github.com/magiconair/properties v1.8.1 h1:ZC2Vc7/ZFkGmsVC9KvOjumD+G5lXy2RtTKyzRKO2BQ4= 152 | github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= 153 | github.com/mattn/go-colorable v0.1.4 h1:snbPLB8fVfU9iwbbo30TPtbLRzwWu6aJS6Xh4eaaviA= 154 | github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= 155 | github.com/mattn/go-isatty v0.0.8 h1:HLtExJ+uU2HOZ+wI0Tt5DtUDrx8yhUqDcp7fYERX4CE= 156 | github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= 157 | github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY= 158 | github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= 159 | github.com/mattn/go-sqlite3 v1.10.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= 160 | github.com/mattn/go-sqlite3 v2.0.3+incompatible h1:gXHsfypPkaMZrKbD5209QV9jbUTJKjyR5WD3HYQSd+U= 161 | github.com/mattn/go-sqlite3 v2.0.3+incompatible/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= 162 | github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= 163 | github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b h1:j7+1HpAFS1zy5+Q4qx1fWh90gTKwiN4QCGoY9TWyyO4= 164 | github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b/go.mod h1:01TrycV0kFyexm33Z7vhZRXopbI8J3TDReVlkTgMUxE= 165 | github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 h1:ZqeYNhU3OHLH3mGKHDcjJRFFRrJa6eAM5H+CtDdOsPc= 166 | github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= 167 | github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742 h1:Esafd1046DLDQ0W1YjYsBW+p8U2u7vzgW2SQVmlNazg= 168 | github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= 169 | github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 h1:RWengNIwukTxcDr9M+97sNutRR1RKhG96O6jWumTTnw= 170 | github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826/go.mod h1:TaXosZuwdSHYgviHp1DAtfrULt5eUgsSMsZf+YrPgl8= 171 | github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= 172 | github.com/natefinch/lumberjack v2.0.0+incompatible h1:4QJd3OLAMgj7ph+yZTuX13Ld4UpgHp07nNdFX7mqFfM= 173 | github.com/natefinch/lumberjack v2.0.0+incompatible/go.mod h1:Wi9p2TTF5DG5oU+6YfsmYQpsTIOm0B1VNzQg9Mw6nPk= 174 | github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= 175 | github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= 176 | github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= 177 | github.com/openzipkin/zipkin-go v0.1.6/go.mod h1:QgAqvLzwWbR/WpD4A3cGpPtJrZXNIiJc5AZX7/PBEpw= 178 | github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= 179 | github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= 180 | github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= 181 | github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= 182 | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= 183 | github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= 184 | github.com/prometheus/client_golang v0.9.3-0.20190127221311-3c4408c8b829/go.mod h1:p2iRAGwDERtqlqzRXnrOVns+ignqQo//hLXqYxZYVNs= 185 | github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= 186 | github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= 187 | github.com/prometheus/common v0.2.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= 188 | github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= 189 | github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= 190 | github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= 191 | github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= 192 | github.com/satori/go.uuid v1.2.0 h1:0uYX9dsZ2yD7q2RtLRtPSdGDWzjeM3TbMJP9utgA0ww= 193 | github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0= 194 | github.com/shirou/gopsutil v2.20.3+incompatible h1:0JVooMPsT7A7HqEYdydp/OfjSOYSjhXV7w1hkKj/NPQ= 195 | github.com/shirou/gopsutil v2.20.3+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA= 196 | github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= 197 | github.com/sirupsen/logrus v1.4.2 h1:SPIRibHv4MatM3XXNO2BJeFLZwZ2LvZgfQ5+UNI2im4= 198 | github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= 199 | github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykElWQ6/NYmHa3jpm/yHnI4xSofP+UP6SpjHcSeM= 200 | github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= 201 | github.com/smartystreets/goconvey v1.6.4 h1:fv0U8FUIMPNf1L9lnHLvLhgicrIVChEkdzIKYqbNC9s= 202 | github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= 203 | github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= 204 | github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= 205 | github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= 206 | github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= 207 | github.com/stretchr/testify v1.2.3-0.20181224173747-660f15d67dbb/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= 208 | github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= 209 | github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= 210 | github.com/stretchr/testify v1.5.1 h1:nOGnQDM7FYENwehXlg/kFVnos3rEvtKTjRvOWSzb6H4= 211 | github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= 212 | github.com/syndtr/goleveldb v1.0.0/go.mod h1:ZVVdQEZoIme9iO1Ch2Jdy24qqXrMMOU6lpPAyBWyWuQ= 213 | github.com/ugorji/go v1.1.7 h1:/68gy2h+1mWMrwZFeD1kQialdSzAb432dtpeJ42ovdo= 214 | github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw= 215 | github.com/ugorji/go/codec v1.1.7 h1:2SvQaVZ1ouYrrKKwoSk2pzd4A9evlKJb9oTL+OaLUSs= 216 | github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY= 217 | github.com/ziutek/mymysql v1.5.4/go.mod h1:LMSpPZ6DbqWFxNCHW77HeMg9I646SAhApZ/wKdgO/C0= 218 | go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= 219 | go.uber.org/atomic v1.6.0 h1:Ezj3JGmsOnG1MoRWQkPBsKLe9DwWD9QeXzTRzzldNVk= 220 | go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= 221 | go.uber.org/multierr v1.5.0 h1:KCa4XfM8CWFCpxXRGok+Q0SS/0XBhMDbHHGABQLvD2A= 222 | go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU= 223 | go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA= 224 | go.uber.org/zap v1.14.1 h1:nYDKopTbvAPq/NrUVZwT15y2lpROBiLLyoRTbXOYWOo= 225 | go.uber.org/zap v1.14.1/go.mod h1:Mb2vm2krFEG5DV0W9qcHBYFtp/Wku1cvYaqPsS/WYfc= 226 | golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= 227 | golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= 228 | golang.org/x/crypto v0.0.0-20190325154230-a5d413f7728c/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= 229 | golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= 230 | golang.org/x/crypto v0.0.0-20200221231518-2aa609cf4a9d h1:1ZiEyfaQIg3Qh0EoqpwAakHVhecoE5wlSg5GjnafJGw= 231 | golang.org/x/crypto v0.0.0-20200221231518-2aa609cf4a9d/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= 232 | golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= 233 | golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= 234 | golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= 235 | golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= 236 | golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= 237 | golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= 238 | golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= 239 | golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= 240 | golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= 241 | golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= 242 | golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= 243 | golang.org/x/net v0.0.0-20190125091013-d26f9f9a57f3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= 244 | golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= 245 | golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= 246 | golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= 247 | golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= 248 | golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= 249 | golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= 250 | golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= 251 | golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 252 | golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 253 | golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 254 | golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 255 | golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 256 | golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 257 | golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 258 | golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 259 | golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 260 | golang.org/x/sys v0.0.0-20181122145206-62eef0e2fa9b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 261 | golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 262 | golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 263 | golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 264 | golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 265 | golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 266 | golang.org/x/sys v0.0.0-20200219091948-cb0a6d8edb6c h1:jceGD5YNJGgGMkJz79agzOln1K9TaZUjv5ird16qniQ= 267 | golang.org/x/sys v0.0.0-20200219091948-cb0a6d8edb6c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 268 | golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= 269 | golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= 270 | golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs= 271 | golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= 272 | golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= 273 | golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= 274 | golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e h1:FDhOuMEY4JVRztM/gsbk+IKUQ8kj74bxZrgw87eMMVc= 275 | golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= 276 | golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= 277 | golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= 278 | golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= 279 | golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= 280 | golang.org/x/tools v0.0.0-20190328211700-ab21143f2384 h1:TFlARGu6Czu1z7q93HTxcP1P+/ZFC/IKythI5RzrnRg= 281 | golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= 282 | golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= 283 | golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= 284 | golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5 h1:hKsoRgsbwY1NafxrwTs+k64bikrLBkAgPir1TNCj3Zs= 285 | golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= 286 | golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= 287 | google.golang.org/api v0.3.1/go.mod h1:6wY9I6uQWHQ8EM57III9mq/AjF+i8G65rmVagqKMtkk= 288 | google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= 289 | google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= 290 | google.golang.org/appengine v1.6.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= 291 | google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= 292 | google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= 293 | google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= 294 | google.golang.org/genproto v0.0.0-20190404172233-64821d5d2107/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= 295 | google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= 296 | google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= 297 | gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= 298 | gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= 299 | gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= 300 | gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= 301 | gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= 302 | gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= 303 | gopkg.in/ini.v1 v1.51.0 h1:AQvPpx3LzTDM0AjnIRlVFwFFGC+npRopjZxLJj6gdno= 304 | gopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= 305 | gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= 306 | gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= 307 | gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= 308 | gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10= 309 | gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= 310 | honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= 311 | honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= 312 | honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= 313 | honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= 314 | xorm.io/builder v0.3.7/go.mod h1:aUW0S9eb9VCaPohFCH3j7czOx1PMW3i1HrSzbLYGBSE= 315 | xorm.io/xorm v1.0.2/go.mod h1:o4vnEsQ5V2F1/WK6w4XTwmiWJeGj82tqjAnHe44wVHY= 316 | -------------------------------------------------------------------------------- /example/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "io/ioutil" 5 | "log" 6 | "os" 7 | "os/signal" 8 | "path/filepath" 9 | 10 | _ "github.com/GoAdminGroup/go-admin/adapter/gin" 11 | _ "github.com/GoAdminGroup/go-admin/modules/db/drivers/sqlite" 12 | _ "github.com/GoAdminGroup/themes/sword" 13 | 14 | "github.com/GoAdminGroup/filemanager" 15 | "github.com/GoAdminGroup/filemanager/modules/root" 16 | "github.com/GoAdminGroup/go-admin/engine" 17 | "github.com/GoAdminGroup/go-admin/modules/config" 18 | "github.com/GoAdminGroup/go-admin/modules/language" 19 | "github.com/gin-gonic/gin" 20 | ) 21 | 22 | func main() { 23 | gin.SetMode(gin.ReleaseMode) 24 | gin.DefaultWriter = ioutil.Discard 25 | 26 | r := gin.Default() 27 | 28 | e := engine.Default() 29 | 30 | cfg := config.Config{ 31 | Databases: config.DatabaseList{ 32 | "default": { 33 | Driver: config.DriverSqlite, 34 | File: "./admin.db", 35 | }, 36 | }, 37 | UrlPrefix: "admin", 38 | Store: config.Store{ 39 | Path: "./uploads", 40 | Prefix: "uploads", 41 | }, 42 | Language: language.EN, 43 | IndexUrl: "/fm/def/list", 44 | Debug: true, 45 | AccessAssetsLogOff: true, 46 | Theme: "sword", 47 | Animation: config.PageAnimation{ 48 | Type: "fadeInUp", 49 | }, 50 | } 51 | 52 | dir, err := os.Getwd() 53 | if err != nil { 54 | panic(err) 55 | } 56 | 57 | if err := e.AddConfig(cfg). 58 | AddPlugins(filemanager. 59 | NewFileManager(filepath.Join(dir, "book")). 60 | AddRoot("code", root.Root{Path: filepath.Join(dir, "code"), Title: "Code"}). 61 | AddRoot("picture", root.Root{Path: filepath.Join(dir, "picture"), Title: "Picture"}), 62 | ). 63 | Use(r); err != nil { 64 | panic(err) 65 | } 66 | 67 | r.Static("/uploads", "./uploads") 68 | 69 | go func() { 70 | _ = r.Run(":9033") 71 | }() 72 | 73 | quit := make(chan os.Signal) 74 | signal.Notify(quit, os.Interrupt) 75 | <-quit 76 | log.Print("closing database connection") 77 | e.SqliteConnection().Close() 78 | } 79 | -------------------------------------------------------------------------------- /example/picture/animal/cat/111.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GoAdminGroup/filemanager/55d31351ebac516bfe98bc2ae70b0de75cd9b699/example/picture/animal/cat/111.jpeg -------------------------------------------------------------------------------- /example/picture/landscape/a.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GoAdminGroup/filemanager/55d31351ebac516bfe98bc2ae70b0de75cd9b699/example/picture/landscape/a.txt -------------------------------------------------------------------------------- /filemanager.go: -------------------------------------------------------------------------------- 1 | package filemanager 2 | 3 | import ( 4 | "encoding/json" 5 | "time" 6 | 7 | "github.com/GoAdminGroup/filemanager/controller" 8 | "github.com/GoAdminGroup/filemanager/guard" 9 | errors "github.com/GoAdminGroup/filemanager/modules/error" 10 | language2 "github.com/GoAdminGroup/filemanager/modules/language" 11 | "github.com/GoAdminGroup/filemanager/modules/permission" 12 | "github.com/GoAdminGroup/filemanager/modules/root" 13 | "github.com/GoAdminGroup/filemanager/modules/util" 14 | "github.com/GoAdminGroup/go-admin/modules/config" 15 | "github.com/GoAdminGroup/go-admin/modules/db" 16 | "github.com/GoAdminGroup/go-admin/modules/language" 17 | "github.com/GoAdminGroup/go-admin/modules/service" 18 | "github.com/GoAdminGroup/go-admin/modules/utils" 19 | "github.com/GoAdminGroup/go-admin/plugins" 20 | ) 21 | 22 | type FileManager struct { 23 | *plugins.Base 24 | 25 | roots root.Roots 26 | 27 | handler *controller.Handler 28 | guard *guard.Guardian 29 | 30 | allowUpload bool 31 | allowCreateDir bool 32 | allowDelete bool 33 | allowMove bool 34 | allowDownload bool 35 | allowRename bool 36 | 37 | pathValidator PathValidator 38 | } 39 | 40 | type PathValidator func(path string) error 41 | 42 | func init() { 43 | plugins.Add(&FileManager{Base: &plugins.Base{PlugName: Name}}) 44 | } 45 | 46 | const ( 47 | Name = "filemanager" 48 | TableName = "filemanager_setting" 49 | ConnectionKey = "filemanager_connection" 50 | ) 51 | 52 | func NewFileManager(rootPath string, titles ...string) *FileManager { 53 | 54 | if rootPath == "" { 55 | panic("filemanager: create fail, wrong path") 56 | } 57 | 58 | title := Name 59 | if len(titles) > 0 { 60 | title = titles[0] 61 | } 62 | return &FileManager{ 63 | Base: &plugins.Base{PlugName: Name}, 64 | roots: root.Roots{"def": root.Root{Path: rootPath, Title: title}}, 65 | allowUpload: true, 66 | allowCreateDir: true, 67 | allowDelete: true, 68 | allowMove: true, 69 | allowDownload: true, 70 | allowRename: true, 71 | } 72 | } 73 | 74 | type Config struct { 75 | AllowUpload bool `json:"allow_upload",yaml:"allow_upload",ini:"allow_upload"` 76 | AllowCreateDir bool `json:"allow_create_dir",yaml:"allow_create_dir",ini:"allow_create_dir"` 77 | AllowDelete bool `json:"allow_delete",yaml:"allow_delete",ini:"allow_delete"` 78 | AllowMove bool `json:"allow_move",yaml:"allow_move",ini:"allow_move"` 79 | AllowDownload bool `json:"allow_download",yaml:"allow_download",ini:"allow_download"` 80 | AllowRename bool `json:"allow_rename",yaml:"allow_rename",ini:"allow_rename"` 81 | Path string `json:"path",yaml:"path",ini:"path"` 82 | Title string `json:"title",yaml:"title",ini:"title"` 83 | } 84 | 85 | func NewFileManagerWithConfig(cfg Config) *FileManager { 86 | 87 | if cfg.Path == "" { 88 | panic("filemanager: create fail, wrong path") 89 | } 90 | 91 | if !util.FileExist(cfg.Path) { 92 | panic("filemanager: wrong directory path") 93 | } 94 | 95 | if cfg.Title == "" { 96 | cfg.Title = Name 97 | } 98 | 99 | return &FileManager{ 100 | Base: &plugins.Base{PlugName: Name}, 101 | roots: root.Roots{"def": root.Root{Path: cfg.Path, Title: cfg.Title}}, 102 | allowUpload: cfg.AllowUpload, 103 | allowCreateDir: cfg.AllowCreateDir, 104 | allowDelete: cfg.AllowDelete, 105 | allowMove: cfg.AllowMove, 106 | allowRename: cfg.AllowRename, 107 | allowDownload: cfg.AllowDownload, 108 | } 109 | } 110 | 111 | func (f *FileManager) IsInstalled() bool { 112 | return len(f.roots) != 0 113 | } 114 | 115 | func (f *FileManager) SetPathValidator(fn PathValidator) *FileManager { 116 | f.pathValidator = fn 117 | return f 118 | } 119 | 120 | func (f *FileManager) GetIndexURL() string { 121 | return config.Url("/fm") 122 | } 123 | 124 | func (f *FileManager) InitPlugin(srv service.List) { 125 | 126 | // DO NOT DELETE 127 | f.InitBase(srv, "fm") 128 | 129 | f.Conn = db.GetConnection(srv) 130 | 131 | if len(f.roots) == 0 { 132 | checkExist, _ := db.WithDriver(f.Conn). 133 | Table("goadmin_site"). 134 | Where("key", "=", ConnectionKey). 135 | First() 136 | if checkExist != nil { 137 | connName := checkExist["value"].(string) 138 | records, err := db.WithDriverAndConnection(connName, f.Conn).Table(TableName).All() 139 | if !db.CheckError(err, db.INSERT) && len(records) > 0 { 140 | for _, record := range records { 141 | switch record["key"].(string) { 142 | case "roots": 143 | err = json.Unmarshal([]byte(record["value"].(string)), &f.roots) 144 | if err != nil { 145 | continue 146 | } 147 | case "allowUpload": 148 | f.allowUpload = record["value"].(string) == "1" 149 | case "allowCreateDir": 150 | f.allowCreateDir = record["value"].(string) == "1" 151 | case "allowDelete": 152 | f.allowDelete = record["value"].(string) == "1" 153 | case "allowMove": 154 | f.allowMove = record["value"].(string) == "1" 155 | case "allowRename": 156 | f.allowRename = record["value"].(string) == "1" 157 | case "allowDownload": 158 | f.allowDownload = record["value"].(string) == "1" 159 | } 160 | } 161 | } 162 | } 163 | } 164 | 165 | p := permission.Permission{ 166 | AllowUpload: f.allowUpload, 167 | AllowCreateDir: f.allowCreateDir, 168 | AllowDelete: f.allowDelete, 169 | AllowMove: f.allowMove, 170 | AllowRename: f.allowRename, 171 | AllowDownload: f.allowDownload, 172 | } 173 | f.handler = controller.NewHandler(f.roots, p) 174 | f.guard = guard.New(f.roots, f.Conn, p) 175 | f.App = f.initRouter(srv) 176 | f.handler.HTML = f.HTMLMenu 177 | 178 | language.Lang[language.CN].Combine(language2.CN) 179 | language.Lang[language.EN].Combine(language2.EN) 180 | 181 | errors.Init() 182 | 183 | f.SetInfo(info) 184 | } 185 | 186 | var info = plugins.Info{ 187 | Website: "http://www.go-admin.cn/plugins/detail/DDN7VxZDTHTeaF8HUU", 188 | Title: "FileManager", 189 | Description: "A plugin help you manage files in your server", 190 | Version: "v0.0.6", 191 | Author: "Official", 192 | Url: "https://github.com/GoAdminGroup/filemanager/archive/v0.0.6.zip", 193 | Cover: "", 194 | Agreement: "", 195 | Uuid: "DDN7VxZDTHTeaF8HUU", 196 | Name: "filemanager", 197 | ModulePath: "github.com/GoAdminGroup/filemanager", 198 | CreateDate: utils.ParseTime("2020-04-05"), 199 | UpdateDate: utils.ParseTime("2020-08-03"), 200 | } 201 | 202 | type Table struct { 203 | Id int64 204 | Key string `xorm:"VARCHAR(100) 'key'"` 205 | Value string `xorm:"TEXT 'value'"` 206 | CreatedAt time.Time `xorm:"'created_at' timestamp NULL DEFAULT CURRENT_TIMESTAMP"` 207 | UpdatedAt time.Time `xorm:"'updated_at' timestamp NULL DEFAULT CURRENT_TIMESTAMP"` 208 | } 209 | 210 | func (*Table) TableName() string { 211 | return TableName 212 | } 213 | 214 | func (f *FileManager) AddRoot(key string, value root.Root) *FileManager { 215 | f.roots.Add(key, value) 216 | return f 217 | } 218 | -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module github.com/GoAdminGroup/filemanager 2 | 3 | go 1.22.2 4 | 5 | require ( 6 | github.com/GoAdminGroup/demo v0.0.0-20240404022751-41c1bea9b668 7 | github.com/GoAdminGroup/go-admin v1.2.26 8 | github.com/GoAdminGroup/html v0.0.1 9 | github.com/gavv/httpexpect v2.0.0+incompatible 10 | github.com/h2non/filetype v1.1.3 11 | golang.org/x/tools v0.20.0 12 | ) 13 | 14 | require ( 15 | filippo.io/edwards25519 v1.1.0 // indirect 16 | github.com/360EntSecGroup-Skylar/excelize v1.4.1 // indirect 17 | github.com/GoAdminGroup/themes v0.0.45 // indirect 18 | github.com/NebulousLabs/fastrand v0.0.0-20181203155948-6fb6489aac4e // indirect 19 | github.com/ajg/form v1.5.1 // indirect 20 | github.com/andybalholm/brotli v1.1.0 // indirect 21 | github.com/buaazp/fasthttprouter v0.1.1 // indirect 22 | github.com/davecgh/go-spew v1.1.1 // indirect 23 | github.com/denisenkom/go-mssqldb v0.0.0-20200206145737-bbfc9a55622e // indirect 24 | github.com/fatih/structs v1.1.0 // indirect 25 | github.com/gin-contrib/sse v0.1.0 // indirect 26 | github.com/gin-gonic/gin v1.5.0 // indirect 27 | github.com/go-playground/locales v0.12.1 // indirect 28 | github.com/go-playground/universal-translator v0.16.0 // indirect 29 | github.com/go-sql-driver/mysql v1.8.1 // indirect 30 | github.com/gobuffalo/logger v1.0.7 // indirect 31 | github.com/gobuffalo/packd v1.0.1 // indirect 32 | github.com/gobuffalo/packr/v2 v2.8.3 // indirect 33 | github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe // indirect 34 | github.com/golang/protobuf v1.5.3 // indirect 35 | github.com/golang/snappy v0.0.4 // indirect 36 | github.com/google/go-querystring v1.1.0 // indirect 37 | github.com/google/uuid v1.6.0 // indirect 38 | github.com/gorilla/websocket v1.5.1 // indirect 39 | github.com/imkira/go-interpol v1.1.0 // indirect 40 | github.com/json-iterator/go v1.1.12 // indirect 41 | github.com/karrick/godirwalk v1.16.1 // indirect 42 | github.com/klauspost/compress v1.17.6 // indirect 43 | github.com/leodido/go-urn v1.1.0 // indirect 44 | github.com/lib/pq v1.10.5 // indirect 45 | github.com/markbates/errx v1.1.0 // indirect 46 | github.com/markbates/oncer v1.0.0 // indirect 47 | github.com/markbates/safe v1.0.1 // indirect 48 | github.com/mattn/go-colorable v0.1.13 // indirect 49 | github.com/mattn/go-isatty v0.0.20 // indirect 50 | github.com/mattn/go-sqlite3 v2.0.3+incompatible // indirect 51 | github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b // indirect 52 | github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect 53 | github.com/modern-go/reflect2 v1.0.2 // indirect 54 | github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect 55 | github.com/moul/http2curl v1.0.0 // indirect 56 | github.com/pmezard/go-difflib v1.0.0 // indirect 57 | github.com/sclevine/agouti v3.0.0+incompatible // indirect 58 | github.com/sergi/go-diff v1.2.0 // indirect 59 | github.com/sirupsen/logrus v1.9.0 // indirect 60 | github.com/smarty/assertions v1.15.1 // indirect 61 | github.com/stretchr/testify v1.9.0 // indirect 62 | github.com/syndtr/goleveldb v1.0.0 // indirect 63 | github.com/ugorji/go/codec v1.2.12 // indirect 64 | github.com/valyala/bytebufferpool v1.0.0 // indirect 65 | github.com/valyala/fasthttp v1.52.0 // indirect 66 | github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f // indirect 67 | github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect 68 | github.com/xeipuuv/gojsonschema v1.2.0 // indirect 69 | github.com/yalp/jsonpath v0.0.0-20180802001716-5cc68e5049a0 // indirect 70 | github.com/yudai/gojsondiff v1.0.0 // indirect 71 | github.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82 // indirect 72 | go.uber.org/atomic v1.9.0 // indirect 73 | go.uber.org/multierr v1.7.0 // indirect 74 | go.uber.org/zap v1.19.1 // indirect 75 | golang.org/x/crypto v0.22.0 // indirect 76 | golang.org/x/net v0.24.0 // indirect 77 | golang.org/x/sys v0.19.0 // indirect 78 | golang.org/x/term v0.19.0 // indirect 79 | golang.org/x/text v0.14.0 // indirect 80 | google.golang.org/protobuf v1.32.0 // indirect 81 | gopkg.in/go-playground/validator.v9 v9.29.1 // indirect 82 | gopkg.in/ini.v1 v1.67.0 // indirect 83 | gopkg.in/natefinch/lumberjack.v2 v2.2.1 // indirect 84 | gopkg.in/yaml.v2 v2.4.0 // indirect 85 | gopkg.in/yaml.v3 v3.0.1 // indirect 86 | xorm.io/builder v0.3.7 // indirect 87 | xorm.io/xorm v1.0.2 // indirect 88 | ) 89 | -------------------------------------------------------------------------------- /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.37.4/go.mod h1:NHPJ89PdicEuT9hdPXMROBD91xc5uRDxsMtSB16k7hw= 4 | cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= 5 | cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU= 6 | cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= 7 | cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc= 8 | cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0= 9 | cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To= 10 | cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4= 11 | cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M= 12 | cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc= 13 | cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk= 14 | cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs= 15 | cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc= 16 | cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY= 17 | cloud.google.com/go v0.72.0/go.mod h1:M+5Vjvlc2wnp6tjzE102Dw08nGShTscUx2nZMufOKPI= 18 | cloud.google.com/go v0.74.0/go.mod h1:VV1xSbzvo+9QJOxLDaJfTjx5e+MePCpCWwvftOeQmWk= 19 | cloud.google.com/go v0.78.0/go.mod h1:QjdrLG0uq+YwhjoVOLsS1t7TW8fs36kLs4XO5R5ECHg= 20 | cloud.google.com/go v0.79.0/go.mod h1:3bzgcEeQlzbuEAYu4mrWhKqWjmpprinYgKJLgKHnbb8= 21 | cloud.google.com/go v0.81.0/go.mod h1:mk/AM35KwGk/Nm2YSeZbxXdrNK3KZOYHmLkOqC2V6E0= 22 | cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= 23 | cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE= 24 | cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc= 25 | cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg= 26 | cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc= 27 | cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ= 28 | cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= 29 | cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk= 30 | cloud.google.com/go/firestore v1.1.0/go.mod h1:ulACoGHTpvq5r8rxGJ4ddJZBZqakUQqClKRT5SZwBmk= 31 | cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= 32 | cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw= 33 | cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA= 34 | cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU= 35 | cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw= 36 | cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos= 37 | cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk= 38 | cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs= 39 | cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= 40 | dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= 41 | filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA= 42 | filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4= 43 | gitea.com/xorm/sqlfiddle v0.0.0-20180821085327-62ce714f951a h1:lSA0F4e9A2NcQSqGqTOXqu2aRi/XEQxDCBwM8yJtE6s= 44 | gitea.com/xorm/sqlfiddle v0.0.0-20180821085327-62ce714f951a/go.mod h1:EXuID2Zs0pAQhH8yz+DNjUbjppKQzKFAn28TMYPB6IU= 45 | github.com/360EntSecGroup-Skylar/excelize v1.4.1 h1:l55mJb6rkkaUzOpSsgEeKYtS6/0gHwBYyfo5Jcjv/Ks= 46 | github.com/360EntSecGroup-Skylar/excelize v1.4.1/go.mod h1:vnax29X2usfl7HHkBrX5EvSCJcmH3dT9luvxzu8iGAE= 47 | github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= 48 | github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= 49 | github.com/GoAdminGroup/components v0.0.2/go.mod h1:lWLtprDb0slqdYvqDCGwuAvktJ8PsheC9H5h8pOkXCA= 50 | github.com/GoAdminGroup/demo v0.0.0-20240404022751-41c1bea9b668 h1:jg+Dz52ABdYlDOh56XMZC34hAllWQcMrMiF/LWoSDog= 51 | github.com/GoAdminGroup/demo v0.0.0-20240404022751-41c1bea9b668/go.mod h1:s1R5DBbfhDOWYX41PwD/SPnr5q2rqwXR+h0+M01NmSI= 52 | github.com/GoAdminGroup/filemanager v0.0.7-0.20200920142100-04648eca30c9/go.mod h1:H3161Jm5n7HkUI7AAr9TJYpuxkLN5PrdQXe+4FMoOq4= 53 | github.com/GoAdminGroup/go-admin v1.2.24/go.mod h1:voQOP8uoaNi/V0EO3WtOvAm3fvTaNlxrmpe4nZdbzas= 54 | github.com/GoAdminGroup/go-admin v1.2.26 h1:kk18rVrteLcrzH7iMM5p/13jghDC5n3DJG/7zAnbnEU= 55 | github.com/GoAdminGroup/go-admin v1.2.26/go.mod h1:QXj94ZrDclKzqwZnAGUWaK3qY1Wfr6/Qy5GnRGeXR+k= 56 | github.com/GoAdminGroup/html v0.0.1 h1:SdWNWl4OKPsvDk2GDp5ZKD6ceWoN8n4Pj6cUYxavUd0= 57 | github.com/GoAdminGroup/html v0.0.1/go.mod h1:A1laTJaOx8sQ64p2dE8IqtstDeCNBHEazrEp7hR5VvM= 58 | github.com/GoAdminGroup/librarian v0.0.5/go.mod h1:XYLCXuTPEUskGuP7wM54Lh4TeSZaA0cnynpF5Ughajs= 59 | github.com/GoAdminGroup/themes v0.0.45 h1:7z3k5Ul0/r2xUDrlxMzumpE9YGGA2mv7Iz3WdPh5gvg= 60 | github.com/GoAdminGroup/themes v0.0.45/go.mod h1:ABCOeBeibfg9DxAsGVa1NzYK9/nIbHT/BuFrCRIKo8A= 61 | github.com/NebulousLabs/fastrand v0.0.0-20181203155948-6fb6489aac4e h1:n+DcnTNkQnHlwpsrHoQtkrJIO7CBx029fw6oR4vIob4= 62 | github.com/NebulousLabs/fastrand v0.0.0-20181203155948-6fb6489aac4e/go.mod h1:Bdzq+51GR4/0DIhaICZEOm+OHvXGwwB2trKZ8B4Y6eQ= 63 | github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo= 64 | github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI= 65 | github.com/ajg/form v1.5.1 h1:t9c7v8JUKu/XxOGBU0yjNpaMloxGEJhUkqFRq0ibGeU= 66 | github.com/ajg/form v1.5.1/go.mod h1:uL1WgH+h2mgNtvBq0339dVnzXdBETtL2LeUXaIv25UY= 67 | github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= 68 | github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= 69 | github.com/andybalholm/brotli v1.1.0 h1:eLKJA0d02Lf0mVpIDgYnqXcUn0GqVmEFny3VuID1U3M= 70 | github.com/andybalholm/brotli v1.1.0/go.mod h1:sms7XGricyQI9K10gOSf56VKKWS4oLer58Q+mhRPtnY= 71 | github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= 72 | github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= 73 | github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= 74 | github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= 75 | github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= 76 | github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= 77 | github.com/benbjohnson/clock v1.1.0 h1:Q92kusRqC1XV2MjkWETPvjJVqKetz1OzxZB7mHJLju8= 78 | github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= 79 | github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= 80 | github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= 81 | github.com/bketelsen/crypt v0.0.4/go.mod h1:aI6NrJ0pMGgvZKL1iVgXLnfIFJtfV+bKCoqOes/6LfM= 82 | github.com/buaazp/fasthttprouter v0.1.1 h1:4oAnN0C3xZjylvZJdP35cxfclyn4TYkW6Y+DSvS+h8Q= 83 | github.com/buaazp/fasthttprouter v0.1.1/go.mod h1:h/Ap5oRVLeItGKTVBb+heQPks+HdIUtGmI4H5WCYijM= 84 | github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= 85 | github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= 86 | github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= 87 | github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= 88 | github.com/clbanning/mxj v1.8.4/go.mod h1:BVjHeAH+rl9rs6f+QIpeRl0tfu10SXn1pUSa5PVGJng= 89 | github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= 90 | github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= 91 | github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= 92 | github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= 93 | github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= 94 | github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk= 95 | github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= 96 | github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= 97 | github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= 98 | github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE= 99 | github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= 100 | github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 101 | github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= 102 | github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 103 | github.com/denisenkom/go-mssqldb v0.0.0-20190707035753-2be1aa521ff4/go.mod h1:zAg7JM8CkOJ43xKXIj7eRO9kmWm/TW578qo+oDO6tuM= 104 | github.com/denisenkom/go-mssqldb v0.0.0-20200206145737-bbfc9a55622e h1:LzwWXEScfcTu7vUZNlDDWDARoSGEtvlDKK2BYHowNeE= 105 | github.com/denisenkom/go-mssqldb v0.0.0-20200206145737-bbfc9a55622e/go.mod h1:xbL0rPBG9cCiLr28tMa8zpbdarY27NDyej4t/EjAShU= 106 | github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs= 107 | github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU= 108 | github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I= 109 | github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= 110 | github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= 111 | github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= 112 | github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po= 113 | github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= 114 | github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= 115 | github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= 116 | github.com/fasthttp-contrib/websocket v0.0.0-20160511215533-1f3b11f56072 h1:DddqAaWDpywytcG8w/qoQ5sAN8X12d3Z3koB0C3Rxsc= 117 | github.com/fasthttp-contrib/websocket v0.0.0-20160511215533-1f3b11f56072/go.mod h1:duJ4Jxv5lDcvg4QuQr0oowTf7dz4/CR8NtyCooz9HL8= 118 | github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= 119 | github.com/fatih/structs v1.1.0 h1:Q7juDM0QtcnhCpeyLGQKyg4TOIghuNXrkL32pHAUMxo= 120 | github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M= 121 | github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= 122 | github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= 123 | github.com/gavv/httpexpect v2.0.0+incompatible h1:1X9kcRshkSKEjNJJxX9Y9mQ5BRfbxU5kORdjhlA1yX8= 124 | github.com/gavv/httpexpect v2.0.0+incompatible/go.mod h1:x+9tiU1YnrOvnB725RkpoLv1M62hOWzwo5OXotisrKc= 125 | github.com/gf-third/mysql v1.4.2/go.mod h1:+dd90V663ppI2fV5uQ6+rHk0u8KCyU6FkG8Um8Cx3ms= 126 | github.com/gf-third/yaml v1.0.1/go.mod h1:t443vj0txEw3+E0MOtkr83kt+PrZg2I8SRuYfn85NM0= 127 | github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= 128 | github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE= 129 | github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI= 130 | github.com/gin-gonic/gin v1.5.0 h1:fi+bqFAx/oLK54somfCtEZs9HeH1LHVoEPUgARpTqyc= 131 | github.com/gin-gonic/gin v1.5.0/go.mod h1:Nd6IXA8m5kNZdNEHMBd93KT+mdY3+bewLgRvmCsR2Do= 132 | github.com/go-echarts/go-echarts v0.0.0-20190915064101-cbb3b43ade5d/go.mod h1:v4lFmU586g/A0xaH1RMDS86YlYrwpj8eHtR+xBReKE8= 133 | github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= 134 | github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= 135 | github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= 136 | github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= 137 | github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= 138 | github.com/go-playground/locales v0.12.1 h1:2FITxuFt/xuCNP1Acdhv62OzaCiviiE4kotfhkmOqEc= 139 | github.com/go-playground/locales v0.12.1/go.mod h1:IUMDtCfWo/w/mtMfIE/IG2K+Ey3ygWanZIBtBW0W2TM= 140 | github.com/go-playground/universal-translator v0.16.0 h1:X++omBR/4cE2MNg91AoC3rmGrCjJ8eAeUP/K/EKx4DM= 141 | github.com/go-playground/universal-translator v0.16.0/go.mod h1:1AnU7NaIRDWWzGEKwgtJRd2xk99HeFyHw3yid4rvQIY= 142 | github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= 143 | github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= 144 | github.com/go-sql-driver/mysql v1.8.1 h1:LedoTUt/eveggdHS9qUFC1EFSa8bU2+1pZjSRpvNJ1Y= 145 | github.com/go-sql-driver/mysql v1.8.1/go.mod h1:wEBSXgmK//2ZFJyE+qWnIsVGmvmEKlqwuVSjsCm7DZg= 146 | github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= 147 | github.com/gobuffalo/envy v1.7.0/go.mod h1:n7DRkBerg/aorDM8kbduw5dN3oXGswK5liaSCx4T5NI= 148 | github.com/gobuffalo/logger v1.0.0/go.mod h1:2zbswyIUa45I+c+FLXuWl9zSWEiVuthsk8ze5s8JvPs= 149 | github.com/gobuffalo/logger v1.0.6/go.mod h1:J31TBEHR1QLV2683OXTAItYIg8pv2JMHnF/quuAbMjs= 150 | github.com/gobuffalo/logger v1.0.7 h1:LTLwWelETXDYyqF/ASf0nxaIcdEOIJNxRokPcfI/xbU= 151 | github.com/gobuffalo/logger v1.0.7/go.mod h1:u40u6Bq3VVvaMcy5sRBclD8SXhBYPS0Qk95ubt+1xJM= 152 | github.com/gobuffalo/packd v0.3.0/go.mod h1:zC7QkmNkYVGKPw4tHpBQ+ml7W/3tIebgeo1b36chA3Q= 153 | github.com/gobuffalo/packd v1.0.1 h1:U2wXfRr4E9DH8IdsDLlRFwTZTK7hLfq9qT/QHXGVe/0= 154 | github.com/gobuffalo/packd v1.0.1/go.mod h1:PP2POP3p3RXGz7Jh6eYEf93S7vA2za6xM7QT85L4+VY= 155 | github.com/gobuffalo/packr v1.30.1/go.mod h1:ljMyFO2EcrnzsHsN99cvbq055Y9OhRrIaviy289eRuk= 156 | github.com/gobuffalo/packr/v2 v2.5.1/go.mod h1:8f9c96ITobJlPzI44jj+4tHnEKNt0xXWSVlXRN9X1Iw= 157 | github.com/gobuffalo/packr/v2 v2.8.3 h1:xE1yzvnO56cUC0sTpKR3DIbxZgB54AftTFMhB2XEWlY= 158 | github.com/gobuffalo/packr/v2 v2.8.3/go.mod h1:0SahksCVcx4IMnigTjiFuyldmTrdTctXsOdiU5KwbKc= 159 | github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= 160 | github.com/gogf/gf v1.11.5/go.mod h1:iuHZkqyEfxFtpwRYboAU7409O/sfdy79YTpY8si332I= 161 | github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= 162 | github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= 163 | github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= 164 | github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe h1:lXe2qZdvpiX5WZkZR4hgp4KJVfY3nMkvmwbVkpv1rVY= 165 | github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0= 166 | github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= 167 | github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= 168 | github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= 169 | github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= 170 | github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= 171 | github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= 172 | github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= 173 | github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= 174 | github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= 175 | github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= 176 | github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4= 177 | github.com/golang/mock v1.5.0/go.mod h1:CWnOUgYIOo4TcNZ0wHX3YZCqsaM1I1Jvs6v3mP3KVu8= 178 | github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= 179 | github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= 180 | github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= 181 | github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= 182 | github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= 183 | github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk= 184 | github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= 185 | github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= 186 | github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= 187 | github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= 188 | github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= 189 | github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= 190 | github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= 191 | github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= 192 | github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= 193 | github.com/golang/protobuf v1.5.1/go.mod h1:DopwsBzvsk0Fs44TXzsVbJyPhcCPeIwnvohx4u74HPM= 194 | github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= 195 | github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= 196 | github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= 197 | github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= 198 | github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM= 199 | github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= 200 | github.com/gomodule/redigo v2.0.0+incompatible/go.mod h1:B4C85qUVwatsJoIUNIfCRsp7qO0iAmpGFZ4EELWSbC4= 201 | github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= 202 | github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= 203 | github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= 204 | github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= 205 | github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= 206 | github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= 207 | github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= 208 | github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= 209 | github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= 210 | github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= 211 | github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= 212 | github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= 213 | github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU= 214 | github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= 215 | github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= 216 | github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8= 217 | github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU= 218 | github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= 219 | github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= 220 | github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= 221 | github.com/google/martian/v3 v3.1.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= 222 | github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= 223 | github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= 224 | github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= 225 | github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= 226 | github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= 227 | github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= 228 | github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= 229 | github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= 230 | github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= 231 | github.com/google/pprof v0.0.0-20210122040257-d980be63207e/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= 232 | github.com/google/pprof v0.0.0-20210226084205-cbba55b83ad5/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= 233 | github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= 234 | github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= 235 | github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= 236 | github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= 237 | github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= 238 | github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= 239 | github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= 240 | github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= 241 | github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8= 242 | github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= 243 | github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg= 244 | github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= 245 | github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= 246 | github.com/gorilla/websocket v1.5.1 h1:gmztn0JnHVt9JZquRuzLw3g4wouNVzKL15iLr/zn/QY= 247 | github.com/gorilla/websocket v1.5.1/go.mod h1:x3kM2JMyaluk02fnUJpQuwD2dCS5NDG2ZHL0uE0tcaY= 248 | github.com/grokify/html-strip-tags-go v0.0.0-20190921062105-daaa06bf1aaf/go.mod h1:2Su6romC5/1VXOQMaWL2yb618ARB8iVo6/DR99A6d78= 249 | github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= 250 | github.com/h2non/filetype v1.0.12/go.mod h1:319b3zT68BvV+WRj7cwy856M2ehB3HqNOt6sy1HndBY= 251 | github.com/h2non/filetype v1.1.3 h1:FKkx9QbD7HR/zjK1Ia5XiBsq9zdLi5Kf3zGyFTAFkGg= 252 | github.com/h2non/filetype v1.1.3/go.mod h1:319b3zT68BvV+WRj7cwy856M2ehB3HqNOt6sy1HndBY= 253 | github.com/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q= 254 | github.com/hashicorp/consul/sdk v0.1.1/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8= 255 | github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= 256 | github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= 257 | github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= 258 | github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= 259 | github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= 260 | github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU= 261 | github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU= 262 | github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4= 263 | github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= 264 | github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= 265 | github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90= 266 | github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= 267 | github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= 268 | github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= 269 | github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64= 270 | github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ= 271 | github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I= 272 | github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc= 273 | github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI= 274 | github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= 275 | github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= 276 | github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= 277 | github.com/imkira/go-interpol v1.1.0 h1:KIiKr0VSG2CUW1hl1jpiyuzuJeKUUpC8iM1AIE7N1Vk= 278 | github.com/imkira/go-interpol v1.1.0/go.mod h1:z0h2/2T3XF8kyEPpRgJ3kmNv+C43p+I/CoI+jC3w2iA= 279 | github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= 280 | github.com/joho/godotenv v1.3.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqxOKXbg= 281 | github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= 282 | github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= 283 | github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= 284 | github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= 285 | github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= 286 | github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= 287 | github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo= 288 | github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= 289 | github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= 290 | github.com/karrick/godirwalk v1.10.12/go.mod h1:RoGL9dQei4vP9ilrpETWE8CLOZ1kiN0LhBygSwrAsHA= 291 | github.com/karrick/godirwalk v1.16.1 h1:DynhcF+bztK8gooS0+NDJFrdNZjJ3gzVzC545UNA9iw= 292 | github.com/karrick/godirwalk v1.16.1/go.mod h1:j4mkqPuvaLI8mp1DroR3P6ad7cyYd4c1qeJ3RV7ULlk= 293 | github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= 294 | github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= 295 | github.com/klauspost/compress v1.8.2/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= 296 | github.com/klauspost/compress v1.17.6 h1:60eq2E/jlfwQXtvZEeBUYADs+BwKBWURIY+Gj2eRGjI= 297 | github.com/klauspost/compress v1.17.6/go.mod h1:/dCuZOvVtNoHsyb+cuJD3itjs3NbnF6KH9zAO4BDxPM= 298 | github.com/klauspost/cpuid v1.2.1/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek= 299 | github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= 300 | github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= 301 | github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= 302 | github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= 303 | github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= 304 | github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= 305 | github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= 306 | github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= 307 | github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= 308 | github.com/leodido/go-urn v1.1.0 h1:Sm1gr51B1kKyfD2BlRcLSiEkffoG96g6TPv6eRoEiB8= 309 | github.com/leodido/go-urn v1.1.0/go.mod h1:+cyI34gQWZcE1eQU7NVgKkkzdXDQHr1dBMtdAPozLkw= 310 | github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= 311 | github.com/lib/pq v1.3.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= 312 | github.com/lib/pq v1.10.5 h1:J+gdV2cUmX7ZqL2B0lFcW0m+egaHC2V3lpO8nWxyYiQ= 313 | github.com/lib/pq v1.10.5/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= 314 | github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= 315 | github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= 316 | github.com/magiconair/properties v1.8.5/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60= 317 | github.com/magiconair/properties v1.8.6 h1:5ibWZ6iY0NctNGWo87LalDlEZ6R41TqbbDamhfG/Qzo= 318 | github.com/magiconair/properties v1.8.6/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60= 319 | github.com/markbates/errx v1.1.0 h1:QDFeR+UP95dO12JgW+tgi2UVfo0V8YBHiUIOaeBPiEI= 320 | github.com/markbates/errx v1.1.0/go.mod h1:PLa46Oex9KNbVDZhKel8v1OT7hD5JZ2eI7AHhA0wswc= 321 | github.com/markbates/oncer v1.0.0 h1:E83IaVAHygyndzPimgUYJjbshhDTALZyXxvk9FOlQRY= 322 | github.com/markbates/oncer v1.0.0/go.mod h1:Z59JA581E9GP6w96jai+TGqafHPW+cPfRxz2aSZ0mcI= 323 | github.com/markbates/safe v1.0.1 h1:yjZkbvRM6IzKj9tlu/zMJLS0n/V351OZWRnF3QfaUxI= 324 | github.com/markbates/safe v1.0.1/go.mod h1:nAqgmRi7cY2nqMc92/bSEeQA+R4OheNU2T1kNSCBdG0= 325 | github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= 326 | github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= 327 | github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= 328 | github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= 329 | github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= 330 | github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= 331 | github.com/mattn/go-isatty v0.0.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2yME+cCiQ= 332 | github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= 333 | github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= 334 | github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= 335 | github.com/mattn/go-runewidth v0.0.7/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= 336 | github.com/mattn/go-sqlite3 v1.10.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= 337 | github.com/mattn/go-sqlite3 v2.0.3+incompatible h1:gXHsfypPkaMZrKbD5209QV9jbUTJKjyR5WD3HYQSd+U= 338 | github.com/mattn/go-sqlite3 v2.0.3+incompatible/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= 339 | github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= 340 | github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b h1:j7+1HpAFS1zy5+Q4qx1fWh90gTKwiN4QCGoY9TWyyO4= 341 | github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b/go.mod h1:01TrycV0kFyexm33Z7vhZRXopbI8J3TDReVlkTgMUxE= 342 | github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= 343 | github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc= 344 | github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= 345 | github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= 346 | github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI= 347 | github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS42BGNg= 348 | github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY= 349 | github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= 350 | github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= 351 | github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= 352 | github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= 353 | github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= 354 | github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= 355 | github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= 356 | github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= 357 | github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= 358 | github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= 359 | github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 h1:RWengNIwukTxcDr9M+97sNutRR1RKhG96O6jWumTTnw= 360 | github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826/go.mod h1:TaXosZuwdSHYgviHp1DAtfrULt5eUgsSMsZf+YrPgl8= 361 | github.com/moul/http2curl v1.0.0 h1:dRMWoAtb+ePxMlLkrCbAqh4TlPHXvoGUSQ323/9Zahs= 362 | github.com/moul/http2curl v1.0.0/go.mod h1:8UbvGypXm98wA/IqH45anm5Y2Z6ep6O31QGOAZ3H0fQ= 363 | github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= 364 | github.com/natefinch/lumberjack v2.0.0+incompatible/go.mod h1:Wi9p2TTF5DG5oU+6YfsmYQpsTIOm0B1VNzQg9Mw6nPk= 365 | github.com/olekukonko/tablewriter v0.0.1/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo= 366 | github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= 367 | github.com/onsi/ginkgo v1.7.0 h1:WSHQ+IS43OoUrWtD1/bbclrwK8TTH5hzp+umCiuxHgs= 368 | github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= 369 | github.com/onsi/gomega v1.4.3 h1:RE1xgDvH7imwFD45h+u2SgIfERHlS2yNG4DObb5BSKU= 370 | github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= 371 | github.com/openzipkin/zipkin-go v0.1.6/go.mod h1:QgAqvLzwWbR/WpD4A3cGpPtJrZXNIiJc5AZX7/PBEpw= 372 | github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= 373 | github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= 374 | github.com/pelletier/go-toml v1.9.3/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c= 375 | github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= 376 | github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= 377 | github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= 378 | github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I= 379 | github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= 380 | github.com/pkg/sftp v1.10.1/go.mod h1:lYOWFsE0bwd1+KfKJaKeuokY15vzFx25BLbzYYoAxZI= 381 | github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= 382 | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= 383 | github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= 384 | github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= 385 | github.com/prometheus/client_golang v0.9.3-0.20190127221311-3c4408c8b829/go.mod h1:p2iRAGwDERtqlqzRXnrOVns+ignqQo//hLXqYxZYVNs= 386 | github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= 387 | github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= 388 | github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= 389 | github.com/prometheus/common v0.2.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= 390 | github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= 391 | github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= 392 | github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= 393 | github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= 394 | github.com/rogpeppe/go-internal v1.1.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= 395 | github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= 396 | github.com/rogpeppe/go-internal v1.8.0/go.mod h1:WmiCO8CzOY8rg0OYDC4/i/2WRWAB6poM+XZ2dLUbcbE= 397 | github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= 398 | github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog= 399 | github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= 400 | github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= 401 | github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= 402 | github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= 403 | github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0= 404 | github.com/sclevine/agouti v3.0.0+incompatible h1:8IBJS6PWz3uTlMP3YBIR5f+KAldcGuOeFkFbUWfBgK4= 405 | github.com/sclevine/agouti v3.0.0+incompatible/go.mod h1:b4WX9W9L1sfQKXeJf1mUTLZKJ48R1S7H23Ji7oFO5Bw= 406 | github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= 407 | github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= 408 | github.com/sergi/go-diff v1.2.0 h1:XU+rvMAioB0UC3q1MFrIQy4Vo5/4VsRDQQXHsEya6xQ= 409 | github.com/sergi/go-diff v1.2.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= 410 | github.com/shirou/gopsutil v2.20.3+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA= 411 | github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= 412 | github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= 413 | github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= 414 | github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= 415 | github.com/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0= 416 | github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= 417 | github.com/smarty/assertions v1.15.1 h1:812oFiXI+G55vxsFf+8bIZ1ux30qtkdqzKbEFwyX3Tk= 418 | github.com/smarty/assertions v1.15.1/go.mod h1:yABtdzeQs6l1brC900WlRNwj6ZR55d7B+E8C6HtKdec= 419 | github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= 420 | github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= 421 | github.com/smartystreets/goconvey v1.8.1 h1:qGjIddxOk4grTu9JPOU31tVfq3cNdBlNa5sSznIX1xY= 422 | github.com/smartystreets/goconvey v1.8.1/go.mod h1:+/u4qLyY6x1jReYOp7GOM2FSt8aP9CzCZL03bI28W60= 423 | github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= 424 | github.com/spf13/afero v1.6.0/go.mod h1:Ai8FlHk4v/PARR026UzYexafAt9roJ7LcLMAmO6Z93I= 425 | github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= 426 | github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= 427 | github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU= 428 | github.com/spf13/cobra v1.2.1/go.mod h1:ExllRjgxM/piMAM+3tAZvg8fsklGAf3tPfi+i8t68Nk= 429 | github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= 430 | github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo= 431 | github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= 432 | github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= 433 | github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s= 434 | github.com/spf13/viper v1.8.1/go.mod h1:o0Pch8wJ9BVSWGQMbra6iw0oQ5oktSIBaujf1rJH9Ns= 435 | github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= 436 | github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= 437 | github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= 438 | github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= 439 | github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= 440 | github.com/stretchr/testify v1.2.3-0.20181224173747-660f15d67dbb/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= 441 | github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= 442 | github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= 443 | github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= 444 | github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= 445 | github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= 446 | github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= 447 | github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= 448 | github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= 449 | github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= 450 | github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= 451 | github.com/syndtr/goleveldb v1.0.0 h1:fBdIW9lB4Iz0n9khmH8w27SJ3QEJ7+IgjPEwGSZiFdE= 452 | github.com/syndtr/goleveldb v1.0.0/go.mod h1:ZVVdQEZoIme9iO1Ch2Jdy24qqXrMMOU6lpPAyBWyWuQ= 453 | github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw= 454 | github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= 455 | github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY= 456 | github.com/ugorji/go/codec v1.2.12 h1:9LC83zGrHhuUA9l16C9AHXAqEV/2wBQ4nkvumAE65EE= 457 | github.com/ugorji/go/codec v1.2.12/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg= 458 | github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw= 459 | github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= 460 | github.com/valyala/fasthttp v1.11.0/go.mod h1:FstJa9V+Pj9vQ7OJie2qMHdwemEDaDiSdBnvPM1Su9w= 461 | github.com/valyala/fasthttp v1.52.0 h1:wqBQpxH71XW0e2g+Og4dzQM8pk34aFYlA1Ga8db7gU0= 462 | github.com/valyala/fasthttp v1.52.0/go.mod h1:hf5C4QnVMkNXMspnsUlfM3WitlgYflyhHYoKol/szxQ= 463 | github.com/valyala/tcplisten v0.0.0-20161114210144-ceec8f93295a/go.mod h1:v3UYOV9WzVtRmSR+PDvWpU/qWl4Wa5LApYYX4ZtKbio= 464 | github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f h1:J9EGpcZtP0E/raorCMxlFGSTBrsSlaDGf3jU/qvAE2c= 465 | github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= 466 | github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 h1:EzJWgHovont7NscjpAxXsDA8S8BMYve8Y5+7cuRE7R0= 467 | github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ= 468 | github.com/xeipuuv/gojsonschema v1.2.0 h1:LhYJRs+L4fBtjZUfuSZIKGeVu0QRy8e5Xi7D17UxZ74= 469 | github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y= 470 | github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= 471 | github.com/yalp/jsonpath v0.0.0-20180802001716-5cc68e5049a0 h1:6fRhSjgLCkTD3JnJxvaJ4Sj+TYblw757bqYgZaOq5ZY= 472 | github.com/yalp/jsonpath v0.0.0-20180802001716-5cc68e5049a0/go.mod h1:/LWChgwKmvncFJFHJ7Gvn9wZArjbV5/FppcK2fKk/tI= 473 | github.com/yudai/gojsondiff v1.0.0 h1:27cbfqXLVEJ1o8I6v3y9lg8Ydm53EKqHXAOMxEGlCOA= 474 | github.com/yudai/gojsondiff v1.0.0/go.mod h1:AY32+k2cwILAkW1fbgxQ5mUmMiZFgLIV+FBNExI05xg= 475 | github.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82 h1:BHyfKlQyqbsFN5p3IfnEUduWvb9is428/nNb5L3U01M= 476 | github.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82/go.mod h1:lgjkn3NuSvDfVJdfcVVdX+jpBxNmX4rDAzaS45IcYoM= 477 | github.com/yudai/pp v2.0.1+incompatible h1:Q4//iY4pNF6yPLZIigmvcl7k/bPgrcTPIFIcmawg5bI= 478 | github.com/yudai/pp v2.0.1+incompatible/go.mod h1:PuxR/8QJ7cyCkFp/aUDS+JY727OFEZkTdatxwunjIkc= 479 | github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= 480 | github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= 481 | github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= 482 | github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= 483 | github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= 484 | github.com/yuin/goldmark v1.4.0/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= 485 | github.com/ziutek/mymysql v1.5.4/go.mod h1:LMSpPZ6DbqWFxNCHW77HeMg9I646SAhApZ/wKdgO/C0= 486 | go.etcd.io/etcd/api/v3 v3.5.0/go.mod h1:cbVKeC6lCfl7j/8jBhAK6aIYO9XOjdptoxU/nLQcPvs= 487 | go.etcd.io/etcd/client/pkg/v3 v3.5.0/go.mod h1:IJHfcCEKxYu1Os13ZdwCwIUTUVGYTSAM3YSwc9/Ac1g= 488 | go.etcd.io/etcd/client/v2 v2.305.0/go.mod h1:h9puh54ZTgAKtEbut2oe9P4L/oqKCVB6xsXlzd7alYQ= 489 | go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= 490 | go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= 491 | go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= 492 | go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= 493 | go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= 494 | go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= 495 | go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= 496 | go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E= 497 | go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= 498 | go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= 499 | go.uber.org/atomic v1.9.0 h1:ECmE8Bn/WFTYwEW/bpKD3M8VtR/zQVbavAoalC1PYyE= 500 | go.uber.org/atomic v1.9.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= 501 | go.uber.org/goleak v1.1.11-0.20210813005559-691160354723 h1:sHOAIxRGBp443oHZIPB+HsUGaksVCXVQENPxwTfQdH4= 502 | go.uber.org/goleak v1.1.11-0.20210813005559-691160354723/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= 503 | go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU= 504 | go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= 505 | go.uber.org/multierr v1.7.0 h1:zaiO/rmgFjbmCXdSYJWQcdvOCsthmdaHfr3Gm2Kx4Ec= 506 | go.uber.org/multierr v1.7.0/go.mod h1:7EAYxJLBy9rStEaz58O2t4Uvip6FSURkq8/ppBp95ak= 507 | go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA= 508 | go.uber.org/zap v1.14.1/go.mod h1:Mb2vm2krFEG5DV0W9qcHBYFtp/Wku1cvYaqPsS/WYfc= 509 | go.uber.org/zap v1.17.0/go.mod h1:MXVU+bhUf/A7Xi2HNOnopQOrmycQ5Ih87HtOu4q5SSo= 510 | go.uber.org/zap v1.19.1 h1:ue41HOKd1vGURxrmeKIgELGb3jPW9DMUDGtsinblHwI= 511 | go.uber.org/zap v1.19.1/go.mod h1:j3DNczoxDZroyBnOT1L/Q79cfUMGZxlv/9dzN7SM1rI= 512 | golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= 513 | golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= 514 | golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= 515 | golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= 516 | golang.org/x/crypto v0.0.0-20190325154230-a5d413f7728c/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= 517 | golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= 518 | golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= 519 | golang.org/x/crypto v0.0.0-20190621222207-cc06ce4a13d4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= 520 | golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= 521 | golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= 522 | golang.org/x/crypto v0.0.0-20200221231518-2aa609cf4a9d/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= 523 | golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= 524 | golang.org/x/crypto v0.22.0 h1:g1v0xeRhjcugydODzvb3mEM9SQ0HGp9s/nh3COQ/C30= 525 | golang.org/x/crypto v0.22.0/go.mod h1:vr6Su+7cTlO45qkww3VDJlzDn0ctJvRgYbC2NvXHt+M= 526 | golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= 527 | golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= 528 | golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= 529 | golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek= 530 | golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY= 531 | golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= 532 | golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= 533 | golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= 534 | golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= 535 | golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= 536 | golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= 537 | golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= 538 | golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= 539 | golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= 540 | golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= 541 | golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= 542 | golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= 543 | golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= 544 | golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= 545 | golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs= 546 | golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= 547 | golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= 548 | golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= 549 | golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= 550 | golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= 551 | golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= 552 | golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= 553 | golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= 554 | golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= 555 | golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= 556 | golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= 557 | golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= 558 | golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= 559 | golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= 560 | golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= 561 | golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= 562 | golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= 563 | golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= 564 | golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= 565 | golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= 566 | golang.org/x/net v0.0.0-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= 567 | golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= 568 | golang.org/x/net v0.0.0-20190125091013-d26f9f9a57f3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= 569 | golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= 570 | golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= 571 | golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= 572 | golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= 573 | golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= 574 | golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= 575 | golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= 576 | golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= 577 | golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= 578 | golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= 579 | golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= 580 | golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= 581 | golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= 582 | golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= 583 | golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= 584 | golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= 585 | golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= 586 | golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= 587 | golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= 588 | golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= 589 | golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= 590 | golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= 591 | golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= 592 | golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= 593 | golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= 594 | golang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= 595 | golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= 596 | golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= 597 | golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= 598 | golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= 599 | golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc= 600 | golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= 601 | golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= 602 | golang.org/x/net v0.24.0 h1:1PcaxkF854Fu3+lvBIx5SYn9wRlBzzcnHZSiaFFAb0w= 603 | golang.org/x/net v0.24.0/go.mod h1:2Q7sJY5mzlzWjKtYUEXSlBWCdyaioyXzRB2RtU8KVE8= 604 | golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= 605 | golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= 606 | golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= 607 | golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= 608 | golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= 609 | golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= 610 | golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= 611 | golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= 612 | golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= 613 | golang.org/x/oauth2 v0.0.0-20210220000619-9bb904979d93/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= 614 | golang.org/x/oauth2 v0.0.0-20210313182246-cd4f82c27b84/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= 615 | golang.org/x/oauth2 v0.0.0-20210402161424-2e8d93401602/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= 616 | golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 617 | golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 618 | golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 619 | golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 620 | golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 621 | golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 622 | golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 623 | golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 624 | golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 625 | golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 626 | golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 627 | golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= 628 | golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= 629 | golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 630 | golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 631 | golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 632 | golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 633 | golang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 634 | golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 635 | golang.org/x/sys v0.0.0-20181122145206-62eef0e2fa9b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 636 | golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 637 | golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 638 | golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 639 | golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 640 | golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 641 | golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 642 | golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 643 | golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 644 | golang.org/x/sys v0.0.0-20190515120540-06a5c4944438/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 645 | golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 646 | golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 647 | golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 648 | golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 649 | golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 650 | golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 651 | golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 652 | golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 653 | golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 654 | golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 655 | golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 656 | golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 657 | golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 658 | golang.org/x/sys v0.0.0-20200219091948-cb0a6d8edb6c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 659 | golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 660 | golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 661 | golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 662 | golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 663 | golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 664 | golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 665 | golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 666 | golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 667 | golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 668 | golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 669 | golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 670 | golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 671 | golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 672 | golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 673 | golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 674 | golang.org/x/sys v0.0.0-20210220050731-9a76102bfb43/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 675 | golang.org/x/sys v0.0.0-20210305230114-8fe3ee5dd75b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 676 | golang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 677 | golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 678 | golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 679 | golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 680 | golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 681 | golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 682 | golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 683 | golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 684 | golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 685 | golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 686 | golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 687 | golang.org/x/sys v0.19.0 h1:q5f1RH2jigJ1MoAWp2KTp3gm5zAGFUTarQZ5U386+4o= 688 | golang.org/x/sys v0.19.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= 689 | golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= 690 | golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= 691 | golang.org/x/term v0.0.0-20220722155259-a9ba230a4035/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= 692 | golang.org/x/term v0.19.0 h1:+ThwsDv+tYfnJFhF4L8jITxu1tdTWRTZpdsWgEgjL6Q= 693 | golang.org/x/term v0.19.0/go.mod h1:2CuTdWZ7KHSQwUzKva0cbMg6q2DMI3Mmxp+gKJbskEk= 694 | golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= 695 | golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= 696 | golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= 697 | golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= 698 | golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= 699 | golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= 700 | golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= 701 | golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= 702 | golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= 703 | golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= 704 | golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= 705 | golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= 706 | golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= 707 | golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= 708 | golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= 709 | golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= 710 | golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= 711 | golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= 712 | golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= 713 | golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= 714 | golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= 715 | golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= 716 | golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= 717 | golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= 718 | golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= 719 | golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= 720 | golang.org/x/tools v0.0.0-20190624180213-70d37148ca0c/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= 721 | golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= 722 | golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= 723 | golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= 724 | golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= 725 | golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= 726 | golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= 727 | golang.org/x/tools v0.0.0-20191112195655-aa38f8e97acc/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= 728 | golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= 729 | golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= 730 | golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= 731 | golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= 732 | golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= 733 | golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= 734 | golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= 735 | golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= 736 | golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= 737 | golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= 738 | golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= 739 | golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= 740 | golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= 741 | golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= 742 | golang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= 743 | golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= 744 | golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= 745 | golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8= 746 | golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= 747 | golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= 748 | golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= 749 | golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= 750 | golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= 751 | golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= 752 | golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= 753 | golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= 754 | golang.org/x/tools v0.0.0-20200904185747-39188db58858/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE= 755 | golang.org/x/tools v0.0.0-20201110124207-079ba7bd75cd/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= 756 | golang.org/x/tools v0.0.0-20201201161351-ac6f37ff4c2a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= 757 | golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= 758 | golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= 759 | golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= 760 | golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= 761 | golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= 762 | golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= 763 | golang.org/x/tools v0.1.7/go.mod h1:LGqMHiF4EqQNHR1JncWGqT5BVaXmza+X+BDGol+dOxo= 764 | golang.org/x/tools v0.20.0 h1:hz/CVckiOxybQvFw6h7b/q80NTr9IUQb4s1IIzW7KNY= 765 | golang.org/x/tools v0.20.0/go.mod h1:WvitBU7JJf6A4jOdg4S1tviW9bhUxkgeCui/0JHctQg= 766 | golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= 767 | golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= 768 | golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= 769 | golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= 770 | golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= 771 | google.golang.org/api v0.3.1/go.mod h1:6wY9I6uQWHQ8EM57III9mq/AjF+i8G65rmVagqKMtkk= 772 | google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= 773 | google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= 774 | google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= 775 | google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= 776 | google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= 777 | google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= 778 | google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= 779 | google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= 780 | google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= 781 | google.golang.org/api v0.19.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= 782 | google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= 783 | google.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= 784 | google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= 785 | google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= 786 | google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM= 787 | google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc= 788 | google.golang.org/api v0.35.0/go.mod h1:/XrVsuzM0rZmrsbjJutiuftIzeuTQcEeaYcSk/mQ1dg= 789 | google.golang.org/api v0.36.0/go.mod h1:+z5ficQTmoYpPn8LCUNVpK5I7hwkpjbcgqA7I34qYtE= 790 | google.golang.org/api v0.40.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjRCQ8= 791 | google.golang.org/api v0.41.0/go.mod h1:RkxM5lITDfTzmyKFPt+wGrCJbVfniCr2ool8kTBzRTU= 792 | google.golang.org/api v0.43.0/go.mod h1:nQsDGjRXMo4lvh5hP0TKqF244gqhGcr/YSIykhUk/94= 793 | google.golang.org/api v0.44.0/go.mod h1:EBOGZqzyhtvMDoxwS97ctnh0zUmYY6CxqXsc1AvkYD8= 794 | google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= 795 | google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= 796 | google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= 797 | google.golang.org/appengine v1.6.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= 798 | google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= 799 | google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= 800 | google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= 801 | google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= 802 | google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= 803 | google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= 804 | google.golang.org/genproto v0.0.0-20190404172233-64821d5d2107/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= 805 | google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= 806 | google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= 807 | google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= 808 | google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= 809 | google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= 810 | google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= 811 | google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= 812 | google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= 813 | google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= 814 | google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= 815 | google.golang.org/genproto v0.0.0-20200115191322-ca5a22157cba/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= 816 | google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= 817 | google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA= 818 | google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= 819 | google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= 820 | google.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= 821 | google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= 822 | google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= 823 | google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= 824 | google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= 825 | google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= 826 | google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= 827 | google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U= 828 | google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= 829 | google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA= 830 | google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= 831 | google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= 832 | google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= 833 | google.golang.org/genproto v0.0.0-20200904004341-0bd0a958aa1d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= 834 | google.golang.org/genproto v0.0.0-20201109203340-2640f1f9cdfb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= 835 | google.golang.org/genproto v0.0.0-20201201144952-b05cb90ed32e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= 836 | google.golang.org/genproto v0.0.0-20201210142538-e3217bee35cc/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= 837 | google.golang.org/genproto v0.0.0-20201214200347-8c77b98c765d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= 838 | google.golang.org/genproto v0.0.0-20210222152913-aa3ee6e6a81c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= 839 | google.golang.org/genproto v0.0.0-20210303154014-9728d6b83eeb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= 840 | google.golang.org/genproto v0.0.0-20210310155132-4ce2db91004e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= 841 | google.golang.org/genproto v0.0.0-20210319143718-93e7006c17a6/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= 842 | google.golang.org/genproto v0.0.0-20210402141018-6c239bbf2bb1/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A= 843 | google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= 844 | google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= 845 | google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= 846 | google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= 847 | google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= 848 | google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= 849 | google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= 850 | google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= 851 | google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= 852 | google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= 853 | google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60= 854 | google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= 855 | google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= 856 | google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= 857 | google.golang.org/grpc v1.31.1/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= 858 | google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0= 859 | google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= 860 | google.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA51WJ8= 861 | google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= 862 | google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= 863 | google.golang.org/grpc v1.36.1/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= 864 | google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= 865 | google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= 866 | google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= 867 | google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= 868 | google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= 869 | google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= 870 | google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= 871 | google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= 872 | google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= 873 | google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4= 874 | google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= 875 | google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= 876 | google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= 877 | google.golang.org/protobuf v1.32.0 h1:pPC6BG5ex8PDFnkbrGU3EixyhKcQ2aDuBS36lqK/C7I= 878 | google.golang.org/protobuf v1.32.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= 879 | gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= 880 | gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= 881 | gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= 882 | gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo= 883 | gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= 884 | gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= 885 | gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4= 886 | gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= 887 | gopkg.in/go-playground/assert.v1 v1.2.1 h1:xoYuJVE7KT85PYWrN730RguIQO0ePzVRfFMXadIrXTM= 888 | gopkg.in/go-playground/assert.v1 v1.2.1/go.mod h1:9RXL0bg/zibRAgZUYszZSwO/z8Y/a8bDuhia5mkpMnE= 889 | gopkg.in/go-playground/validator.v9 v9.29.1 h1:SvGtYmN60a5CVKTOzMSyfzWDeZRxRuGvRQyEAKbw1xc= 890 | gopkg.in/go-playground/validator.v9 v9.29.1/go.mod h1:+c9/zcJMFNgbLvly1L1V+PpxWdVbfP1avr/N00E2vyQ= 891 | gopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= 892 | gopkg.in/ini.v1 v1.62.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= 893 | gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA= 894 | gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= 895 | gopkg.in/natefinch/lumberjack.v2 v2.2.1 h1:bBRl1b0OH9s/DuPhuXpNl+VtCaJXFZ5/uEFST95x9zc= 896 | gopkg.in/natefinch/lumberjack.v2 v2.2.1/go.mod h1:YD8tP3GAjkrDg1eZH7EGmyESg/lsYskCTPBJVb9jqSc= 897 | gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= 898 | gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= 899 | gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= 900 | gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= 901 | gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= 902 | gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= 903 | gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= 904 | gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= 905 | gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= 906 | gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 907 | gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 908 | gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= 909 | gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 910 | honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= 911 | honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= 912 | honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= 913 | honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= 914 | honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= 915 | honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= 916 | honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= 917 | honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= 918 | rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= 919 | rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= 920 | rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= 921 | xorm.io/builder v0.3.7 h1:2pETdKRK+2QG4mLX4oODHEhn5Z8j1m8sXa7jfu+/SZI= 922 | xorm.io/builder v0.3.7/go.mod h1:aUW0S9eb9VCaPohFCH3j7czOx1PMW3i1HrSzbLYGBSE= 923 | xorm.io/xorm v1.0.2 h1:kZlCh9rqd1AzGwWitcrEEqHE1h1eaZE/ujU5/2tWEtg= 924 | xorm.io/xorm v1.0.2/go.mod h1:o4vnEsQ5V2F1/WK6w4XTwmiWJeGj82tqjAnHe44wVHY= 925 | -------------------------------------------------------------------------------- /guard/delete.go: -------------------------------------------------------------------------------- 1 | package guard 2 | 3 | import ( 4 | "path/filepath" 5 | "strings" 6 | 7 | errors "github.com/GoAdminGroup/filemanager/modules/error" 8 | "github.com/GoAdminGroup/filemanager/modules/util" 9 | "github.com/GoAdminGroup/go-admin/context" 10 | ) 11 | 12 | type DeleteParam struct { 13 | Path string 14 | Prefix string 15 | Error error 16 | Paths []string 17 | } 18 | 19 | func (g *Guardian) Delete(ctx *context.Context) { 20 | 21 | if !g.permissions.AllowDelete { 22 | ctx.SetUserValue(deleteParamKey, &DeleteParam{Error: errors.NoPermission}) 23 | ctx.Next() 24 | return 25 | } 26 | 27 | var ( 28 | relativePaths = ctx.FormValue("id") 29 | relativePathArr = strings.Split(relativePaths, ",") 30 | 31 | paths = make([]string, 0) 32 | ) 33 | 34 | for _, relativePath := range relativePathArr { 35 | path := filepath.Join(g.roots.GetPathFromPrefix(ctx), relativePath) 36 | 37 | if relativePath == "" || !strings.Contains(path, g.roots.GetPathFromPrefix(ctx)) || !util.FileExist(path) || strings.Contains(path, "..") { 38 | ctx.SetUserValue(deleteParamKey, &DeleteParam{Error: errors.DirIsNotExist}) 39 | ctx.Next() 40 | return 41 | } 42 | 43 | paths = append(paths, path) 44 | 45 | } 46 | ctx.SetUserValue(deleteParamKey, &DeleteParam{ 47 | Path: relativePaths, 48 | Paths: paths, 49 | Prefix: g.GetPrefix(ctx), 50 | }) 51 | ctx.Next() 52 | } 53 | 54 | func GetDeleteParam(ctx *context.Context) *DeleteParam { 55 | return ctx.UserValue[deleteParamKey].(*DeleteParam) 56 | } 57 | -------------------------------------------------------------------------------- /guard/files.go: -------------------------------------------------------------------------------- 1 | package guard 2 | 3 | import ( 4 | errors "github.com/GoAdminGroup/filemanager/modules/error" 5 | "github.com/GoAdminGroup/filemanager/modules/util" 6 | "github.com/GoAdminGroup/go-admin/context" 7 | ) 8 | 9 | type FilesParam struct { 10 | *Base 11 | } 12 | 13 | func (g *Guardian) Files(ctx *context.Context) { 14 | 15 | relativePath, path, err := g.getPaths(ctx) 16 | 17 | if !util.IsDirectory(path) { 18 | err = errors.IsNotDir 19 | } 20 | 21 | ctx.SetUserValue(filesParamKey, &FilesParam{ 22 | Base: &Base{ 23 | Path: relativePath, 24 | FullPath: path, 25 | Error: err, 26 | Prefix: g.GetPrefix(ctx), 27 | }, 28 | }) 29 | ctx.Next() 30 | } 31 | 32 | func GetFilesParam(ctx *context.Context) *FilesParam { 33 | return ctx.UserValue[filesParamKey].(*FilesParam) 34 | } 35 | -------------------------------------------------------------------------------- /guard/guard.go: -------------------------------------------------------------------------------- 1 | package guard 2 | 3 | import ( 4 | "net/url" 5 | "path/filepath" 6 | "strings" 7 | 8 | "github.com/GoAdminGroup/filemanager/modules/constant" 9 | errors "github.com/GoAdminGroup/filemanager/modules/error" 10 | "github.com/GoAdminGroup/filemanager/modules/permission" 11 | "github.com/GoAdminGroup/filemanager/modules/root" 12 | "github.com/GoAdminGroup/filemanager/modules/util" 13 | "github.com/GoAdminGroup/go-admin/context" 14 | "github.com/GoAdminGroup/go-admin/modules/db" 15 | ) 16 | 17 | type Guardian struct { 18 | conn db.Connection 19 | roots root.Roots 20 | permissions permission.Permission 21 | } 22 | 23 | func New(r root.Roots, c db.Connection, p permission.Permission) *Guardian { 24 | return &Guardian{ 25 | roots: r, 26 | conn: c, 27 | permissions: p, 28 | } 29 | } 30 | 31 | func (g *Guardian) Update(r root.Roots, p permission.Permission) { 32 | g.roots = r 33 | g.permissions = p 34 | } 35 | 36 | const ( 37 | filesParamKey = "files_param" 38 | uploadParamKey = "upload_param" 39 | createDirParamKey = "create_dir_param" 40 | deleteParamKey = "delete_param" 41 | renameParamKey = "rename_param" 42 | previewParamKey = "preview_param" 43 | ) 44 | 45 | type Base struct { 46 | Path string 47 | Prefix string 48 | FullPath string 49 | Error error 50 | } 51 | 52 | func (g *Guardian) GetPrefix(ctx *context.Context) string { 53 | prefix := ctx.Query(constant.PrefixKey) 54 | if prefix == "" { 55 | if _, ok := g.roots["def"]; ok { 56 | return "def" 57 | } else { 58 | for name := range g.roots { 59 | return name 60 | } 61 | } 62 | } 63 | return prefix 64 | } 65 | 66 | func (g *Guardian) getPaths(ctx *context.Context) (string, string, error) { 67 | var ( 68 | err error 69 | 70 | relativePath, _ = url.QueryUnescape(ctx.Query("path")) 71 | path = filepath.Join(g.roots.GetPathFromPrefix(ctx), relativePath) 72 | ) 73 | if !strings.Contains(path, g.roots.GetPathFromPrefix(ctx)) { 74 | err = errors.DirIsNotExist 75 | } 76 | 77 | if !util.FileExist(path) { 78 | err = errors.DirIsNotExist 79 | } 80 | 81 | return relativePath, path, err 82 | } 83 | -------------------------------------------------------------------------------- /guard/move.go: -------------------------------------------------------------------------------- 1 | package guard 2 | 3 | import ( 4 | "path/filepath" 5 | 6 | errors "github.com/GoAdminGroup/filemanager/modules/error" 7 | "github.com/GoAdminGroup/filemanager/modules/util" 8 | "github.com/GoAdminGroup/go-admin/context" 9 | ) 10 | 11 | type MoveParam struct { 12 | Src string 13 | Dist string 14 | Prefix string 15 | Error error 16 | } 17 | 18 | func (g *Guardian) Move(ctx *context.Context) { 19 | 20 | distDir := ctx.FormValue("dist") 21 | src := ctx.FormValue("src") 22 | 23 | if src == "" || distDir == "" { 24 | ctx.SetUserValue(deleteParamKey, &MoveParam{Error: errors.EmptyName}) 25 | ctx.Next() 26 | return 27 | } 28 | 29 | if distDir == "/" { 30 | distDir = "" 31 | } 32 | 33 | distDir = g.roots.GetPathFromPrefix(ctx) + distDir 34 | src = g.roots.GetPathFromPrefix(ctx) + src 35 | 36 | if !util.IsDirectory(distDir) { 37 | ctx.SetUserValue(deleteParamKey, &MoveParam{Error: errors.IsNotDir}) 38 | ctx.Next() 39 | return 40 | } 41 | 42 | ctx.SetUserValue(deleteParamKey, &MoveParam{ 43 | Src: src, 44 | Dist: distDir + "/" + filepath.Base(src), 45 | Prefix: g.GetPrefix(ctx), 46 | }) 47 | ctx.Next() 48 | } 49 | 50 | func GetMoveParam(ctx *context.Context) *MoveParam { 51 | return ctx.UserValue[deleteParamKey].(*MoveParam) 52 | } 53 | -------------------------------------------------------------------------------- /guard/preview.go: -------------------------------------------------------------------------------- 1 | package guard 2 | 3 | import ( 4 | "github.com/GoAdminGroup/filemanager/modules/constant" 5 | errors "github.com/GoAdminGroup/filemanager/modules/error" 6 | "github.com/GoAdminGroup/filemanager/modules/util" 7 | "github.com/GoAdminGroup/go-admin/context" 8 | ) 9 | 10 | type PreviewParam struct { 11 | Base 12 | } 13 | 14 | func (g *Guardian) Preview(ctx *context.Context) { 15 | 16 | relativePath, path, err := g.getPaths(ctx) 17 | 18 | if !util.IsFile(path) { 19 | err = errors.IsNotFile 20 | } 21 | 22 | ctx.SetUserValue(previewParamKey, &PreviewParam{ 23 | Base: Base{ 24 | Path: relativePath, 25 | FullPath: path, 26 | Error: err, 27 | Prefix: ctx.Query(constant.PrefixKey), 28 | }, 29 | }) 30 | ctx.Next() 31 | } 32 | 33 | func GetPreviewParam(ctx *context.Context) *PreviewParam { 34 | return ctx.UserValue[previewParamKey].(*PreviewParam) 35 | } 36 | -------------------------------------------------------------------------------- /guard/rename.go: -------------------------------------------------------------------------------- 1 | package guard 2 | 3 | import ( 4 | "path/filepath" 5 | 6 | errors "github.com/GoAdminGroup/filemanager/modules/error" 7 | "github.com/GoAdminGroup/filemanager/modules/util" 8 | "github.com/GoAdminGroup/go-admin/context" 9 | ) 10 | 11 | type RenameParam struct { 12 | Src string 13 | Dist string 14 | Error error 15 | Prefix string 16 | } 17 | 18 | func (g *Guardian) Rename(ctx *context.Context) { 19 | 20 | distName := ctx.FormValue("name") 21 | src := ctx.FormValue("path") 22 | 23 | if src == "" || src == "/" || distName == "" || distName == "/" { 24 | ctx.SetUserValue(renameParamKey, &RenameParam{Error: errors.EmptyName}) 25 | ctx.Next() 26 | return 27 | } 28 | 29 | if filepath.Ext(distName) == "" && util.IsFile(g.roots.GetPathFromPrefix(ctx)+src) { 30 | distName += filepath.Ext(src) 31 | } 32 | 33 | ctx.SetUserValue(renameParamKey, &RenameParam{ 34 | Src: g.roots.GetPathFromPrefix(ctx) + src, 35 | Dist: g.roots.GetPathFromPrefix(ctx) + filepath.Dir(src) + "/" + distName, 36 | Prefix: g.GetPrefix(ctx), 37 | }) 38 | ctx.Next() 39 | } 40 | 41 | func GetRenameParam(ctx *context.Context) *RenameParam { 42 | return ctx.UserValue[renameParamKey].(*RenameParam) 43 | } 44 | -------------------------------------------------------------------------------- /guard/upload.go: -------------------------------------------------------------------------------- 1 | package guard 2 | 3 | import ( 4 | "mime/multipart" 5 | "path/filepath" 6 | "strings" 7 | 8 | "github.com/GoAdminGroup/filemanager/modules/constant" 9 | errors "github.com/GoAdminGroup/filemanager/modules/error" 10 | "github.com/GoAdminGroup/filemanager/modules/util" 11 | "github.com/GoAdminGroup/go-admin/context" 12 | ) 13 | 14 | type UploadParam struct { 15 | Base 16 | Files map[string][]*multipart.FileHeader 17 | } 18 | 19 | func (g *Guardian) Upload(ctx *context.Context) { 20 | 21 | if !g.permissions.AllowUpload { 22 | ctx.SetUserValue(uploadParamKey, &UploadParam{Base: Base{Error: errors.NoPermission}}) 23 | ctx.Next() 24 | return 25 | } 26 | 27 | relativePath, path, err := g.getPaths(ctx) 28 | 29 | if !util.IsDirectory(path) { 30 | ctx.SetUserValue(uploadParamKey, &UploadParam{ 31 | Base: Base{Error: errors.IsNotDir}, 32 | }) 33 | ctx.Next() 34 | return 35 | } 36 | 37 | files := ctx.Request.MultipartForm.File 38 | 39 | if len(files) == 0 { 40 | err = errors.NoFile 41 | } 42 | 43 | ctx.SetUserValue(uploadParamKey, &UploadParam{ 44 | Base: Base{ 45 | Path: relativePath, 46 | FullPath: path, 47 | Error: err, 48 | Prefix: ctx.Query(constant.PrefixKey), 49 | }, 50 | Files: files, 51 | }) 52 | ctx.Next() 53 | } 54 | 55 | func GetUploadParam(ctx *context.Context) *UploadParam { 56 | return ctx.UserValue[uploadParamKey].(*UploadParam) 57 | } 58 | 59 | type CreateDirParam struct { 60 | Base 61 | Dir string 62 | } 63 | 64 | func (g *Guardian) CreateDir(ctx *context.Context) { 65 | 66 | if !g.permissions.AllowCreateDir { 67 | ctx.SetUserValue(createDirParamKey, &CreateDirParam{Base: Base{Error: errors.NoPermission}}) 68 | ctx.Next() 69 | return 70 | } 71 | 72 | var ( 73 | relativePath = ctx.FormValue("path") 74 | 75 | name = ctx.FormValue("name") 76 | path = filepath.Join(g.roots.GetPathFromPrefix(ctx), relativePath) 77 | ) 78 | 79 | if name == "" || !strings.Contains(path, g.roots.GetPathFromPrefix(ctx)) { 80 | ctx.SetUserValue(createDirParamKey, &CreateDirParam{ 81 | Base: Base{Error: errors.DirIsNotExist}, 82 | }) 83 | ctx.Next() 84 | return 85 | } 86 | 87 | if !util.FileExist(path) { 88 | ctx.SetUserValue(createDirParamKey, &CreateDirParam{ 89 | Base: Base{Error: errors.DirIsNotExist}, 90 | }) 91 | ctx.Next() 92 | return 93 | } 94 | 95 | if !util.IsDirectory(path) { 96 | ctx.SetUserValue(createDirParamKey, &CreateDirParam{ 97 | Base: Base{Error: errors.IsNotDir}, 98 | }) 99 | ctx.Next() 100 | return 101 | } 102 | 103 | ctx.SetUserValue(createDirParamKey, &CreateDirParam{ 104 | Base: Base{ 105 | Path: relativePath, 106 | FullPath: path, 107 | Prefix: ctx.Query(constant.PrefixKey), 108 | }, 109 | Dir: path + "/" + name, 110 | }) 111 | ctx.Next() 112 | } 113 | 114 | func GetCreateDirParam(ctx *context.Context) *CreateDirParam { 115 | return ctx.UserValue[createDirParamKey].(*CreateDirParam) 116 | } 117 | -------------------------------------------------------------------------------- /installation.go: -------------------------------------------------------------------------------- 1 | package filemanager 2 | 3 | import ( 4 | "encoding/json" 5 | "strings" 6 | 7 | "github.com/GoAdminGroup/go-admin/modules/db/dialect" 8 | "github.com/GoAdminGroup/go-admin/modules/logger" 9 | "github.com/GoAdminGroup/go-admin/modules/menu" 10 | form2 "github.com/GoAdminGroup/go-admin/plugins/admin/modules/form" 11 | "github.com/GoAdminGroup/go-admin/plugins/admin/modules/parameter" 12 | "github.com/GoAdminGroup/go-admin/template/icon" 13 | 14 | errors "github.com/GoAdminGroup/filemanager/modules/error" 15 | language2 "github.com/GoAdminGroup/filemanager/modules/language" 16 | "github.com/GoAdminGroup/filemanager/modules/permission" 17 | "github.com/GoAdminGroup/filemanager/modules/root" 18 | "github.com/GoAdminGroup/go-admin/context" 19 | "github.com/GoAdminGroup/go-admin/modules/config" 20 | "github.com/GoAdminGroup/go-admin/modules/db" 21 | "github.com/GoAdminGroup/go-admin/modules/utils" 22 | "github.com/GoAdminGroup/go-admin/plugins/admin/modules/table" 23 | "github.com/GoAdminGroup/go-admin/template/types" 24 | "github.com/GoAdminGroup/go-admin/template/types/form" 25 | ) 26 | 27 | func (f *FileManager) GetSettingPage() table.Generator { 28 | return func(ctx *context.Context) (fileManagerConfiguration table.Table) { 29 | 30 | cfg := table.DefaultConfigWithDriver(config.GetDatabases().GetDefault().Driver) 31 | 32 | message1 := "install" 33 | message2 := "installation" 34 | 35 | if !f.IsInstalled() { 36 | cfg = cfg.SetOnlyNewForm() 37 | } else { 38 | 39 | message1 = "update" 40 | message2 = "setting" 41 | 42 | cfg = cfg.SetOnlyUpdateForm().SetGetDataFun(func(params parameter.Parameters) ([]map[string]interface{}, int) { 43 | 44 | var m = make([]map[string]interface{}, 1) 45 | 46 | item, err := db.WithDriver(f.Conn). 47 | Table("goadmin_site"). 48 | Where("key", "=", ConnectionKey). 49 | First() 50 | 51 | if db.CheckError(err, db.QUERY) { 52 | return m, 1 53 | } 54 | 55 | items, err := db.WithDriverAndConnection(item["value"].(string), f.Conn).Table(TableName).All() 56 | if db.CheckError(err, db.QUERY) { 57 | return m, 1 58 | } 59 | 60 | m[0] = make(map[string]interface{}) 61 | names, titles, paths := make([]string, 0), make([]string, 0), make([]string, 0) 62 | for _, item := range items { 63 | if item["key"].(string) == "roots" { 64 | rootsMap := make(root.Roots) 65 | _ = json.Unmarshal([]byte(item["value"].(string)), &rootsMap) 66 | for name, value := range rootsMap { 67 | names = append(names, name) 68 | titles = append(titles, value.Title) 69 | paths = append(paths, value.Path) 70 | } 71 | } else { 72 | if item["value"] == "1" { 73 | m[0][item["key"].(string)] = 1 74 | } else if item["value"] == "0" { 75 | m[0][item["key"].(string)] = 0 76 | } else { 77 | m[0][item["key"].(string)] = item["value"] 78 | } 79 | } 80 | } 81 | 82 | m[0]["id"] = "1" 83 | m[0]["name"] = strings.Join(names, ",") 84 | m[0]["title"] = strings.Join(titles, ",") 85 | m[0]["path"] = strings.Join(paths, ",") 86 | 87 | return m, 1 88 | }) 89 | } 90 | 91 | fileManagerConfiguration = table.NewDefaultTable(ctx, cfg) 92 | 93 | formList := fileManagerConfiguration.GetForm(). 94 | AddXssJsFilter(). 95 | HideBackButton(). 96 | HideContinueNewCheckBox(). 97 | HideResetButton() 98 | 99 | connNames := config.GetDatabases().Connections() 100 | ops := make(types.FieldOptions, len(connNames)) 101 | for i, name := range connNames { 102 | ops[i] = types.FieldOption{Text: name, Value: name} 103 | } 104 | 105 | formList.AddField(language2.Get("Connection"), "conn", db.Varchar, form.SelectSingle). 106 | FieldOptions(ops).FieldHelpMsg(language2.GetHTML("sqlite3 need to import the sql first")) 107 | 108 | formList.AddRow(func(panel *types.FormPanel) { 109 | panel.AddField(language2.Get("allow upload"), "allowUpload", db.Int, form.Switch).FieldOptions(types.FieldOptions{ 110 | {Value: "1", Text: language2.Get("yes")}, 111 | {Value: "0", Text: language2.Get("no")}, 112 | }).FieldDefault("1").FieldRowWidth(3) 113 | panel.AddField(language2.Get("allow createdir"), "allowCreateDir", db.Int, form.Switch).FieldOptions(types.FieldOptions{ 114 | {Value: "1", Text: language2.Get("yes")}, 115 | {Value: "0", Text: language2.Get("no")}, 116 | }).FieldDefault("1").FieldRowWidth(4).FieldHeadWidth(4) 117 | }) 118 | 119 | formList.AddRow(func(panel *types.FormPanel) { 120 | panel.AddField(language2.Get("allow delete"), "allowDelete", db.Int, form.Switch).FieldOptions(types.FieldOptions{ 121 | {Value: "1", Text: language2.Get("yes")}, 122 | {Value: "0", Text: language2.Get("no")}, 123 | }).FieldDefault("1").FieldRowWidth(3) 124 | panel.AddField(language2.Get("allow move"), "allowMove", db.Int, form.Switch).FieldOptions(types.FieldOptions{ 125 | {Value: "1", Text: language2.Get("yes")}, 126 | {Value: "0", Text: language2.Get("no")}, 127 | }).FieldDefault("1").FieldRowWidth(4).FieldHeadWidth(4) 128 | }) 129 | 130 | formList.AddRow(func(panel *types.FormPanel) { 131 | panel.AddField(language2.Get("allow rename"), "allowRename", db.Int, form.Switch).FieldOptions(types.FieldOptions{ 132 | {Value: "1", Text: language2.Get("yes")}, 133 | {Value: "0", Text: language2.Get("no")}, 134 | }).FieldDefault("1").FieldRowWidth(3) 135 | panel.AddField(language2.Get("allow download"), "allowDownload", db.Int, form.Switch).FieldOptions(types.FieldOptions{ 136 | {Value: "1", Text: language2.Get("yes")}, 137 | {Value: "0", Text: language2.Get("no")}, 138 | }).FieldDefault("1").FieldRowWidth(4).FieldHeadWidth(4) 139 | }) 140 | 141 | formList.AddTable(language2.Get("roots"), "roots", func(panel *types.FormPanel) { 142 | panel.AddField(language2.Get("name"), "name", db.Varchar, form.Text).FieldHideLabel(). 143 | FieldDisplay(func(value types.FieldModel) interface{} { 144 | return strings.Split(value.Value, ",") 145 | }) 146 | panel.AddField(language2.Get("title"), "title", db.Varchar, form.Text).FieldHideLabel(). 147 | FieldDisplay(func(value types.FieldModel) interface{} { 148 | return strings.Split(value.Value, ",") 149 | }) 150 | panel.AddField(language2.Get("path"), "path", db.Varchar, form.Text).FieldHideLabel(). 151 | FieldDisplay(func(value types.FieldModel) interface{} { 152 | return strings.Split(value.Value, ",") 153 | }) 154 | }) 155 | 156 | var updateInsertFn = func(values form2.Values) error { 157 | connName := values.Get("conn") 158 | if connName == "" { 159 | return errors.EmptyConnectionName 160 | } 161 | tables, err := db.WithDriver(f.Conn).Table(f.Conn.GetConfig(connName).Name).ShowTables() 162 | if err != nil { 163 | logger.Error("filemanager get sql tables error: ", err) 164 | return err 165 | } 166 | var rootsMap = make(root.Roots, len(values["name"])) 167 | for k, name := range values["name"] { 168 | 169 | if f.pathValidator != nil { 170 | err = f.pathValidator(values["path"][k]) 171 | if err != nil { 172 | return err 173 | } 174 | } 175 | 176 | rootsMap[name] = root.Root{ 177 | Path: values["path"][k], 178 | Title: values["title"][k], 179 | } 180 | 181 | if !f.IsInstalled() { 182 | _, err := f.NewMenu(menu.NewMenuData{ 183 | Order: int64(k), 184 | Title: values["title"][k], 185 | Icon: icon.FolderO, 186 | PluginName: f.Name(), 187 | Uri: "/" + f.URLPrefix + "/" + name + "/list", 188 | Uuid: "fm_" + name, 189 | }) 190 | 191 | if err != nil { 192 | logger.Error("filemanager insert menu error: ", err) 193 | } 194 | } 195 | } 196 | roots, _ := json.Marshal(rootsMap) 197 | 198 | if !utils.InArray(tables, TableName) { 199 | err = f.Conn.CreateDB(connName, new(Table)) 200 | if err != nil { 201 | logger.Error("filemanager create database table error: ", err) 202 | return err 203 | } 204 | _, err = db.WithDriverAndConnection(connName, f.Conn). 205 | Table(TableName). 206 | Insert(dialect.H{ 207 | "key": "roots", 208 | "value": roots, 209 | }) 210 | if db.CheckError(err, db.INSERT) { 211 | return err 212 | } 213 | values = values.RemoveSysRemark() 214 | for key, value := range values { 215 | if key != "name" && key != "path" && key != "title" && key != "roots" && 216 | !strings.Contains(key, "__checkbox__") { 217 | _, _ = db.WithDriverAndConnection(connName, f.Conn). 218 | Table(TableName). 219 | Insert(dialect.H{ 220 | "key": key, 221 | "value": value[0], 222 | }) 223 | } 224 | } 225 | } else { 226 | _, err = db.WithDriverAndConnection(connName, f.Conn). 227 | Table(TableName). 228 | Where("key", "=", "roots"). 229 | Update(dialect.H{ 230 | "value": roots, 231 | }) 232 | if db.CheckError(err, db.UPDATE) { 233 | return err 234 | } 235 | 236 | values = values.RemoveSysRemark() 237 | for key, value := range values { 238 | if key != "name" && key != "path" && key != "title" && key != "roots" && 239 | !strings.Contains(key, "__checkbox__") { 240 | _, _ = db.WithDriverAndConnection(connName, f.Conn). 241 | Table(TableName). 242 | Where("key", "=", key). 243 | Update(dialect.H{ 244 | "value": value[0], 245 | }) 246 | } 247 | } 248 | } 249 | 250 | checkExist, _ := db.WithDriver(f.Conn). 251 | Table("goadmin_site"). 252 | Where("key", "=", ConnectionKey). 253 | First() 254 | 255 | if checkExist != nil { 256 | _, _ = db.WithDriver(f.Conn). 257 | Table("goadmin_site"). 258 | Where("key", "=", ConnectionKey). 259 | Update(dialect.H{ 260 | "value": connName, 261 | }) 262 | } else { 263 | _, _ = db.WithDriver(f.Conn). 264 | Table("goadmin_site"). 265 | Insert(dialect.H{ 266 | "key": ConnectionKey, 267 | "value": connName, 268 | }) 269 | } 270 | 271 | p := permission.Permission{ 272 | AllowUpload: values.Get("allowUpload") == "1", 273 | AllowCreateDir: values.Get("allowCreateDir") == "1", 274 | AllowDelete: values.Get("allowDelete") == "1", 275 | AllowMove: values.Get("allowMove") == "1", 276 | AllowRename: values.Get("allowRename") == "1", 277 | AllowDownload: values.Get("allowDownload") == "1", 278 | } 279 | 280 | f.roots = rootsMap 281 | f.handler.Update(f.roots, p) 282 | f.guard.Update(f.roots, p) 283 | 284 | return nil 285 | } 286 | 287 | formList.SetInsertFn(updateInsertFn) 288 | formList.SetUpdateFn(updateInsertFn) 289 | 290 | formList.EnableAjaxData(types.AjaxData{ 291 | SuccessTitle: language2.Get(message1 + " success"), 292 | ErrorTitle: language2.Get(message1 + " fail"), 293 | SuccessJumpURL: config.Prefix() + "/fm", 294 | }).SetFormNewTitle(language2.GetHTML("filemanager " + message2)). 295 | SetTitle(language2.Get("filemanager " + message2)). 296 | SetFormNewBtnWord(language2.GetHTML(message1)) 297 | 298 | return 299 | } 300 | } 301 | -------------------------------------------------------------------------------- /models/file.go: -------------------------------------------------------------------------------- 1 | package models 2 | 3 | type File struct { 4 | Name string `json:"name"` // 文件名 5 | IsDirectory bool `json:"isDirectory"` // 是否是文件夹 6 | Size int `json:"size"` // 大小 7 | Extension string `json:"extension"` // 扩展名 8 | Mime string `json:"mime"` // 媒体类型 9 | Path string `json:"path"` // 相对路径(相对于storagePath) 10 | LastModified int64 `json:"lastModified"` // 最后修改时间 Unix Timestamp seconds 11 | Content string `json:"content"` //只有文件有内容显示 12 | } 13 | 14 | type Files []File 15 | -------------------------------------------------------------------------------- /modules/constant/constant.go: -------------------------------------------------------------------------------- 1 | package constant 2 | 3 | const ( 4 | PrefixKey = "__prefix" 5 | ) 6 | -------------------------------------------------------------------------------- /modules/error/error.go: -------------------------------------------------------------------------------- 1 | package errors 2 | 3 | import ( 4 | "errors" 5 | 6 | "github.com/GoAdminGroup/filemanager/modules/language" 7 | ) 8 | 9 | var ( 10 | DirIsNotExist error 11 | WrongPrefix error 12 | IsNotDir error 13 | IsNotFile error 14 | EmptyName error 15 | NoFile error 16 | NoPermission error 17 | EmptyConnectionName error 18 | ) 19 | 20 | func Init() { 21 | DirIsNotExist = errors.New(language.Get("not exist")) 22 | IsNotDir = errors.New(language.Get("is not a dir")) 23 | IsNotFile = errors.New(language.Get("is not a file")) 24 | EmptyName = errors.New(language.Get("empty name")) 25 | NoFile = errors.New(language.Get("no files")) 26 | NoPermission = errors.New(language.Get("no permission")) 27 | WrongPrefix = errors.New(language.Get("wrong prefix")) 28 | EmptyConnectionName = errors.New(language.Get("empty connection name")) 29 | } 30 | -------------------------------------------------------------------------------- /modules/language/cn.go: -------------------------------------------------------------------------------- 1 | package language 2 | 3 | import "github.com/GoAdminGroup/go-admin/modules/language" 4 | 5 | var CN = language.LangSet{ 6 | "filemanager.not exist": "不存在", 7 | "filemanager.is not a dir": "不是文件夹", 8 | "filemanager.is not a file": "不是文件", 9 | "filemanager.filemanager": "文件管理器", 10 | 11 | "filemanager.a plugin help you manage files in your server": "文件管理插件,帮助您管理服务器文件。", 12 | "filemanager.official": "GoAdmin官方", 13 | 14 | "filemanager.filename": "名称", 15 | "filemanager.size": "大小", 16 | "filemanager.last modify time": "最后修改时间", 17 | "filemanager.operation": "操作", 18 | 19 | "filemanager.download": "下载", 20 | 21 | "filemanager.home": "根目录", 22 | "filemanager.last": "上一层", 23 | "filemanager.upload": "上传", 24 | "filemanager.upload success": "上传成功", 25 | "filemanager.new directory": "新建文件夹", 26 | "filemanager.create": "创建", 27 | "filemanager.input name": "输入名称", 28 | "filemanager.create success": "创建成功", 29 | 30 | "filemanager.delete": "删除", 31 | "filemanager.rename": "重命名", 32 | "filemanager.move": "移动", 33 | "filemanager.move success": "移动成功", 34 | 35 | "filemanager.rename success": "重命名成功", 36 | "filemanager.no permission": "没有权限", 37 | "filemanager.no files": "没有文件", 38 | "filemanager.no supported": "暂不支持该文件格式文件预览", 39 | 40 | "filemanager.title": "标题", 41 | "filemanager.name": "标志", 42 | "filemanager.path": "路径", 43 | "filemanager.roots": "监听文件夹路径", 44 | 45 | "filemanager.allow upload": "允许上传", 46 | "filemanager.allow createdir": "允许创建文件夹", 47 | "filemanager.allow delete": "允许删除", 48 | "filemanager.allow move": "允许移动", 49 | "filemanager.allow rename": "允许重命名", 50 | "filemanager.allow download": "允许下载", 51 | 52 | "filemanager.connection": "连接", 53 | 54 | "filemanager.yes": "是", 55 | "filemanager.no": "否", 56 | 57 | "filemanager.install": "安装", 58 | "filemanager.install success": "安装成功", 59 | "filemanager.install fail": "安装失败", 60 | "filemanager.update": "设置", 61 | "filemanager.update success": "设置成功", 62 | "filemanager.update fail": "设置失败", 63 | "filemanager.filemanager setting": "文件管理器设置", 64 | 65 | "filemanager.filemanager installation": "安装文件管理器", 66 | 67 | "filemanager.sqlite3 need to import the sql first": "如果使用sqlite3,需要先导入执行安装sql", 68 | } 69 | -------------------------------------------------------------------------------- /modules/language/en.go: -------------------------------------------------------------------------------- 1 | package language 2 | 3 | import "github.com/GoAdminGroup/go-admin/modules/language" 4 | 5 | var EN = language.LangSet{ 6 | "filemanager.not exist": "Not Exist", 7 | "filemanager.is not a dir": "It is not a directory", 8 | "filemanager.is not a file": "It is not a file", 9 | "filemanager.filemanager": "File Manager", 10 | 11 | "filemanager.a plugin help you manage files in your server": "A plugin help you manage files in your server", 12 | "filemanager.official": "Official", 13 | 14 | "filemanager.filename": "Name", 15 | "filemanager.size": "Size", 16 | "filemanager.last modify time": "Last Modified Time", 17 | "filemanager.operation": "Operation", 18 | 19 | "filemanager.download": "Download", 20 | "filemanager.delete": "Delete", 21 | "filemanager.move": "Move", 22 | "filemanager.rename": "Rename", 23 | 24 | "filemanager.home": "Root", 25 | "filemanager.last": "Last", 26 | "filemanager.upload": "Upload", 27 | "filemanager.upload success": "Upload Succeed", 28 | "filemanager.new directory": "Create Directory", 29 | "filemanager.create": "Create", 30 | "filemanager.input name": "Input Name", 31 | "filemanager.create success": "Create Succeed", 32 | "filemanager.move success": "Move Succeed", 33 | 34 | "filemanager.rename success": "Rename Succeed", 35 | "filemanager.no permission": "No Permission", 36 | "filemanager.no files": "No Files", 37 | "filemanager.no supported": "No supported yet", 38 | 39 | "filemanager.title": "Title", 40 | "filemanager.name": "Name", 41 | "filemanager.path": "Path", 42 | "filemanager.roots": "Monitoring Folder Path", 43 | 44 | "filemanager.allow upload": "Allow Upload", 45 | "filemanager.allow createdir": "Allow CreateDir", 46 | "filemanager.allow delete": "Allow Delete", 47 | "filemanager.allow move": "Allow Move", 48 | "filemanager.allow rename": "Allow Rename", 49 | "filemanager.allow download": "Allow Download", 50 | 51 | "filemanager.connection": "Connection", 52 | 53 | "filemanager.yes": "Yes", 54 | "filemanager.no": "No", 55 | 56 | "filemanager.install": "Installation", 57 | "filemanager.install success": "Install Success", 58 | "filemanager.install fail": "Install Fail", 59 | "filemanager.update": "Update", 60 | "filemanager.update success": "Update Success", 61 | "filemanager.update fail": "Update Fail ", 62 | "filemanager.filemanager setting": "FileManager Setting", 63 | 64 | "filemanager.filemanager installation": "FileManager Installation", 65 | 66 | "filemanager.sqlite3 need to import the sql first": "sqlite3 need to import and execute the sql command first", 67 | } 68 | -------------------------------------------------------------------------------- /modules/language/language.go: -------------------------------------------------------------------------------- 1 | package language 2 | 3 | import ( 4 | "html/template" 5 | 6 | "github.com/GoAdminGroup/go-admin/modules/language" 7 | ) 8 | 9 | func Get(key string) string { 10 | return language.GetWithScope(key, "filemanager") 11 | } 12 | 13 | func GetHTML(key string) template.HTML { 14 | return template.HTML(language.GetWithScope(key, "filemanager")) 15 | } 16 | -------------------------------------------------------------------------------- /modules/permission/permission.go: -------------------------------------------------------------------------------- 1 | package permission 2 | 3 | type Permission struct { 4 | AllowUpload bool 5 | AllowRename bool 6 | AllowCreateDir bool 7 | AllowDelete bool 8 | AllowMove bool 9 | AllowDownload bool 10 | } 11 | 12 | func (p Permission) HasOperation() bool { 13 | return p.AllowDownload || p.AllowDelete || p.AllowMove 14 | } 15 | -------------------------------------------------------------------------------- /modules/root/root.go: -------------------------------------------------------------------------------- 1 | package root 2 | 3 | import ( 4 | errors "github.com/GoAdminGroup/filemanager/modules/error" 5 | "github.com/GoAdminGroup/go-admin/context" 6 | ) 7 | 8 | type Root struct { 9 | Path string 10 | Title string 11 | } 12 | 13 | type Roots map[string]Root 14 | 15 | func (r Roots) Add(key string, value Root) { 16 | r[key] = value 17 | } 18 | 19 | func (r Roots) GetPathFromPrefix(ctx *context.Context) string { 20 | return r.GetFromPrefix(ctx).Path 21 | } 22 | 23 | func (r Roots) GetTitleFromPrefix(ctx *context.Context) string { 24 | return r.GetFromPrefix(ctx).Title 25 | } 26 | 27 | func (r Roots) GetFromPrefix(ctx *context.Context) Root { 28 | prefix := ctx.Query("__prefix") 29 | if prefix == "" { 30 | prefix = "def" 31 | } 32 | if root, ok := r[prefix]; ok { 33 | return root 34 | } 35 | for name, v := range r { 36 | if name != "" { 37 | return v 38 | } 39 | } 40 | panic(errors.WrongPrefix) 41 | } 42 | -------------------------------------------------------------------------------- /modules/util/util.go: -------------------------------------------------------------------------------- 1 | package util 2 | 3 | import ( 4 | "fmt" 5 | "io" 6 | "mime" 7 | "mime/multipart" 8 | "os" 9 | "path/filepath" 10 | "strings" 11 | 12 | "golang.org/x/tools/godoc/util" 13 | ) 14 | 15 | func FileExist(path string) bool { 16 | _, err := os.Stat(path) //os.Stat获取文件信息 17 | if err != nil { 18 | return os.IsExist(err) 19 | } 20 | return true 21 | } 22 | 23 | func IsDirectory(filename string) bool { 24 | info, err := os.Stat(filename) 25 | if err != nil { 26 | return false 27 | } 28 | return info.IsDir() 29 | } 30 | 31 | func IsFile(filename string) bool { 32 | info, err := os.Stat(filename) 33 | if err != nil { 34 | return false 35 | } 36 | return !info.IsDir() 37 | } 38 | 39 | func MkdirIfNotExist(path string) { 40 | if _, err := os.Stat(path); os.IsNotExist(err) { 41 | _ = os.Mkdir(path, os.ModePerm) 42 | } 43 | } 44 | 45 | func MkFileIfNotExist(path string) { 46 | if _, err := os.Stat(path); os.IsNotExist(err) { 47 | _, _ = os.Create(path) 48 | } 49 | } 50 | 51 | func UploadFileTo(fh *multipart.FileHeader, destDirectory string) (int64, error) { 52 | src, err := fh.Open() 53 | if err != nil { 54 | return 0, err 55 | } 56 | defer src.Close() 57 | 58 | out, err := os.OpenFile(filepath.Join(destDirectory, fh.Filename), 59 | os.O_WRONLY|os.O_CREATE, os.FileMode(0666)) 60 | if err != nil { 61 | return 0, err 62 | } 63 | defer out.Close() 64 | 65 | return io.Copy(out, src) 66 | } 67 | 68 | func IsTextFile(filepath string) bool { 69 | f, err := os.Open(filepath) 70 | if err != nil { 71 | return false 72 | } 73 | defer f.Close() 74 | 75 | var buf [1024]byte 76 | n, err := f.Read(buf[0:]) 77 | if err != nil { 78 | return false 79 | } 80 | 81 | return util.IsText(buf[0:n]) 82 | } 83 | 84 | func Substr(s string, pos, length int) string { 85 | runes := []rune(s) 86 | l := pos + length 87 | if l > len(runes) { 88 | l = len(runes) 89 | } 90 | return string(runes[pos:l]) 91 | } 92 | 93 | func GetParentDirectory(directory string) string { 94 | return Substr(directory, 0, strings.LastIndex(directory, "/")) 95 | } 96 | 97 | func ParseFileContentType(fileName string) string { 98 | contentType := mime.TypeByExtension(filepath.Ext(fileName)) 99 | if strings.HasPrefix(contentType, "text/") { 100 | contentType = "text/plain" 101 | } 102 | return contentType 103 | } 104 | 105 | func IsHiddenFile(name string) bool { 106 | if strings.TrimSpace(name) == "" { 107 | return false 108 | } 109 | 110 | return strings.HasPrefix(name, ".") 111 | } 112 | 113 | func ByteCountIEC(b int) string { 114 | const unit = 1024 115 | if b < unit { 116 | return fmt.Sprintf("%d B", b) 117 | } 118 | div, exp := unit, 0 119 | for n := b / unit; n >= unit; n /= unit { 120 | div *= unit 121 | exp++ 122 | } 123 | return fmt.Sprintf("%.1f %ciB", 124 | float64(b)/float64(div), "KMGTPE"[exp]) 125 | } 126 | -------------------------------------------------------------------------------- /previewer/code.go: -------------------------------------------------------------------------------- 1 | package previewer 2 | 3 | import ( 4 | "html/template" 5 | 6 | "github.com/GoAdminGroup/html" 7 | ) 8 | 9 | type Code struct { 10 | Ext string 11 | } 12 | 13 | func NewCode(ext string) *Code { 14 | return &Code{ 15 | Ext: ext, 16 | } 17 | } 18 | 19 | var ExtJSMap = map[string]template.HTML{ 20 | ".go": "golang", 21 | ".php": "php", 22 | ".py": "python", 23 | ".json": "json", 24 | ".md": "markdown", 25 | ".sql": "sql", 26 | ".js": "javascript", 27 | ".css": "css", 28 | ".less": "less", 29 | ".sass": "sass", 30 | ".cpp": "c_cpp", 31 | ".rb": "ruby", 32 | ".ini": "ini", 33 | ".yaml": "yaml", 34 | ".yml": "yaml", 35 | ".xml": "xml", 36 | ".coffee": "coffee", 37 | ".sh": "sh", 38 | } 39 | 40 | func (i *Code) Preview(content []byte) template.HTML { 41 | 42 | var ( 43 | extJS = template.HTML(``) 44 | ext = template.HTML("html") 45 | ) 46 | 47 | if e, ok := ExtJSMap[i.Ext]; ok { 48 | ext = e 49 | } 50 | 51 | return extJS + html.DivEl().SetClass("preview-content"). 52 | SetStyle("margin", "10px auto 10px auto"). 53 | SetStyle("width", "90%"). 54 | SetContent(` 55 |
56 |         
57 |     
58 | 59 | 69 | `).Get() 70 | } 71 | -------------------------------------------------------------------------------- /previewer/image.go: -------------------------------------------------------------------------------- 1 | package previewer 2 | 3 | import ( 4 | "encoding/base64" 5 | "html/template" 6 | 7 | template2 "github.com/GoAdminGroup/go-admin/template" 8 | "github.com/GoAdminGroup/html" 9 | "github.com/h2non/filetype" 10 | ) 11 | 12 | type Image struct{} 13 | 14 | func (i *Image) Preview(content []byte) template.HTML { 15 | t, _ := filetype.Image(content) 16 | b64 := base64.StdEncoding.EncodeToString(content) 17 | 18 | return html.DivEl().SetClass("preview-content"). 19 | SetStyle("margin", "20px auto 20px auto"). 20 | SetStyle("width", "500px"). 21 | SetContent(template2.Default(). 22 | Image(). 23 | SetWidth("500"). 24 | SetHeight("auto"). 25 | SetSrc(template.HTML("data:" + t.MIME.Value + ";base64," + b64)).GetContent()). 26 | Get() 27 | } 28 | -------------------------------------------------------------------------------- /previewer/pdf.go: -------------------------------------------------------------------------------- 1 | package previewer 2 | 3 | import ( 4 | "html/template" 5 | ) 6 | 7 | type PDF struct{} 8 | 9 | // TODO 10 | func (p *PDF) Preview(content []byte) template.HTML { 11 | //sourceJS := template.HTML(``) 12 | // 13 | //return sourceJS + html.DivEl().SetClass("preview-content"). 14 | // SetStyle("margin", "20px auto 20px auto"). 15 | // SetStyle("width", "500px"). 16 | // SetContent(``). 17 | // Get() 18 | panic("implement me") 19 | } 20 | -------------------------------------------------------------------------------- /previewer/previewer.go: -------------------------------------------------------------------------------- 1 | package previewer 2 | 3 | import ( 4 | "html/template" 5 | "io/ioutil" 6 | "path/filepath" 7 | 8 | "github.com/GoAdminGroup/filemanager/modules/language" 9 | "github.com/GoAdminGroup/html" 10 | "github.com/h2non/filetype" 11 | ) 12 | 13 | type Previewer interface { 14 | Preview(content []byte) template.HTML 15 | } 16 | 17 | func Preview(path string) (template.HTML, error) { 18 | buf, err := ioutil.ReadFile(filepath.FromSlash(path)) 19 | 20 | if err != nil { 21 | return "", err 22 | } 23 | 24 | if filetype.IsImage(buf) { 25 | return image.Preview(buf), nil 26 | } 27 | 28 | ext := filepath.Ext(path) 29 | 30 | if IsCode(ext) { 31 | return NewCode(ext).Preview(buf), nil 32 | } 33 | 34 | return html.DivEl().SetClass("preview-content"). 35 | SetStyle("margin", "20px auto 20px auto"). 36 | SetStyle("width", "500px"). 37 | SetStyle("text-align", "center"). 38 | SetContent(html.H1(language.GetHTML("no supported"))). 39 | Get(), nil 40 | } 41 | 42 | var image = new(Image) 43 | 44 | var codeExtensions = [...]string{ 45 | ".go", ".php", ".html", ".css", ".js", ".py", ".md", 46 | ".c", ".cpp", ".java", ".sh", ".tmpl", ".mod", ".sum", 47 | ".sql", ".json", ".txt", 48 | } 49 | 50 | func IsCode(ext string) bool { 51 | for _, e := range codeExtensions { 52 | if ext == e { 53 | return true 54 | } 55 | } 56 | return false 57 | } 58 | -------------------------------------------------------------------------------- /router.go: -------------------------------------------------------------------------------- 1 | package filemanager 2 | 3 | import ( 4 | "github.com/GoAdminGroup/go-admin/context" 5 | "github.com/GoAdminGroup/go-admin/modules/auth" 6 | "github.com/GoAdminGroup/go-admin/modules/service" 7 | ) 8 | 9 | func (f *FileManager) initRouter(srv service.List) *context.App { 10 | 11 | app := context.NewApp() 12 | authRoute := app.Group("/", auth.Middleware(f.Conn)) 13 | 14 | authRoute.GET("/", f.guard.Files, f.handler.ListFiles) 15 | authRoute.GET("/:__prefix/list", f.guard.Files, f.handler.ListFiles) 16 | authRoute.GET("/:__prefix/download", f.handler.Download) 17 | authRoute.POST("/:__prefix/upload", f.guard.Upload, f.handler.Upload) 18 | authRoute.POST("/:__prefix/create/dir/popup", f.handler.CreateDirPopUp) 19 | authRoute.POST("/:__prefix/create/dir", f.guard.CreateDir, f.handler.CreateDir) 20 | authRoute.POST("/:__prefix/delete", f.guard.Delete, f.handler.Delete) 21 | authRoute.POST("/:__prefix/move/popup", f.handler.MovePopup) 22 | authRoute.POST("/:__prefix/move", f.guard.Move, f.handler.Move) 23 | authRoute.GET("/:__prefix/preview", f.guard.Preview, f.handler.Preview) 24 | authRoute.POST("/:__prefix/rename/popup", f.handler.RenamePopUp) 25 | authRoute.POST("/:__prefix/rename", f.guard.Rename, f.handler.Rename) 26 | 27 | return app 28 | } 29 | -------------------------------------------------------------------------------- /tests/admin.db: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GoAdminGroup/filemanager/55d31351ebac516bfe98bc2ae70b0de75cd9b699/tests/admin.db -------------------------------------------------------------------------------- /tests/common_test.go: -------------------------------------------------------------------------------- 1 | package tests 2 | 3 | import ( 4 | "net/http" 5 | "testing" 6 | 7 | "github.com/GoAdminGroup/demo/tables" 8 | "github.com/GoAdminGroup/go-admin/modules/config" 9 | "github.com/GoAdminGroup/go-admin/tests" 10 | "github.com/GoAdminGroup/go-admin/tests/common" 11 | "github.com/GoAdminGroup/go-admin/tests/frameworks/gin" 12 | "github.com/GoAdminGroup/go-admin/tests/web" 13 | "github.com/gavv/httpexpect" 14 | ) 15 | 16 | // Black box testing 17 | func TestDemoBlackBox(t *testing.T) { 18 | tests.BlackBoxTestSuit(t, gin.NewHandler, config.DatabaseList{ 19 | "default": { 20 | Driver: config.DriverSqlite, 21 | File: "./admin.db", 22 | }, 23 | }, tables.Generators, func(cfg config.DatabaseList) { 24 | // Data cleaner of the framework 25 | tests.Cleaner(cfg) 26 | // Clean your own data: 27 | // ... 28 | }, func(e *httpexpect.Expect) { 29 | // Test cases of the framework 30 | common.Test(e) 31 | // Write your own API test, for example: 32 | // More usages: https://github.com/gavv/httpexpect 33 | e.GET("/admin").Expect().Status(http.StatusOK) 34 | }) 35 | } 36 | 37 | // User acceptance testing 38 | func TestDemoUserAcceptance(t *testing.T) { 39 | web.UserAcceptanceTestSuit(t, func(t *testing.T, page *web.Page) { 40 | // Write test case base on chromedriver, for example: 41 | // More usages: https://github.com/sclevine/agouti 42 | page.NavigateTo("http://127.0.0.1:9033/admin") 43 | page.Contain("username") 44 | page.Click("") 45 | }, func(quit chan struct{}) { 46 | // start the server: 47 | // .... 48 | }, true) // if local parameter is true, it will not be headless, and window not close when finishing tests. 49 | } 50 | --------------------------------------------------------------------------------