From d395245beee5732adfba289b692a3e485a6154bb Mon Sep 17 00:00:00 2001
From: a-wing <1@233.email>
Date: Sun, 6 Nov 2022 01:15:51 +0800
Subject: [PATCH 01/11] feat(server): http file server interface #199
---
go.mod | 3 +++
go.sum | 9 ++++++++
server/httpd/file.go | 53 ++++++++++++++++++++++++++++++++++++++++++++
server/server.go | 45 +++++++++++++++++++++++++++++++++++++
4 files changed, 110 insertions(+)
create mode 100644 server/httpd/file.go
diff --git a/go.mod b/go.mod
index 4faa2968..a576a736 100644
--- a/go.mod
+++ b/go.mod
@@ -5,6 +5,7 @@ go 1.18
require (
github.com/BurntSushi/toml v1.2.1
github.com/a-wing/lightcable v0.1.1
+ github.com/djherbis/stow/v4 v4.0.0
github.com/gorilla/mux v1.8.0
github.com/gorilla/websocket v1.5.0
github.com/hashicorp/golang-lru v0.5.4
@@ -14,11 +15,13 @@ require (
github.com/pion/transport v0.13.1
github.com/pion/turn/v2 v2.0.8
github.com/pion/webrtc/v3 v3.1.47
+ github.com/rs/xid v1.4.0
github.com/sb-im/jsonrpc-lite v0.2.0
github.com/schollz/progressbar/v3 v3.12.0
github.com/sirupsen/logrus v1.9.0
github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e
github.com/spf13/cobra v1.6.1
+ go.etcd.io/bbolt v1.3.6
golang.org/x/term v0.1.0
)
diff --git a/go.sum b/go.sum
index 4ea0939b..9268f623 100644
--- a/go.sum
+++ b/go.sum
@@ -6,6 +6,8 @@ github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46t
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/djherbis/stow/v4 v4.0.0 h1:9ncmiT8vIIGEMVsRWr3IHS+AUXLEcfsgzIrHcsTVpTY=
+github.com/djherbis/stow/v4 v4.0.0/go.mod h1:aJlUphKUMWUrtg5FQhbakgaPZ5SNPhzWZ8iSHrwcZI0=
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE=
@@ -96,6 +98,8 @@ github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZN
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
github.com/rivo/uniseg v0.4.2 h1:YwD0ulJSJytLpiaWua0sBDusfsCZohxjxzVTYjwxfV8=
github.com/rivo/uniseg v0.4.2/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
+github.com/rs/xid v1.4.0 h1:qd7wPTDkN6KQx2VmMBLrpHkiyQwgFXRnkOLacUiaSNY=
+github.com/rs/xid v1.4.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg=
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/sb-im/jsonrpc-lite v0.2.0 h1:r45VX/mESjt6SYBX7V6yIDr3EUWi40EjQIXzz0B0lzo=
github.com/sb-im/jsonrpc-lite v0.2.0/go.mod h1:dHV+dbbKl+2+/pDgAavKuAWdEfjGWGck0M7Au+Tkj8Q=
@@ -118,6 +122,9 @@ github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/
github.com/stretchr/testify v1.7.1 h1:5TQK59W5E3v0r2duFAb7P95B6hEeOyEnHRa8MjYSMTY=
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
+go.etcd.io/bbolt v1.3.5/go.mod h1:G5EMThwa9y8QZGBClrRx5EY+Yw9kAhnjy3bSjsnlVTQ=
+go.etcd.io/bbolt v1.3.6 h1:/ecaJf0sk1l4l6V4awd65v2C3ILy7MSj+s/x1ADCIMU=
+go.etcd.io/bbolt v1.3.6/go.mod h1:qXsaaIqmgQH0T+OPdb99Bf+PKfBBQVAdyD6TY9G8XM4=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
@@ -149,7 +156,9 @@ golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200923182605-d9f96fdee20d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
diff --git a/server/httpd/file.go b/server/httpd/file.go
new file mode 100644
index 00000000..010f835c
--- /dev/null
+++ b/server/httpd/file.go
@@ -0,0 +1,53 @@
+package httpd
+
+import (
+ "io"
+ "mime/multipart"
+ "net/http"
+ "net/url"
+ "os"
+ "unicode"
+)
+
+type Meta struct {
+ Name string `json:"name"`
+ Type string `json:"type"`
+ Size int64 `json:"size"`
+ UXID string `json:"uxid"`
+}
+
+func SaveUploadedFile(file *multipart.FileHeader, dst string) error {
+ src, err := file.Open()
+ if err != nil {
+ return err
+ }
+ defer src.Close()
+
+ out, err := os.Create(dst)
+ if err != nil {
+ return err
+ }
+ defer out.Close()
+
+ _, err = io.Copy(out, src)
+ return err
+}
+
+func FileAttachment(w http.ResponseWriter, r *http.Request, filepath, filename string) {
+ if isASCII(filename) {
+ w.Header().Set("Content-Disposition", `attachment; filename="`+filename+`"`)
+ } else {
+ w.Header().Set("Content-Disposition", `attachment; filename*=UTF-8''`+url.QueryEscape(filename))
+ }
+ http.ServeFile(w, r, filepath)
+}
+
+// https://stackoverflow.com/questions/53069040/checking-a-string-contains-only-ascii-characters
+func isASCII(s string) bool {
+ for i := 0; i < len(s); i++ {
+ if s[i] > unicode.MaxASCII {
+ return false
+ }
+ }
+ return true
+}
diff --git a/server/server.go b/server/server.go
index a0e4249d..c073619c 100644
--- a/server/server.go
+++ b/server/server.go
@@ -7,6 +7,7 @@ import (
"io/fs"
"log"
"net/http"
+ "path"
"filegogo/server/httpd"
"filegogo/server/turnd"
@@ -14,6 +15,10 @@ import (
"github.com/a-wing/lightcable"
"github.com/gorilla/mux"
"github.com/pion/webrtc/v3"
+ "github.com/rs/xid"
+
+ "github.com/djherbis/stow/v4"
+ bolt "go.etcd.io/bbolt"
)
//go:embed build
@@ -22,6 +27,12 @@ var dist embed.FS
const (
ApiPathConfig = "/config"
ApiPathSignal = "/s/"
+
+ ApiPathFileInfo = "/info/"
+ ApiPathFileRaw = "/raw/"
+
+ dataPath = "tmp"
+ dbName = "store.db"
)
func Run(cfg *Config) {
@@ -36,6 +47,13 @@ func Run(cfg *Config) {
defer turnSrv.Close()
}
+ db, err := bolt.Open(path.Join(dataPath, dbName), 0600, nil)
+ if err != nil {
+ log.Fatal(err)
+ }
+
+ store := stow.NewJSONStore(db, []byte("room"))
+
sr := mux.NewRouter()
cable := lightcable.New(lightcable.DefaultConfig)
@@ -73,6 +91,33 @@ func Run(cfg *Config) {
}
})
+ sr.HandleFunc(ApiPathFileRaw+"{room:[0-9]+}", func(w http.ResponseWriter, r *http.Request) {
+ uxid := xid.New().String()
+
+ f, fh, err := r.FormFile("f")
+ if err != nil {
+ return
+ }
+ f.Close()
+
+ store.Put(mux.Vars(r)["room"], &httpd.Meta{
+ Name: fh.Filename,
+ Size: fh.Size,
+ UXID: uxid,
+ })
+
+ httpd.SaveUploadedFile(fh, path.Join(dataPath, uxid))
+
+ }).Methods(http.MethodPost)
+
+ sr.HandleFunc(ApiPathFileRaw+"{room:[0-9]+}", func(w http.ResponseWriter, r *http.Request) {
+ room := mux.Vars(r)["room"]
+ var m httpd.Meta
+ store.Get(room, &m)
+
+ httpd.FileAttachment(w, r, path.Join(dataPath, m.UXID), m.Name)
+ }).Methods(http.MethodGet)
+
fsys, err := fs.Sub(dist, "build")
if err != nil {
log.Fatal(err)
From bd1a7018bf23bd58688f504fd8a52b599f23241f Mon Sep 17 00:00:00 2001
From: a-wing <1@233.email>
Date: Sun, 6 Nov 2022 11:30:01 +0800
Subject: [PATCH 02/11] feat(server): tmp file storage #199
---
.gitignore | 1 +
README.md | 16 ++++++++--------
cmd/server.go | 2 ++
conf/filegogo.toml | 3 +++
server/httpd/room.go | 2 ++
server/server.go | 14 ++++++++------
6 files changed, 24 insertions(+), 14 deletions(-)
diff --git a/.gitignore b/.gitignore
index 6df6bd22..97c9170a 100644
--- a/.gitignore
+++ b/.gitignore
@@ -4,6 +4,7 @@
/filegogo-server.toml
bin
+data
build
node_modules
diff --git a/README.md b/README.md
index 699a4862..1c69332f 100644
--- a/README.md
+++ b/README.md
@@ -41,14 +41,6 @@ make
## Run Development
-### Server
-
-```bash
-
-# Default Listen port: 8080
-go run ./main.go server
-```
-
### Webapp
```bash
@@ -60,6 +52,14 @@ npm install
npm run dev
```
+### Server
+
+```bash
+
+# Default Listen port: 8080
+go run ./main.go server
+```
+
### Client
> run cli client. For example:
diff --git a/cmd/server.go b/cmd/server.go
index 02c8c5b2..5ca1d185 100644
--- a/cmd/server.go
+++ b/cmd/server.go
@@ -21,6 +21,8 @@ var serverCmd = &cobra.Command{
Listen: "0.0.0.0:8080",
RoomAlive: 1024,
RoomCount: 10000,
+
+ StoragePath: "data",
},
}
diff --git a/conf/filegogo.toml b/conf/filegogo.toml
index 3da177f0..cfbc9a3c 100644
--- a/conf/filegogo.toml
+++ b/conf/filegogo.toml
@@ -9,6 +9,9 @@ roomAlive = 1024
# room id: [0 - 9999]
roomCount = 10000
+# http file relay storage
+storagePath = "data"
+
# Enable Built-in turn server
#[turn]
diff --git a/server/httpd/room.go b/server/httpd/room.go
index 9ad13a84..2c290efe 100644
--- a/server/httpd/room.go
+++ b/server/httpd/room.go
@@ -22,6 +22,8 @@ type Config struct {
Listen string
RoomAlive int
RoomCount int
+
+ StoragePath string
}
type Server struct {
diff --git a/server/server.go b/server/server.go
index c073619c..f9f9a0e6 100644
--- a/server/server.go
+++ b/server/server.go
@@ -7,6 +7,7 @@ import (
"io/fs"
"log"
"net/http"
+ "os"
"path"
"filegogo/server/httpd"
@@ -31,8 +32,7 @@ const (
ApiPathFileInfo = "/info/"
ApiPathFileRaw = "/raw/"
- dataPath = "tmp"
- dbName = "store.db"
+ dbName = "store.db"
)
func Run(cfg *Config) {
@@ -46,12 +46,14 @@ func Run(cfg *Config) {
}
defer turnSrv.Close()
}
+ if err := os.MkdirAll(cfg.Http.StoragePath, os.ModePerm); err != nil {
+ log.Fatal(err)
+ }
- db, err := bolt.Open(path.Join(dataPath, dbName), 0600, nil)
+ db, err := bolt.Open(path.Join(cfg.Http.StoragePath, dbName), 0600, nil)
if err != nil {
log.Fatal(err)
}
-
store := stow.NewJSONStore(db, []byte("room"))
sr := mux.NewRouter()
@@ -106,7 +108,7 @@ func Run(cfg *Config) {
UXID: uxid,
})
- httpd.SaveUploadedFile(fh, path.Join(dataPath, uxid))
+ httpd.SaveUploadedFile(fh, path.Join(cfg.Http.StoragePath, uxid))
}).Methods(http.MethodPost)
@@ -115,7 +117,7 @@ func Run(cfg *Config) {
var m httpd.Meta
store.Get(room, &m)
- httpd.FileAttachment(w, r, path.Join(dataPath, m.UXID), m.Name)
+ httpd.FileAttachment(w, r, path.Join(cfg.Http.StoragePath, m.UXID), m.Name)
}).Methods(http.MethodGet)
fsys, err := fs.Sub(dist, "build")
From 5ef2be4a8dab4f2f20448080aa6a93f8ffda8212 Mon Sep 17 00:00:00 2001
From: a-wing <1@233.email>
Date: Fri, 2 Dec 2022 00:07:54 +0800
Subject: [PATCH 03/11] feat(webapp): upload button #199
---
vite.config.ts | 1 +
webapp/components/File.tsx | 5 +++--
webapp/components/index.tsx | 2 ++
webapp/components/upload.module.scss | 20 ++++++++++++++++++++
webapp/components/upload.tsx | 19 +++++++++++++++++++
5 files changed, 45 insertions(+), 2 deletions(-)
create mode 100644 webapp/components/upload.module.scss
create mode 100644 webapp/components/upload.tsx
diff --git a/vite.config.ts b/vite.config.ts
index 7f5a7325..dd1d8b91 100644
--- a/vite.config.ts
+++ b/vite.config.ts
@@ -7,6 +7,7 @@ export default defineConfig({
port: 3000,
proxy: {
'/s': 'http://localhost:8080',
+ '^/raw/.*': 'http://localhost:8080',
'/config': 'http://localhost:8080',
'^/s/.*': {
target: 'ws://localhost:8080',
diff --git a/webapp/components/File.tsx b/webapp/components/File.tsx
index d986dbcc..b940c265 100644
--- a/webapp/components/File.tsx
+++ b/webapp/components/File.tsx
@@ -23,7 +23,7 @@ function File(props: {
}
return (
- <>
+
)
}
diff --git a/webapp/components/index.tsx b/webapp/components/index.tsx
index 8b385d5d..d929305a 100644
--- a/webapp/components/index.tsx
+++ b/webapp/components/index.tsx
@@ -10,6 +10,7 @@ import Address from './Address'
import File from './File'
import Qrcode from './QRCode'
import Card from './card'
+import Upload from './upload'
import { DomSendFile, DomRecvFile } from '../libfgg/pool/file/dom'
@@ -92,6 +93,7 @@ function Index(props: { address: string }) {
handleFile={ (files: any) => { handleFile(files) } }
getFile={ getfile }
>
+
>
)
}
diff --git a/webapp/components/upload.module.scss b/webapp/components/upload.module.scss
new file mode 100644
index 00000000..51acd92b
--- /dev/null
+++ b/webapp/components/upload.module.scss
@@ -0,0 +1,20 @@
+.button {
+ width: 100%;
+ border: 1px solid #ccc;
+ display: inline-block;
+ padding: 10px 0px;
+ cursor: pointer;
+ text-align: center;
+ border-radius: 5px;
+ color: white;
+ font-size: calc(10px + 2vmin);
+}
+
+.button:hover {
+ border: 1px solid #0bffa5;
+}
+
+.button:active {
+ box-shadow: 0 5px #666;
+ transform: translateY(5px);
+}
diff --git a/webapp/components/upload.tsx b/webapp/components/upload.tsx
new file mode 100644
index 00000000..2af7076d
--- /dev/null
+++ b/webapp/components/upload.tsx
@@ -0,0 +1,19 @@
+import styles from './upload.module.scss'
+
+function Upload(props: { name: string, file: any }) {
+ const send = () => {
+ const form = document.getElementById('form-upload')
+ const formData = new FormData(form as HTMLFormElement)
+ const xhr = new XMLHttpRequest()
+ xhr.open("POST", `/raw/${props.name}`, true)
+ xhr.send(formData)
+ }
+
+ return (
+ <>
+
+ >
+ )
+}
+
+export default Upload
From d2b4fd8d46cd4e686d71ab0b3142a7d4e7dacd1e Mon Sep 17 00:00:00 2001
From: a-wing <1@233.email>
Date: Sat, 3 Dec 2022 00:02:33 +0800
Subject: [PATCH 04/11] feat(webapp): download button #199
---
webapp/components/download.tsx | 15 +++++++++++++++
webapp/components/index.tsx | 18 +++++++++++-------
webapp/components/upload.module.scss | 1 +
3 files changed, 27 insertions(+), 7 deletions(-)
create mode 100644 webapp/components/download.tsx
diff --git a/webapp/components/download.tsx b/webapp/components/download.tsx
new file mode 100644
index 00000000..014510f3
--- /dev/null
+++ b/webapp/components/download.tsx
@@ -0,0 +1,15 @@
+import styles from './upload.module.scss'
+
+function Download(props: { name: string }) {
+ const send = () => {
+ window.open(`/raw/${props.name}`)
+ }
+
+ return (
+ <>
+
+ >
+ )
+}
+
+export default Download
diff --git a/webapp/components/index.tsx b/webapp/components/index.tsx
index d929305a..bf403063 100644
--- a/webapp/components/index.tsx
+++ b/webapp/components/index.tsx
@@ -13,6 +13,7 @@ import Card from './card'
import Upload from './upload'
import { DomSendFile, DomRecvFile } from '../libfgg/pool/file/dom'
+import Download from './download'
const fgg = new LibFgg()
let enabled = true
@@ -87,13 +88,16 @@ function Index(props: { address: string }) {
>
}
- { handleFile(files) } }
- getFile={ getfile }
- >
-
+
+ { handleFile(files) } }
+ getFile={ getfile }
+ >
+
+
+
>
)
}
diff --git a/webapp/components/upload.module.scss b/webapp/components/upload.module.scss
index 51acd92b..e93490f8 100644
--- a/webapp/components/upload.module.scss
+++ b/webapp/components/upload.module.scss
@@ -3,6 +3,7 @@
border: 1px solid #ccc;
display: inline-block;
padding: 10px 0px;
+ background-color: #f14668;
cursor: pointer;
text-align: center;
border-radius: 5px;
From 58d423aa7708cb596733f2b878ae60708a35a41a Mon Sep 17 00:00:00 2001
From: a-wing <1@233.email>
Date: Sun, 4 Dec 2022 00:48:14 +0800
Subject: [PATCH 05/11] feat(server): add relay file info #199
---
server/server.go | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/server/server.go b/server/server.go
index f9f9a0e6..26d8c812 100644
--- a/server/server.go
+++ b/server/server.go
@@ -93,6 +93,14 @@ func Run(cfg *Config) {
}
})
+ sr.HandleFunc(ApiPathFileInfo+"{room:[0-9]+}", func(w http.ResponseWriter, r *http.Request) {
+ room := mux.Vars(r)["room"]
+ var m httpd.Meta
+ store.Get(room, &m)
+ data, _ := json.Marshal(m)
+ w.Header().Add("Content-type", "application/json")
+ w.Write(data)
+ })
sr.HandleFunc(ApiPathFileRaw+"{room:[0-9]+}", func(w http.ResponseWriter, r *http.Request) {
uxid := xid.New().String()
From 82d89175a88c89bcbf3386d136f334d821853a27 Mon Sep 17 00:00:00 2001
From: a-wing <1@233.email>
Date: Wed, 7 Dec 2022 20:50:28 +0800
Subject: [PATCH 06/11] refactor(webapp): add relay file #199
---
webapp/components/File.tsx | 11 ++++++++---
webapp/components/download.tsx | 15 ---------------
webapp/components/index.tsx | 4 ----
webapp/components/upload.module.scss | 21 ---------------------
webapp/components/upload.tsx | 19 -------------------
webapp/lib/api.ts | 21 +++++++++++++++++++++
6 files changed, 29 insertions(+), 62 deletions(-)
delete mode 100644 webapp/components/download.tsx
delete mode 100644 webapp/components/upload.module.scss
delete mode 100644 webapp/components/upload.tsx
diff --git a/webapp/components/File.tsx b/webapp/components/File.tsx
index b940c265..a1efdaf0 100644
--- a/webapp/components/File.tsx
+++ b/webapp/components/File.tsx
@@ -1,5 +1,8 @@
import { useRef, useState, ChangeEvent } from 'react'
import styles from './File.module.scss'
+import { putRawFile, getRawFile } from '../lib/api'
+
+let tmp: File | undefined
function File(props: {
recver: boolean,
@@ -23,7 +26,7 @@ function File(props: {
}
return (
-
+
+
+ >
)
}
diff --git a/webapp/components/download.tsx b/webapp/components/download.tsx
deleted file mode 100644
index 014510f3..00000000
--- a/webapp/components/download.tsx
+++ /dev/null
@@ -1,15 +0,0 @@
-import styles from './upload.module.scss'
-
-function Download(props: { name: string }) {
- const send = () => {
- window.open(`/raw/${props.name}`)
- }
-
- return (
- <>
-
- >
- )
-}
-
-export default Download
diff --git a/webapp/components/index.tsx b/webapp/components/index.tsx
index bf403063..fe059ff4 100644
--- a/webapp/components/index.tsx
+++ b/webapp/components/index.tsx
@@ -10,10 +10,8 @@ import Address from './Address'
import File from './File'
import Qrcode from './QRCode'
import Card from './card'
-import Upload from './upload'
import { DomSendFile, DomRecvFile } from '../libfgg/pool/file/dom'
-import Download from './download'
const fgg = new LibFgg()
let enabled = true
@@ -95,8 +93,6 @@ function Index(props: { address: string }) {
handleFile={ (files: any) => { handleFile(files) } }
getFile={ getfile }
>
-
-
>
)
diff --git a/webapp/components/upload.module.scss b/webapp/components/upload.module.scss
deleted file mode 100644
index e93490f8..00000000
--- a/webapp/components/upload.module.scss
+++ /dev/null
@@ -1,21 +0,0 @@
-.button {
- width: 100%;
- border: 1px solid #ccc;
- display: inline-block;
- padding: 10px 0px;
- background-color: #f14668;
- cursor: pointer;
- text-align: center;
- border-radius: 5px;
- color: white;
- font-size: calc(10px + 2vmin);
-}
-
-.button:hover {
- border: 1px solid #0bffa5;
-}
-
-.button:active {
- box-shadow: 0 5px #666;
- transform: translateY(5px);
-}
diff --git a/webapp/components/upload.tsx b/webapp/components/upload.tsx
deleted file mode 100644
index 2af7076d..00000000
--- a/webapp/components/upload.tsx
+++ /dev/null
@@ -1,19 +0,0 @@
-import styles from './upload.module.scss'
-
-function Upload(props: { name: string, file: any }) {
- const send = () => {
- const form = document.getElementById('form-upload')
- const formData = new FormData(form as HTMLFormElement)
- const xhr = new XMLHttpRequest()
- xhr.open("POST", `/raw/${props.name}`, true)
- xhr.send(formData)
- }
-
- return (
- <>
-
- >
- )
-}
-
-export default Upload
diff --git a/webapp/lib/api.ts b/webapp/lib/api.ts
index d74ccc86..029ec753 100644
--- a/webapp/lib/api.ts
+++ b/webapp/lib/api.ts
@@ -26,10 +26,31 @@ async function getRoom(): Promise {
return result.room || ''
}
+async function putRawFile(f: File): Promise {
+ const room = shareGetRoom(window.location.href)
+ if (room === '') throw "not room"
+
+ let formData = new FormData()
+ formData.append('f', f, f.name)
+ await fetch(`/raw/${room}`, {
+ method: "post",
+ body: formData,
+ })
+ return
+}
+
+async function getRawFile(): Promise {
+ const room = shareGetRoom(window.location.href)
+ window.open(`/raw/${room}`)
+}
+
+
export {
getServer,
getConfig,
getRoom,
getLogLevel,
+ putRawFile,
+ getRawFile,
shareGetRoom,
}
From db0906392131dae58308e8ab6b6923ab787a5bbf Mon Sep 17 00:00:00 2001
From: a-wing <1@233.email>
Date: Thu, 8 Dec 2022 16:42:49 +0800
Subject: [PATCH 07/11] refactor(webapp): add relay file info #199
---
server/server.go | 12 ++++++++----
vite.config.ts | 9 ++++++---
webapp/components/File.tsx | 6 ++++--
webapp/components/index.tsx | 16 ++++++++++++++--
webapp/lib/api.ts | 8 ++++++++
5 files changed, 40 insertions(+), 11 deletions(-)
diff --git a/server/server.go b/server/server.go
index 26d8c812..cfcf9fd8 100644
--- a/server/server.go
+++ b/server/server.go
@@ -96,10 +96,14 @@ func Run(cfg *Config) {
sr.HandleFunc(ApiPathFileInfo+"{room:[0-9]+}", func(w http.ResponseWriter, r *http.Request) {
room := mux.Vars(r)["room"]
var m httpd.Meta
- store.Get(room, &m)
- data, _ := json.Marshal(m)
- w.Header().Add("Content-type", "application/json")
- w.Write(data)
+ err := store.Get(room, &m)
+ if err != nil {
+ w.WriteHeader(http.StatusNotFound)
+ } else {
+ data, _ := json.Marshal(m)
+ w.Header().Add("Content-type", "application/json")
+ w.Write(data)
+ }
})
sr.HandleFunc(ApiPathFileRaw+"{room:[0-9]+}", func(w http.ResponseWriter, r *http.Request) {
uxid := xid.New().String()
diff --git a/vite.config.ts b/vite.config.ts
index dd1d8b91..65c7d904 100644
--- a/vite.config.ts
+++ b/vite.config.ts
@@ -2,13 +2,16 @@ import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
// https://vitejs.dev/config/
+
+const server = 'http://localhost:8080'
export default defineConfig({
server: {
port: 3000,
proxy: {
- '/s': 'http://localhost:8080',
- '^/raw/.*': 'http://localhost:8080',
- '/config': 'http://localhost:8080',
+ '/s': server,
+ '^/raw/.*': server,
+ '^/info/.*': server,
+ '/config': server,
'^/s/.*': {
target: 'ws://localhost:8080',
ws: true,
diff --git a/webapp/components/File.tsx b/webapp/components/File.tsx
index a1efdaf0..eca832d9 100644
--- a/webapp/components/File.tsx
+++ b/webapp/components/File.tsx
@@ -39,8 +39,10 @@ function File(props: {
ref={ hiddenFileInput }
onChange={ (ev: ChangeEvent) => { handleFile(ev.target.files); tmp = ev.target.files?.[0] } }
/>
-
-
+
+
+
+
>
)
}
diff --git a/webapp/components/index.tsx b/webapp/components/index.tsx
index fe059ff4..7dc157fe 100644
--- a/webapp/components/index.tsx
+++ b/webapp/components/index.tsx
@@ -1,7 +1,7 @@
import { useEffect, useRef, useState } from 'react'
import { ProtoHttpToWs } from '../lib/util'
-import { getServer, getConfig, shareGetRoom } from '../lib/api'
+import { getServer, getConfig, shareGetRoom, getRawInfo } from '../lib/api'
import LibFgg from '../libfgg/libfgg'
import log from 'loglevel'
import { Meta } from '../libfgg/pool/data'
@@ -77,9 +77,21 @@ function Index(props: { address: string }) {
}
}, [props.address])
+ useEffect(() => {
+ const load = async () => {
+
+ let data = await getRawInfo()
+ console.log(data)
+ if (data) {
+ setMeta(data)
+ }
+ }
+ load()
+ }, [props.address])
+
return (
<>
- { recver && meta
+ { meta
?
: <>
diff --git a/webapp/lib/api.ts b/webapp/lib/api.ts
index 029ec753..df56a0d6 100644
--- a/webapp/lib/api.ts
+++ b/webapp/lib/api.ts
@@ -44,6 +44,13 @@ async function getRawFile(): Promise {
window.open(`/raw/${room}`)
}
+async function getRawInfo(): Promise {
+ const room = shareGetRoom(window.location.href)
+ const response = await fetch(`/info/${room}`)
+ if (response.status == 200) {
+ return await response.json()
+ }
+}
export {
getServer,
@@ -52,5 +59,6 @@ export {
getLogLevel,
putRawFile,
getRawFile,
+ getRawInfo,
shareGetRoom,
}
From 725aad42fe7983532c2fcb3b33878ce11ca5a8c2 Mon Sep 17 00:00:00 2001
From: a-wing <1@233.email>
Date: Thu, 8 Dec 2022 17:06:16 +0800
Subject: [PATCH 08/11] feat(server): add file mime type #199
---
go.mod | 1 +
go.sum | 2 ++
server/server.go | 3 +++
3 files changed, 6 insertions(+)
diff --git a/go.mod b/go.mod
index a576a736..fc3b188d 100644
--- a/go.mod
+++ b/go.mod
@@ -15,6 +15,7 @@ require (
github.com/pion/transport v0.13.1
github.com/pion/turn/v2 v2.0.8
github.com/pion/webrtc/v3 v3.1.47
+ github.com/qingstor/go-mime v0.1.0
github.com/rs/xid v1.4.0
github.com/sb-im/jsonrpc-lite v0.2.0
github.com/schollz/progressbar/v3 v3.12.0
diff --git a/go.sum b/go.sum
index 9268f623..bcd32b6b 100644
--- a/go.sum
+++ b/go.sum
@@ -95,6 +95,8 @@ github.com/pion/webrtc/v3 v3.1.47 h1:2dFEKRI1rzFvehXDq43hK9OGGyTGJSusUi3j6QKHC5s
github.com/pion/webrtc/v3 v3.1.47/go.mod h1:8U39MYZCLVV4sIBn01htASVNkWQN2zDa/rx5xisEXWs=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
+github.com/qingstor/go-mime v0.1.0 h1:FhTJtM7TRm9pfgCXpjGUxqwbumGojrgE9ecRz5PXvfc=
+github.com/qingstor/go-mime v0.1.0/go.mod h1:EDwWgaMufg74m7futsF0ZGkdA52ajjAycY+XDeV8M88=
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
github.com/rivo/uniseg v0.4.2 h1:YwD0ulJSJytLpiaWua0sBDusfsCZohxjxzVTYjwxfV8=
github.com/rivo/uniseg v0.4.2/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
diff --git a/server/server.go b/server/server.go
index cfcf9fd8..5cfe6dd5 100644
--- a/server/server.go
+++ b/server/server.go
@@ -9,6 +9,7 @@ import (
"net/http"
"os"
"path"
+ "strings"
"filegogo/server/httpd"
"filegogo/server/turnd"
@@ -16,6 +17,7 @@ import (
"github.com/a-wing/lightcable"
"github.com/gorilla/mux"
"github.com/pion/webrtc/v3"
+ "github.com/qingstor/go-mime"
"github.com/rs/xid"
"github.com/djherbis/stow/v4"
@@ -117,6 +119,7 @@ func Run(cfg *Config) {
store.Put(mux.Vars(r)["room"], &httpd.Meta{
Name: fh.Filename,
Size: fh.Size,
+ Type: mime.DetectFileExt(strings.TrimPrefix(path.Ext(fh.Filename), ".")),
UXID: uxid,
})
From 237121397828e02660533bf025213caa2025f821 Mon Sep 17 00:00:00 2001
From: a-wing <1@233.email>
Date: Thu, 8 Dec 2022 18:47:21 +0800
Subject: [PATCH 09/11] feat(server): add relay file delete #199
---
server/server.go | 20 +++++++++++++++-----
vite.config.ts | 3 +--
webapp/components/File.tsx | 34 +++++++++++++++++++++++++---------
webapp/components/index.tsx | 10 ++++++----
webapp/lib/api.ts | 26 +++++++++++++++++---------
5 files changed, 64 insertions(+), 29 deletions(-)
diff --git a/server/server.go b/server/server.go
index 5cfe6dd5..8fc699a0 100644
--- a/server/server.go
+++ b/server/server.go
@@ -31,8 +31,8 @@ const (
ApiPathConfig = "/config"
ApiPathSignal = "/s/"
- ApiPathFileInfo = "/info/"
- ApiPathFileRaw = "/raw/"
+ ApiPathBoxInfo = "/api/info/"
+ ApiPathBoxFile = "/api/file/"
dbName = "store.db"
)
@@ -95,7 +95,7 @@ func Run(cfg *Config) {
}
})
- sr.HandleFunc(ApiPathFileInfo+"{room:[0-9]+}", func(w http.ResponseWriter, r *http.Request) {
+ sr.HandleFunc(ApiPathBoxInfo+"{room:[0-9]+}", func(w http.ResponseWriter, r *http.Request) {
room := mux.Vars(r)["room"]
var m httpd.Meta
err := store.Get(room, &m)
@@ -107,7 +107,8 @@ func Run(cfg *Config) {
w.Write(data)
}
})
- sr.HandleFunc(ApiPathFileRaw+"{room:[0-9]+}", func(w http.ResponseWriter, r *http.Request) {
+
+ sr.HandleFunc(ApiPathBoxFile+"{room:[0-9]+}", func(w http.ResponseWriter, r *http.Request) {
uxid := xid.New().String()
f, fh, err := r.FormFile("f")
@@ -127,7 +128,7 @@ func Run(cfg *Config) {
}).Methods(http.MethodPost)
- sr.HandleFunc(ApiPathFileRaw+"{room:[0-9]+}", func(w http.ResponseWriter, r *http.Request) {
+ sr.HandleFunc(ApiPathBoxFile+"{room:[0-9]+}", func(w http.ResponseWriter, r *http.Request) {
room := mux.Vars(r)["room"]
var m httpd.Meta
store.Get(room, &m)
@@ -135,6 +136,15 @@ func Run(cfg *Config) {
httpd.FileAttachment(w, r, path.Join(cfg.Http.StoragePath, m.UXID), m.Name)
}).Methods(http.MethodGet)
+ sr.HandleFunc(ApiPathBoxFile+"{room:[0-9]+}", func(w http.ResponseWriter, r *http.Request) {
+ room := mux.Vars(r)["room"]
+ var m httpd.Meta
+ store.Get(room, &m)
+ store.Delete(room)
+ os.Remove(path.Join(cfg.Http.StoragePath, m.UXID))
+
+ }).Methods(http.MethodDelete)
+
fsys, err := fs.Sub(dist, "build")
if err != nil {
log.Fatal(err)
diff --git a/vite.config.ts b/vite.config.ts
index 65c7d904..89de6355 100644
--- a/vite.config.ts
+++ b/vite.config.ts
@@ -9,8 +9,7 @@ export default defineConfig({
port: 3000,
proxy: {
'/s': server,
- '^/raw/.*': server,
- '^/info/.*': server,
+ '^/api/.*': server,
'/config': server,
'^/s/.*': {
target: 'ws://localhost:8080',
diff --git a/webapp/components/File.tsx b/webapp/components/File.tsx
index eca832d9..c5016ad7 100644
--- a/webapp/components/File.tsx
+++ b/webapp/components/File.tsx
@@ -1,20 +1,28 @@
import { useRef, useState, ChangeEvent } from 'react'
import styles from './File.module.scss'
-import { putRawFile, getRawFile } from '../lib/api'
+import { putBoxFile, getBoxFile, delBoxFile } from '../lib/api'
let tmp: File | undefined
function File(props: {
recver: boolean,
+ isBox: boolean,
percent: number,
handleFile: (files: FileList | null) => void,
getFile: () => void }) {
const hiddenFileInput = useRef(null)
const handleClick = () => {
- props.recver
- ? props.getFile()
- : hiddenFileInput.current?.click?.()
+ if (props.recver) {
+ if (props.isBox) {
+ getBoxFile()
+ } else {
+ props.getFile()
+ }
+ } else {
+ hiddenFileInput.current?.click?.()
+ }
+
}
const [filename, setFilename] = useState('Select File')
@@ -35,14 +43,22 @@ function File(props: {
// This id e2e test need
id="upload"
type="file"
- name="f"
ref={ hiddenFileInput }
onChange={ (ev: ChangeEvent) => { handleFile(ev.target.files); tmp = ev.target.files?.[0] } }
/>
-
-
-
-
+
+ { props.recver
+ ?
+ :
+ }
>
)
}
diff --git a/webapp/components/index.tsx b/webapp/components/index.tsx
index 7dc157fe..dc5d56f4 100644
--- a/webapp/components/index.tsx
+++ b/webapp/components/index.tsx
@@ -1,7 +1,7 @@
import { useEffect, useRef, useState } from 'react'
import { ProtoHttpToWs } from '../lib/util'
-import { getServer, getConfig, shareGetRoom, getRawInfo } from '../lib/api'
+import { getServer, getConfig, shareGetRoom, getBoxInfo } from '../lib/api'
import LibFgg from '../libfgg/libfgg'
import log from 'loglevel'
import { Meta } from '../libfgg/pool/data'
@@ -22,6 +22,7 @@ function Index(props: { address: string }) {
const [meta, setMeta] = useState(null)
const [progress, setProgress] = useState(0)
const [recver, setRecver] = useState(false)
+ const [isBox, setIsBox] = useState(false)
const refIce = useRef([])
@@ -79,11 +80,11 @@ function Index(props: { address: string }) {
useEffect(() => {
const load = async () => {
-
- let data = await getRawInfo()
- console.log(data)
+ let data = await getBoxInfo()
if (data) {
setMeta(data)
+ setIsBox(true)
+ setRecver(true)
}
}
load()
@@ -101,6 +102,7 @@ function Index(props: { address: string }) {
{ handleFile(files) } }
getFile={ getfile }
diff --git a/webapp/lib/api.ts b/webapp/lib/api.ts
index df56a0d6..a298ecf5 100644
--- a/webapp/lib/api.ts
+++ b/webapp/lib/api.ts
@@ -26,27 +26,34 @@ async function getRoom(): Promise {
return result.room || ''
}
-async function putRawFile(f: File): Promise {
+async function putBoxFile(f: File): Promise {
const room = shareGetRoom(window.location.href)
if (room === '') throw "not room"
let formData = new FormData()
formData.append('f', f, f.name)
- await fetch(`/raw/${room}`, {
+ await fetch(`/api/file/${room}`, {
method: "post",
body: formData,
})
return
}
-async function getRawFile(): Promise {
+async function getBoxFile(): Promise {
const room = shareGetRoom(window.location.href)
- window.open(`/raw/${room}`)
+ window.open(`/api/file/${room}`)
}
-async function getRawInfo(): Promise {
+async function delBoxFile(): Promise {
const room = shareGetRoom(window.location.href)
- const response = await fetch(`/info/${room}`)
+ await fetch(`/api/file/${room}`, {
+ method: "delete",
+ })
+}
+
+async function getBoxInfo(): Promise {
+ const room = shareGetRoom(window.location.href)
+ const response = await fetch(`/api/info/${room}`)
if (response.status == 200) {
return await response.json()
}
@@ -57,8 +64,9 @@ export {
getConfig,
getRoom,
getLogLevel,
- putRawFile,
- getRawFile,
- getRawInfo,
+ putBoxFile,
+ getBoxFile,
+ delBoxFile,
+ getBoxInfo,
shareGetRoom,
}
From a3a48d1b20d85ab0a6c4b77e9eaeeb9867eed3a1 Mon Sep 17 00:00:00 2001
From: a-wing <1@233.email>
Date: Thu, 8 Dec 2022 19:38:05 +0800
Subject: [PATCH 10/11] feat(webapp): add reload #199
---
webapp/components/File.tsx | 12 ++++++++++--
webapp/components/index.tsx | 21 +++++++++++++--------
2 files changed, 23 insertions(+), 10 deletions(-)
diff --git a/webapp/components/File.tsx b/webapp/components/File.tsx
index c5016ad7..90a426a0 100644
--- a/webapp/components/File.tsx
+++ b/webapp/components/File.tsx
@@ -7,6 +7,7 @@ let tmp: File | undefined
function File(props: {
recver: boolean,
isBox: boolean,
+ reLoad: () => void,
percent: number,
handleFile: (files: FileList | null) => void,
getFile: () => void }) {
@@ -51,12 +52,19 @@ function File(props: {
?
:
}
>
diff --git a/webapp/components/index.tsx b/webapp/components/index.tsx
index dc5d56f4..42f89d7e 100644
--- a/webapp/components/index.tsx
+++ b/webapp/components/index.tsx
@@ -78,15 +78,19 @@ function Index(props: { address: string }) {
}
}, [props.address])
- useEffect(() => {
- const load = async () => {
- let data = await getBoxInfo()
- if (data) {
- setMeta(data)
- setIsBox(true)
- setRecver(true)
- }
+ const load = async () => {
+ let data = await getBoxInfo()
+ if (data) {
+ setMeta(data)
+ setIsBox(true)
+ setRecver(true)
+ } else {
+ setIsBox(false)
+ setRecver(false)
+ setMeta(null)
}
+ }
+ useEffect(() => {
load()
}, [props.address])
@@ -103,6 +107,7 @@ function Index(props: { address: string }) {
{ handleFile(files) } }
getFile={ getfile }
From 446ff0b209350ffbacc77648abef70d6ed282254 Mon Sep 17 00:00:00 2001
From: a-wing <1@233.email>
Date: Sat, 10 Dec 2022 13:26:20 +0800
Subject: [PATCH 11/11] chore(deps): update gomod
---
go.mod | 24 +++++++++++------------
go.sum | 62 +++++++++++++++++++++++++++++++++++++---------------------
2 files changed, 52 insertions(+), 34 deletions(-)
diff --git a/go.mod b/go.mod
index fc3b188d..2255369e 100644
--- a/go.mod
+++ b/go.mod
@@ -12,28 +12,28 @@ require (
github.com/pion/datachannel v1.5.2
github.com/pion/logging v0.2.2
github.com/pion/sctp v1.8.3
- github.com/pion/transport v0.13.1
- github.com/pion/turn/v2 v2.0.8
- github.com/pion/webrtc/v3 v3.1.47
+ github.com/pion/transport v0.14.1
+ github.com/pion/turn/v2 v2.0.9
+ github.com/pion/webrtc/v3 v3.1.49
github.com/qingstor/go-mime v0.1.0
github.com/rs/xid v1.4.0
github.com/sb-im/jsonrpc-lite v0.2.0
- github.com/schollz/progressbar/v3 v3.12.0
+ github.com/schollz/progressbar/v3 v3.12.2
github.com/sirupsen/logrus v1.9.0
github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e
github.com/spf13/cobra v1.6.1
go.etcd.io/bbolt v1.3.6
- golang.org/x/term v0.1.0
+ golang.org/x/term v0.3.0
)
require (
github.com/google/uuid v1.3.0 // indirect
- github.com/inconshreveable/mousetrap v1.0.1 // indirect
+ github.com/inconshreveable/mousetrap v1.1.0 // indirect
github.com/mattn/go-runewidth v0.0.14 // indirect
github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db // indirect
github.com/pion/dtls/v2 v2.1.5 // indirect
- github.com/pion/ice/v2 v2.2.11 // indirect
- github.com/pion/interceptor v0.1.11 // indirect
+ github.com/pion/ice/v2 v2.2.12 // indirect
+ github.com/pion/interceptor v0.1.12 // indirect
github.com/pion/mdns v0.0.5 // indirect
github.com/pion/randutil v0.1.0 // indirect
github.com/pion/rtcp v1.2.10 // indirect
@@ -42,9 +42,9 @@ require (
github.com/pion/srtp/v2 v2.0.10 // indirect
github.com/pion/stun v0.3.5 // indirect
github.com/pion/udp v0.1.1 // indirect
- github.com/rivo/uniseg v0.4.2 // indirect
+ github.com/rivo/uniseg v0.4.3 // indirect
github.com/spf13/pflag v1.0.5 // indirect
- golang.org/x/crypto v0.0.0-20221010152910-d6f0a8c073c2 // indirect
- golang.org/x/net v0.0.0-20221004154528-8021a29435af // indirect
- golang.org/x/sys v0.1.0 // indirect
+ golang.org/x/crypto v0.4.0 // indirect
+ golang.org/x/net v0.4.0 // indirect
+ golang.org/x/sys v0.3.0 // indirect
)
diff --git a/go.sum b/go.sum
index bcd32b6b..dc5a1516 100644
--- a/go.sum
+++ b/go.sum
@@ -33,8 +33,9 @@ github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/ad
github.com/hashicorp/golang-lru v0.5.4 h1:YDjusn29QI/Das2iO9M0BHnIbxPeyuCHsjMW+lJfyTc=
github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4=
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
-github.com/inconshreveable/mousetrap v1.0.1 h1:U3uMjPSQEBMNp1lFxmllqCPM6P5u/Xq7Pgzkat/bFNc=
github.com/inconshreveable/mousetrap v1.0.1/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
+github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
+github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
github.com/k0kubun/go-ansi v0.0.0-20180517002512-3bf9e2903213/go.mod h1:vNUNkEQ1e29fT/6vq2aBdFsgNPmy8qMdSay1npru+Sw=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
@@ -57,10 +58,11 @@ github.com/pion/datachannel v1.5.2 h1:piB93s8LGmbECrpO84DnkIVWasRMk3IimbcXkTQLE6
github.com/pion/datachannel v1.5.2/go.mod h1:FTGQWaHrdCwIJ1rw6xBIfZVkslikjShim5yr05XFuCQ=
github.com/pion/dtls/v2 v2.1.5 h1:jlh2vtIyUBShchoTDqpCCqiYCyRFJ/lvf/gQ8TALs+c=
github.com/pion/dtls/v2 v2.1.5/go.mod h1:BqCE7xPZbPSubGasRoDFJeTsyJtdD1FanJYL0JGheqY=
-github.com/pion/ice/v2 v2.2.11 h1:wiAy7TSrVZ4KdyjC0CcNTkwltz9ywetbe4wbHLKUbIg=
-github.com/pion/ice/v2 v2.2.11/go.mod h1:NqUDUao6SjSs1+4jrqpexDmFlptlVhGxQjcymXLaVvE=
-github.com/pion/interceptor v0.1.11 h1:00U6OlqxA3FFB50HSg25J/8cWi7P6FbSzw4eFn24Bvs=
+github.com/pion/ice/v2 v2.2.12 h1:n3M3lUMKQM5IoofhJo73D3qVla+mJN2nVvbSPq32Nig=
+github.com/pion/ice/v2 v2.2.12/go.mod h1:z2KXVFyRkmjetRlaVRgjO9U3ShKwzhlUylvxKfHfd5A=
github.com/pion/interceptor v0.1.11/go.mod h1:tbtKjZY14awXd7Bq0mmWvgtHB5MDaRN7HV3OZ/uy7s8=
+github.com/pion/interceptor v0.1.12 h1:CslaNriCFUItiXS5o+hh5lpL0t0ytQkFnUcbbCs2Zq8=
+github.com/pion/interceptor v0.1.12/go.mod h1:bDtgAD9dRkBZpWHGKaoKb42FhDHTG2rX8Ii9LRALLVA=
github.com/pion/logging v0.2.2 h1:M9+AIj/+pxNsDfAT64+MAVgJO0rsyLnoJKCqf//DoeY=
github.com/pion/logging v0.2.2/go.mod h1:k0/tDVsRCX2Mb2ZEmTqNa7CWsQPc+YYCB7Q+5pahoms=
github.com/pion/mdns v0.0.5 h1:Q2oj/JB3NqfzY9xGZ1fPzZzK7sDSD8rZPOvcIQ10BCw=
@@ -73,7 +75,6 @@ github.com/pion/rtcp v1.2.10/go.mod h1:ztfEwXZNLGyF1oQDttz/ZKIBaeeg/oWbRYqzBM9TL
github.com/pion/rtp v1.7.13 h1:qcHwlmtiI50t1XivvoawdCGTP4Uiypzfrsap+bijcoA=
github.com/pion/rtp v1.7.13/go.mod h1:bDb5n+BFZxXx0Ea7E5qe+klMuqiBrP+w8XSjiWtCUko=
github.com/pion/sctp v1.8.0/go.mod h1:xFe9cLMZ5Vj6eOzpyiKjT9SwGM4KpK/8Jbw5//jc+0s=
-github.com/pion/sctp v1.8.2/go.mod h1:xFe9cLMZ5Vj6eOzpyiKjT9SwGM4KpK/8Jbw5//jc+0s=
github.com/pion/sctp v1.8.3 h1:LWcciN2ptLkw9Ugp/Ks2E76fiWy7yk3Wm79D6oFbFNo=
github.com/pion/sctp v1.8.3/go.mod h1:OHbDjdk7kg+L+7TJim9q/qGVefdEJohuA2SZyihccgI=
github.com/pion/sdp/v3 v3.0.6 h1:WuDLhtuFUUVpTfus9ILC4HRyHsW6TdugjEX/QY9OiUw=
@@ -85,28 +86,30 @@ github.com/pion/stun v0.3.5/go.mod h1:gDMim+47EeEtfWogA37n6qXZS88L5V6LqFcf+DZA2U
github.com/pion/transport v0.12.2/go.mod h1:N3+vZQD9HlDP5GWkZ85LohxNsDcNgofQmyL6ojX5d8Q=
github.com/pion/transport v0.12.3/go.mod h1:OViWW9SP2peE/HbwBvARicmAVnesphkNkCVZIWJ6q9A=
github.com/pion/transport v0.13.0/go.mod h1:yxm9uXpK9bpBBWkITk13cLo1y5/ur5VQpG22ny6EP7g=
-github.com/pion/transport v0.13.1 h1:/UH5yLeQtwm2VZIPjxwnNFxjS4DFhyLfS4GlfuKUzfA=
github.com/pion/transport v0.13.1/go.mod h1:EBxbqzyv+ZrmDb82XswEE0BjfQFtuw1Nu6sjnjWCsGg=
-github.com/pion/turn/v2 v2.0.8 h1:KEstL92OUN3k5k8qxsXHpr7WWfrdp7iJZHx99ud8muw=
+github.com/pion/transport v0.14.1 h1:XSM6olwW+o8J4SCmOBb/BpwZypkHeyM0PGFCxNQBr40=
+github.com/pion/transport v0.14.1/go.mod h1:4tGmbk00NeYA3rUa9+n+dzCCoKkcy3YlYb99Jn2fNnI=
github.com/pion/turn/v2 v2.0.8/go.mod h1:+y7xl719J8bAEVpSXBXvTxStjJv3hbz9YFflvkpcGPw=
+github.com/pion/turn/v2 v2.0.9 h1:jcDPw0Vfd5I4iTc7s0Upfc2aMnyu2lgJ9vV0SUrNC1o=
+github.com/pion/turn/v2 v2.0.9/go.mod h1:DQlwUwx7hL8Xya6TTAabbd9DdKXTNR96Xf5g5Qqso/M=
github.com/pion/udp v0.1.1 h1:8UAPvyqmsxK8oOjloDk4wUt63TzFe9WEJkg5lChlj7o=
github.com/pion/udp v0.1.1/go.mod h1:6AFo+CMdKQm7UiA0eUPA8/eVCTx8jBIITLZHc9DWX5M=
-github.com/pion/webrtc/v3 v3.1.47 h1:2dFEKRI1rzFvehXDq43hK9OGGyTGJSusUi3j6QKHC5s=
-github.com/pion/webrtc/v3 v3.1.47/go.mod h1:8U39MYZCLVV4sIBn01htASVNkWQN2zDa/rx5xisEXWs=
+github.com/pion/webrtc/v3 v3.1.49 h1:rbsNGxK9jMYts+xE6zYAJMUQHnGwmk/JYze8yttW+to=
+github.com/pion/webrtc/v3 v3.1.49/go.mod h1:kHf/o47QW4No1rgpsFux/h7lUhtUnwFnSFDZOXeLapw=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/qingstor/go-mime v0.1.0 h1:FhTJtM7TRm9pfgCXpjGUxqwbumGojrgE9ecRz5PXvfc=
github.com/qingstor/go-mime v0.1.0/go.mod h1:EDwWgaMufg74m7futsF0ZGkdA52ajjAycY+XDeV8M88=
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
-github.com/rivo/uniseg v0.4.2 h1:YwD0ulJSJytLpiaWua0sBDusfsCZohxjxzVTYjwxfV8=
-github.com/rivo/uniseg v0.4.2/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
+github.com/rivo/uniseg v0.4.3 h1:utMvzDsuh3suAEnhH0RdHmoPbU648o6CvXxTx4SBMOw=
+github.com/rivo/uniseg v0.4.3/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
github.com/rs/xid v1.4.0 h1:qd7wPTDkN6KQx2VmMBLrpHkiyQwgFXRnkOLacUiaSNY=
github.com/rs/xid v1.4.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg=
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/sb-im/jsonrpc-lite v0.2.0 h1:r45VX/mESjt6SYBX7V6yIDr3EUWi40EjQIXzz0B0lzo=
github.com/sb-im/jsonrpc-lite v0.2.0/go.mod h1:dHV+dbbKl+2+/pDgAavKuAWdEfjGWGck0M7Au+Tkj8Q=
-github.com/schollz/progressbar/v3 v3.12.0 h1:BVFNM+V/l20JUYkJ5fO/CnOYPV3Et3tON8FmJepkdq4=
-github.com/schollz/progressbar/v3 v3.12.0/go.mod h1:g7QSuwyGpqCjVQPFZXA31MSxtrhka9Y9LMdF+XT77/Y=
+github.com/schollz/progressbar/v3 v3.12.2 h1:yLqqqpQNMxGxHY8uEshRihaHWwa0rf0yb7/Zrpgq2C0=
+github.com/schollz/progressbar/v3 v3.12.2/go.mod h1:HFJYIYQQJX32UJdyoigUl19xoV6aMwZt6iX/C30RWfg=
github.com/sclevine/agouti v3.0.0+incompatible/go.mod h1:b4WX9W9L1sfQKXeJf1mUTLZKJ48R1S7H23Ji7oFO5Bw=
github.com/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0=
github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
@@ -117,23 +120,31 @@ github.com/spf13/cobra v1.6.1/go.mod h1:IOw/AERYS7UzyrGinqmz6HLUo219MORXGxhbaJUq
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
+github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
+github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
-github.com/stretchr/testify v1.7.1 h1:5TQK59W5E3v0r2duFAb7P95B6hEeOyEnHRa8MjYSMTY=
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
+github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
+github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk=
+github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
+github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
go.etcd.io/bbolt v1.3.5/go.mod h1:G5EMThwa9y8QZGBClrRx5EY+Yw9kAhnjy3bSjsnlVTQ=
go.etcd.io/bbolt v1.3.6 h1:/ecaJf0sk1l4l6V4awd65v2C3ILy7MSj+s/x1ADCIMU=
go.etcd.io/bbolt v1.3.6/go.mod h1:qXsaaIqmgQH0T+OPdb99Bf+PKfBBQVAdyD6TY9G8XM4=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
+golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.0.0-20220427172511-eb4f295cb31f/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
-golang.org/x/crypto v0.0.0-20221010152910-d6f0a8c073c2 h1:x8vtB3zMecnlqZIwJNUUpwYKYSqCz5jXbiyv0ZJJZeI=
golang.org/x/crypto v0.0.0-20221010152910-d6f0a8c073c2/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
+golang.org/x/crypto v0.4.0 h1:UVQgzMY87xqpKNgb+kDsll2Igd33HszWHFLmpaRMq/8=
+golang.org/x/crypto v0.4.0/go.mod h1:3quD/ATkf6oY+rnes5c3ExXTbLc8mueNue5/DoinL80=
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
+golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
@@ -141,17 +152,20 @@ golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.0.0-20201201195509-5d6afe98e0b7/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
+golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk=
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20211201190559-0a0e4e1bb54c/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
golang.org/x/net v0.0.0-20220531201128-c960675eff93/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
-golang.org/x/net v0.0.0-20221002022538-bcab6841153b/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk=
-golang.org/x/net v0.0.0-20221004154528-8021a29435af h1:wv66FM3rLZGPdxpYL+ApnDe2HzHcTFta3z5nsc13wI4=
-golang.org/x/net v0.0.0-20221004154528-8021a29435af/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk=
+golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
+golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco=
+golang.org/x/net v0.4.0 h1:Q5QPcMlvfxFTAPV0+07Xz/MpK9NTXu2VDUuy0FeMfaU=
+golang.org/x/net v0.4.0/go.mod h1:MBQ8lrhLObU/6UmLb4fmbmk5OcyYmqtbGd/9yIeKjEE=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
@@ -171,22 +185,26 @@ golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.0.0-20220608164250-635b8c9b7f68/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220622161953-175b2fd9d664/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.0.0-20221010170243-090e33056c14/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.1.0 h1:kunALQeHf1/185U1i0GOB/fy1IPRDDpuoOOqRReG57U=
golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.3.0 h1:w8ZOecv6NaNa/zC8944JTU3vz4u6Lagfk4RPQxv92NQ=
+golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
-golang.org/x/term v0.1.0 h1:g6Z6vPFA9dYBAF7DWcH6sCcOntplXsDKcliusYijMlw=
golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
+golang.org/x/term v0.3.0 h1:qoo4akIqOcDME5bhc/NgxUdovd6BSS2uMsVjB56q1xI=
+golang.org/x/term v0.3.0/go.mod h1:q750SLmJuPmVoN1blW3UFBPREJfb1KmY3vwxfr+nFDA=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
+golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
+golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=