├── example.gif ├── assets └── icon.png ├── CHANGELOG.md ├── main.go ├── uninstall.sh ├── downloader ├── client.go ├── reader.go ├── human_readable_bytes.go ├── option.go └── downloader.go ├── .github ├── dependabot.yml └── workflows │ └── release.yml ├── .gitignore ├── Makefile ├── generate-asset.go ├── cmd ├── version.go ├── config.go └── dl.go ├── notifier ├── notifier.go ├── icon.go └── asset.go ├── go.mod ├── CONTRIBUTING.md ├── logger └── logger.go ├── values └── values.go ├── LICENSE.md ├── install.sh ├── update ├── update.go └── github.go ├── config └── config.go ├── README.md └── go.sum /example.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thedevsaddam/dl/HEAD/example.gif -------------------------------------------------------------------------------- /assets/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thedevsaddam/dl/HEAD/assets/icon.png -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | * Change notifier package 2 | * Change binary update time from 7days -> 3days 3 | * Show update logs after self-update -------------------------------------------------------------------------------- /main.go: -------------------------------------------------------------------------------- 1 | //go:generate go run generate-asset.go 2 | 3 | package main 4 | 5 | import "github.com/thedevsaddam/dl/cmd" 6 | 7 | func main() { 8 | cmd.Execute() 9 | } 10 | -------------------------------------------------------------------------------- /uninstall.sh: -------------------------------------------------------------------------------- 1 | #! /bin/bash 2 | 3 | TARGET=/usr/local/bin/dl 4 | MESSAGE_START="Removing dl" 5 | MESSAGE_END="dl removed" 6 | 7 | echo "$MESSAGE_START" 8 | rm $TARGET 9 | echo "$MESSAGE_END" 10 | -------------------------------------------------------------------------------- /downloader/client.go: -------------------------------------------------------------------------------- 1 | package downloader 2 | 3 | import "net/http" 4 | 5 | // HTTPClient interface 6 | type HTTPClient interface { 7 | // Do sends an HTTP request and returns an HTTP response 8 | Do(req *http.Request) (*http.Response, error) 9 | } 10 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - package-ecosystem: "gomod" 4 | directory: "/" 5 | schedule: 6 | interval: "daily" 7 | target-branch: "dev" 8 | # Labels on pull requests for version updates only 9 | labels: 10 | - "go mod dependencies" -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | vendor 2 | *.DS_Store 3 | dl 4 | .coverage.txt 5 | bin/linux_386 6 | bin/linux_amd64 7 | bin/linux_arm64 8 | bin/mac_amd64 9 | bin/mac_arm64 10 | bin/windows_386.exe 11 | bin/windows_amd64.exe 12 | file_example_MP3_700KB.mp3 13 | Apex.2021.720p.WEBRip.x264.AAC-%5BYTS.MX%5D.mp4 14 | go1.14.2.src.tar.gz -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | .PHONY: all test coverage 2 | all: test build 3 | build: 4 | go build -o dl 5 | binary: 6 | go run generate-asset.go 7 | ./build.sh 8 | install: 9 | go install ./... 10 | test: 11 | go test ./... -v -coverprofile .coverage.txt 12 | go tool cover -func .coverage.txt 13 | coverage: test 14 | go tool cover -html=.coverage.txt -------------------------------------------------------------------------------- /downloader/reader.go: -------------------------------------------------------------------------------- 1 | package downloader 2 | 3 | import ( 4 | "io" 5 | "sync/atomic" 6 | ) 7 | 8 | // Reader represents a custom reader 9 | type Reader struct { 10 | io.Reader 11 | 12 | downloaded *uint64 13 | } 14 | 15 | func (r Reader) Read(b []byte) (int, error) { 16 | n, err := r.Reader.Read(b) 17 | atomic.AddUint64(r.downloaded, uint64(n)) 18 | return n, err 19 | } 20 | -------------------------------------------------------------------------------- /generate-asset.go: -------------------------------------------------------------------------------- 1 | // +build generateasset 2 | 3 | package main 4 | 5 | import ( 6 | "log" 7 | "net/http" 8 | 9 | "github.com/shurcooL/vfsgen" 10 | ) 11 | 12 | func main() { 13 | var fs http.FileSystem = http.Dir("./assets/") 14 | err := vfsgen.Generate(fs, vfsgen.Options{ 15 | Filename: "./notifier/asset.go", 16 | PackageName: "notifier", 17 | VariableName: "AssetFS", 18 | }) 19 | if err != nil { 20 | log.Fatalln(err) 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /cmd/version.go: -------------------------------------------------------------------------------- 1 | package cmd 2 | 3 | import ( 4 | "fmt" 5 | 6 | "github.com/spf13/cobra" 7 | ) 8 | 9 | var cmdVersion = &cobra.Command{ 10 | Use: "version", 11 | Short: "Display application version", 12 | Long: `Display application version`, 13 | Run: version, 14 | } 15 | 16 | func init() { 17 | cmdDL.AddCommand(cmdVersion) 18 | } 19 | 20 | func version(cmd *cobra.Command, args []string) { 21 | fmt.Println(logo) 22 | fmt.Println("Version:", Version) 23 | fmt.Println("Git commit:", GitCommit) 24 | fmt.Println("Build date:", BuildDate) 25 | } 26 | -------------------------------------------------------------------------------- /notifier/notifier.go: -------------------------------------------------------------------------------- 1 | package notifier 2 | 3 | import "github.com/gen2brain/beeep" 4 | 5 | // Notifier represents a notifier type 6 | type Notifier struct { 7 | appName string 8 | iconPath string 9 | } 10 | 11 | // New return a new notifier 12 | func New(name string) *Notifier { 13 | writeIcon() // call every time 14 | return &Notifier{ 15 | appName: name, 16 | } 17 | } 18 | 19 | // Notify send a notification to device 20 | func (n *Notifier) Notify(title, text string) { 21 | iconPath, _ := getIconPath() 22 | beeep.Notify(title, text, iconPath) 23 | } 24 | -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module github.com/thedevsaddam/dl 2 | 3 | go 1.16 4 | 5 | require ( 6 | github.com/Masterminds/semver v1.5.0 7 | github.com/briandowns/spinner v1.16.0 8 | github.com/gen2brain/beeep v0.0.0-20210529141713-5586760f0cc1 9 | github.com/kardianos/osext v0.0.0-20190222173326-2bc1f35cddc0 10 | github.com/schollz/progressbar/v3 v3.8.3 11 | github.com/shurcooL/httpfs v0.0.0-20190707220628-8d4bc4ba7749 // indirect 12 | github.com/shurcooL/vfsgen v0.0.0-20200824052919-0d455de96546 13 | github.com/spf13/cobra v1.2.1 14 | github.com/thedevsaddam/retry v0.0.0-20200324223450-9769a859cc6d 15 | ) 16 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing 2 | 3 | ## Must follow the guide for issues 4 | - Use the search tool before opening a new issue. 5 | - Please provide source code and stack trace if you found a bug. 6 | - Please review the existing issues and provide feedback to them 7 | 8 | ## Pull Request Process 9 | - Open your pull request against `dev` branch 10 | - It should pass all tests in the available continuous integrations systems such as TravisCI. 11 | - You should add/modify tests to cover your proposed code changes. 12 | - If your pull request contains a new feature, please document it on the README. 13 | -------------------------------------------------------------------------------- /downloader/human_readable_bytes.go: -------------------------------------------------------------------------------- 1 | package downloader 2 | 3 | import ( 4 | "fmt" 5 | "math" 6 | ) 7 | 8 | // humanaReadableBytes convert Bytes to human readable form 9 | func humanaReadableBytes(s float64) string { 10 | units := []string{"B", "kB", "MB", "GB", "TB", "PB", "EB"} 11 | base := 1024.0 12 | if s < 10 { 13 | return fmt.Sprintf("%2.0f B", s) 14 | } 15 | e := math.Floor(math.Log(s) / math.Log(base)) 16 | suffix := units[int(e)] 17 | val := math.Floor(float64(s)/math.Pow(base, e)*10+0.5) / 10 18 | f := "%.0f" 19 | if val < 10 { 20 | f = "%.1f" 21 | } 22 | 23 | return fmt.Sprintf("%s %s", fmt.Sprintf(f, val), suffix) 24 | } 25 | -------------------------------------------------------------------------------- /logger/logger.go: -------------------------------------------------------------------------------- 1 | package logger 2 | 3 | import ( 4 | "fmt" 5 | "log" 6 | ) 7 | 8 | type Logger interface { 9 | Println(v ...interface{}) 10 | Printf(format string, v ...interface{}) 11 | } 12 | 13 | // defautlLogger implements the logger contract 14 | type defautlLogger struct { 15 | verbose bool 16 | } 17 | 18 | // New return a default implementation of custom logger 19 | func New(verbose bool) Logger { 20 | return defautlLogger{verbose: verbose} 21 | } 22 | 23 | func (d defautlLogger) Println(v ...interface{}) { 24 | if d.verbose { 25 | log.Println("dl:", fmt.Sprintln(v...)) 26 | } 27 | } 28 | 29 | func (d defautlLogger) Printf(format string, v ...interface{}) { 30 | if d.verbose { 31 | log.Println("dl:", fmt.Sprintf(format, v...)) 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /notifier/icon.go: -------------------------------------------------------------------------------- 1 | package notifier 2 | 3 | import ( 4 | "io/ioutil" 5 | "log" 6 | "os" 7 | "path/filepath" 8 | ) 9 | 10 | const ( 11 | configDirectory = ".dl" 12 | icon = ".dl" + "/icon.png" 13 | ) 14 | 15 | func getIconPath() (string, error) { 16 | homeDir, err := os.UserHomeDir() 17 | if err != nil { 18 | return "", err 19 | } 20 | return filepath.Join(homeDir, icon), nil 21 | } 22 | 23 | func writeIcon() { 24 | iconPath, _ := getIconPath() 25 | if _, err := os.Stat(iconPath); err == nil { 26 | return 27 | } 28 | 29 | fp, err := AssetFS.Open("/icon.png") 30 | if err != nil { 31 | log.Fatal(err) 32 | } 33 | bs, err := ioutil.ReadAll(fp) 34 | if err != nil { 35 | log.Fatal(err) 36 | } 37 | if err == nil { 38 | err := ioutil.WriteFile(iconPath, bs, 0644) 39 | if err != nil { 40 | log.Println(err) 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /values/values.go: -------------------------------------------------------------------------------- 1 | package values 2 | 3 | import "strings" 4 | 5 | // MapStrSliceString maps a string key to a list of MapStrSliceString. 6 | type MapStrSliceString map[string][]string 7 | 8 | // Get return the keys name based on extension. 9 | func (v MapStrSliceString) Get(ext string) string { 10 | if v == nil { 11 | return "" 12 | } 13 | for k, extensions := range v { 14 | for _, e := range extensions { 15 | if strings.ToLower(strings.TrimSpace(e)) == strings.ToLower(strings.TrimSpace(ext)) { 16 | return k 17 | } 18 | } 19 | } 20 | return "" 21 | } 22 | 23 | // Add adds the value to key. It appends to any existing 24 | // MapStrSliceString associated with key. 25 | func (v MapStrSliceString) Add(key, value string) { 26 | for _, e := range v[key] { 27 | if strings.ToLower(strings.TrimSpace(e)) == strings.ToLower(strings.TrimSpace(value)) { 28 | return 29 | } 30 | } 31 | v[key] = append(v[key], value) 32 | } 33 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | # The MIT License (MIT) 2 | 3 | Copyright (c) 2021 Saddam H 4 | 5 | > Permission is hereby granted, free of charge, to any person obtaining a copy 6 | > of this software and associated documentation files (the "Software"), to deal 7 | > in the Software without restriction, including without limitation the rights 8 | > to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | > copies of the Software, and to permit persons to whom the Software is 10 | > furnished to do so, subject to the following conditions: 11 | > 12 | > The above copyright notice and this permission notice shall be included in 13 | > all copies or substantial portions of the Software. 14 | > 15 | > THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | > IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | > FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | > AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | > LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | > OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | > THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /install.sh: -------------------------------------------------------------------------------- 1 | #! /bin/bash 2 | 3 | exec_curl(){ 4 | echo "Found dl latest version: $VERSION" 5 | echo "Download may take few minutes depending on your internet speed" 6 | echo "Downloading dl to $2" 7 | curl -L --silent --connect-timeout 30 --retry-delay 5 --retry 5 -o "$2" "$1" 8 | } 9 | 10 | OS=`uname` 11 | ARCH=`uname -m` 12 | VERSION=$1 13 | URL=https://github.com/thedevsaddam/dl 14 | TARGET=/usr/local/bin/dl 15 | MESSAGE_START="Installing dl" 16 | MESSAGE_END="Installation complete" 17 | 18 | if [ "$VERSION" == "" ]; then 19 | LATEST_RELEASE=$(curl -L -s -H 'Accept: application/json' $URL/releases/latest) 20 | VERSION=$(echo $LATEST_RELEASE | sed -e 's/.*"tag_name":"\([^"]*\)".*/\1/') 21 | fi 22 | 23 | if [ "$OS" == "Darwin" ]; then 24 | if [ "$ARCH" == "x86_64" ]; then 25 | exec_curl $URL/releases/download/$VERSION/darwin_amd64 $TARGET 26 | echo "$MESSAGE_START" 27 | chmod +x $TARGET 28 | echo "$MESSAGE_END" 29 | dl 30 | fi 31 | 32 | if [ "$ARCH" == "arm64" ] || [ "$ARCH" == "aarch64" ]; then 33 | exec_curl $URL/releases/download/$VERSION/darwin_arm64 $TARGET 34 | echo "$MESSAGE_START" 35 | chmod +x $TARGET 36 | echo "$MESSAGE_END" 37 | dl 38 | fi 39 | 40 | elif [ "$OS" == "Linux" ]; then 41 | if [ "$ARCH" == "x86_64" ]; then 42 | exec_curl $URL/releases/download/$VERSION/linux_amd64 $TARGET 43 | echo "$MESSAGE_START" 44 | chmod +x $TARGET 45 | echo "$MESSAGE_END" 46 | dl 47 | fi 48 | 49 | if [ "$ARCH" == "arm64" ] || [ "$ARCH" == "aarch64" ]; then 50 | exec_curl $URL/releases/download/$VERSION/linux_arm64 $TARGET 51 | echo "$MESSAGE_START" 52 | chmod +x $TARGET 53 | echo "$MESSAGE_END" 54 | dl 55 | fi 56 | 57 | if [ "$ARCH" == "i368" ]; then 58 | exec_curl $URL/releases/download/$VERSION/linux_386 $TARGET 59 | chmod +x $TARGET 60 | dl 61 | fi 62 | fi 63 | -------------------------------------------------------------------------------- /update/update.go: -------------------------------------------------------------------------------- 1 | package update 2 | 3 | import ( 4 | "context" 5 | "errors" 6 | "fmt" 7 | "runtime" 8 | "time" 9 | 10 | "github.com/Masterminds/semver" 11 | "github.com/briandowns/spinner" 12 | ) 13 | 14 | const ( 15 | layoutISO = "2006-01-02" 16 | updateInDays = 3 17 | ) 18 | 19 | // SelfUpdate update the application to its latest version 20 | // if the current release is 3days old and has a new update 21 | func SelfUpdate(ctx context.Context, buildDate, version string) error { 22 | if buildDate == "unknown" { 23 | return errors.New("update: unable to update based on unkown build date/version") 24 | } 25 | currBinaryReleaseDate, err := time.Parse(layoutISO, buildDate) 26 | if err != nil { 27 | return fmt.Errorf("update: %v", err) 28 | } 29 | if (time.Since(currBinaryReleaseDate).Hours() / 24) <= updateInDays { 30 | return nil 31 | } 32 | 33 | releaseInfo, err := fetchReleaseInfo(ctx) 34 | if err != nil { 35 | return fmt.Errorf("update: %v", err) 36 | } 37 | 38 | if releaseInfo.Draft || releaseInfo.Prerelease { 39 | return nil 40 | } 41 | 42 | c, err := semver.NewConstraint(">" + version) 43 | if err != nil { 44 | return fmt.Errorf("update: %v", err) 45 | } 46 | 47 | v, err := semver.NewVersion(releaseInfo.TagName) 48 | if err != nil { 49 | return fmt.Errorf("update: %v", err) 50 | } 51 | // Check if the version meets the constraints. The a variable will be true. 52 | if !c.Check(v) { 53 | return nil 54 | } 55 | 56 | os := runtime.GOOS 57 | arch := runtime.GOARCH 58 | fmt.Println("Found newer version:", releaseInfo.TagName) 59 | 60 | s := spinner.New(spinner.CharSets[70], 100*time.Millisecond, spinner.WithHiddenCursor(true)) // code:39 is earth for the lib 61 | s.Prefix = fmt.Sprintf("Updating from %s to %s ( ", version, releaseInfo.Name) 62 | s.Suffix = ")" 63 | s.Start() 64 | name := fmt.Sprintf("%s_%s", os, arch) 65 | if os == "windows" { 66 | name = name + ".exe" 67 | } 68 | err = updateBinary(ctx, releaseInfo.getDownloadURL(name)) 69 | s.Stop() 70 | fmt.Println() 71 | fmt.Println("Update includes:") 72 | fmt.Print(releaseInfo.Body) 73 | fmt.Println() 74 | 75 | return err 76 | } 77 | -------------------------------------------------------------------------------- /cmd/config.go: -------------------------------------------------------------------------------- 1 | package cmd 2 | 3 | import ( 4 | "encoding/json" 5 | "fmt" 6 | "log" 7 | "os" 8 | "strings" 9 | 10 | "github.com/spf13/cobra" 11 | "github.com/thedevsaddam/dl/config" 12 | ) 13 | 14 | var ( 15 | path string 16 | subPath string 17 | autoUpdate string 18 | 19 | cmdConfig = &cobra.Command{ 20 | Use: "config", 21 | Short: "Config set configuration values", 22 | Long: `Config set configuration values`, 23 | Run: setConfig, 24 | } 25 | ) 26 | 27 | func init() { 28 | cmdConfig.Flags().StringVarP(&path, "path", "p", "", "destination directory where the file will be downloaded") 29 | cmdConfig.Flags().StringVarP(&subPath, "subpath", "s", "", "sub directory map in this format subdirectoryName:.ext1,.ext2. e.g: video:.mp4,.mkv") 30 | cmdConfig.Flags().IntVarP(&concurrent, "concurrent", "c", 0, "number of concurrent process will be running, default: 5") 31 | cmdConfig.Flags().BoolVarP(&debug, "debug", "d", false, "display configuration") 32 | cmdConfig.Flags().StringVarP(&autoUpdate, "auto-update", "a", "", "enable/disable auto-update. e.g: -a true, -a false") 33 | cmdDL.AddCommand(cmdConfig) 34 | } 35 | 36 | func setConfig(cmd *cobra.Command, args []string) { 37 | // if user provide "." then set current directory as root directory 38 | if path == "." { 39 | dir, err := os.Getwd() 40 | if err != nil { 41 | log.Fatalln(err) 42 | } 43 | path = dir 44 | } 45 | 46 | oldCfg := config.DefaultConfig() 47 | newCfg := config.Config{Directory: path, Concurrency: uint(concurrent)} 48 | newCfg.AutoUpdate = oldCfg.AutoUpdate 49 | if autoUpdate == "true" { 50 | newCfg.AutoUpdate = true 51 | } else if autoUpdate == "false" { 52 | newCfg.AutoUpdate = false 53 | } 54 | 55 | if subPath != "" { 56 | newCfg.SubDirMap = config.DefaultConfig().SubDirMap // assign old config 57 | 58 | pp := strings.Split(subPath, ":") 59 | if len(pp) > 1 { 60 | subDir := pp[0] 61 | extensions := strings.Split(pp[1], ",") 62 | for _, e := range extensions { 63 | newCfg.SubDirMap.Add(subDir, e) 64 | } 65 | } 66 | } 67 | 68 | if err := config.SetConfig(newCfg); err != nil { 69 | log.Fatalln(err) 70 | } 71 | 72 | if debug { 73 | if err := config.LoadDefaultConfig(); err != nil { 74 | log.Fatalln(err) 75 | } 76 | bb, err := json.MarshalIndent(config.DefaultConfig(), "", " ") 77 | if err == nil { 78 | fmt.Println(string(bb)) 79 | } 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /downloader/option.go: -------------------------------------------------------------------------------- 1 | package downloader 2 | 3 | import ( 4 | "errors" 5 | "strings" 6 | 7 | "github.com/thedevsaddam/dl/logger" 8 | "github.com/thedevsaddam/dl/values" 9 | ) 10 | 11 | // option describes type for providing configuration options to JSONQ 12 | type option struct { 13 | concurrency int 14 | path string // directory 15 | subPathMap values.MapStrSliceString // sub directory 16 | skipSubPathMap bool 17 | log logger.Logger 18 | verbose bool 19 | } 20 | 21 | // OptionFunc represents a contract for option func, it basically set options to jsonq instance options 22 | type OptionFunc func(*DownloadManager) error 23 | 24 | // WithConcurrency set number of concurrent request to be made 25 | func WithConcurrency(c uint) OptionFunc { 26 | return func(dm *DownloadManager) error { 27 | if c == 0 { 28 | return errors.New("dl: concurrency can't be empty") 29 | } 30 | dm.option.concurrency = int(c) 31 | return nil 32 | } 33 | } 34 | 35 | // WithFilePath set the directory to save file 36 | func WithFilePath(path string) OptionFunc { 37 | return func(dm *DownloadManager) error { 38 | if path == "" { 39 | return errors.New("dl: filepath can't be empty") 40 | } 41 | dm.option.path = strings.TrimSpace(strings.TrimSuffix(path, "/")) 42 | return nil 43 | } 44 | } 45 | 46 | // WithSubPathMap set the directory to save file 47 | func WithSubPathMap(m values.MapStrSliceString) OptionFunc { 48 | return func(dm *DownloadManager) error { 49 | dm.option.subPathMap = m 50 | return nil 51 | } 52 | } 53 | 54 | // WithSkipSubPathMap skip subdirectory resolving 55 | func WithSkipSubPathMap() OptionFunc { 56 | return func(dm *DownloadManager) error { 57 | dm.option.skipSubPathMap = true 58 | return nil 59 | } 60 | } 61 | 62 | // WithFilename set the filename 63 | func WithFilename(name string) OptionFunc { 64 | return func(dm *DownloadManager) error { 65 | if name == "" { 66 | return errors.New("dl: filename can't be empty") 67 | } 68 | dm.fileName = strings.TrimSpace(name) 69 | return nil 70 | } 71 | } 72 | 73 | // WithVerbose enable debug output log 74 | func WithVerbose() OptionFunc { 75 | return func(dm *DownloadManager) error { 76 | dm.option.verbose = true 77 | return nil 78 | } 79 | } 80 | 81 | // WithLogger set custom logger 82 | func WithLogger(l logger.Logger) OptionFunc { 83 | return func(dm *DownloadManager) error { 84 | dm.option.log = l 85 | return nil 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /update/github.go: -------------------------------------------------------------------------------- 1 | package update 2 | 3 | import ( 4 | "context" 5 | "encoding/json" 6 | "errors" 7 | "io" 8 | "net/http" 9 | "os" 10 | "path/filepath" 11 | "time" 12 | 13 | "github.com/kardianos/osext" 14 | ) 15 | 16 | type ( 17 | // ReleaseInfo represents github latest release info 18 | ReleaseInfo struct { 19 | TagName string `json:"tag_name"` 20 | Name string `json:"name"` 21 | Body string `json:"body"` 22 | Draft bool `json:"draft"` 23 | Prerelease bool `json:"prerelease"` 24 | CreatedAt time.Time `json:"created_at"` 25 | PublishedAt time.Time `json:"published_at"` 26 | Assets []Asset `json:"assets"` 27 | } 28 | Asset struct { 29 | Name string `json:"name"` 30 | Size int `json:"size"` 31 | DownloadCount int `json:"download_count"` 32 | BrowserDownloadURL string `json:"browser_download_url"` 33 | } 34 | ) 35 | 36 | func (r *ReleaseInfo) getDownloadURL(name string) string { 37 | for _, a := range r.Assets { 38 | if a.Name == name { 39 | return a.BrowserDownloadURL 40 | } 41 | } 42 | return "" 43 | } 44 | 45 | // fetchReleaseInfo return githublatest release info 46 | func fetchReleaseInfo(ctx context.Context) (*ReleaseInfo, error) { 47 | url := "https://api.github.com/repos/thedevsaddam/dl/releases/latest" 48 | ctx, cancel := context.WithTimeout(ctx, 3*time.Second) 49 | defer cancel() 50 | req, err := http.NewRequestWithContext(ctx, http.MethodGet, url, nil) 51 | if err != nil { 52 | return nil, err 53 | } 54 | resp, err := http.DefaultClient.Do(req) 55 | if err != nil { 56 | return nil, err 57 | } 58 | defer resp.Body.Close() 59 | 60 | if resp.StatusCode != http.StatusOK { 61 | return nil, errors.New("update: failed to fetch latest release") 62 | } 63 | 64 | rf := ReleaseInfo{} 65 | if err := json.NewDecoder(resp.Body).Decode(&rf); err != nil { 66 | return nil, err 67 | } 68 | return &rf, nil 69 | } 70 | 71 | // updateBinary download the binary in current binary and replace the old one 72 | func updateBinary(ctx context.Context, url string) error { 73 | if url == "" { 74 | return errors.New("update: empty download url") 75 | } 76 | ctx, cancel := context.WithTimeout(ctx, 120*time.Second) 77 | defer cancel() 78 | req, err := http.NewRequestWithContext(ctx, http.MethodGet, url, nil) 79 | if err != nil { 80 | return err 81 | } 82 | resp, err := http.DefaultClient.Do(req) 83 | if err != nil { 84 | return err 85 | } 86 | defer resp.Body.Close() 87 | 88 | if resp.StatusCode != http.StatusOK { 89 | return errors.New("update: failed to fetch binary file") 90 | } 91 | 92 | dir, err := osext.ExecutableFolder() 93 | if err != nil { 94 | return err 95 | } 96 | 97 | fileName := filepath.Join(dir, filepath.Base(os.Args[0])) 98 | tmpFile := fileName + ".tmp" 99 | 100 | if err := os.Chmod(fileName, 0777); err != nil { 101 | return err 102 | } 103 | 104 | if err := os.Rename(fileName, tmpFile); err != nil { 105 | return err 106 | } 107 | 108 | f, err := os.Create(fileName) 109 | if err != nil { 110 | return err 111 | } 112 | 113 | if err := os.Chmod(fileName, 0777); err != nil { 114 | return err 115 | } 116 | 117 | _, err = io.Copy(f, resp.Body) 118 | if err != nil { 119 | if err := os.Rename(tmpFile, fileName); err != nil { 120 | return err 121 | } 122 | return err 123 | } 124 | 125 | return os.Remove(tmpFile) 126 | } 127 | -------------------------------------------------------------------------------- /config/config.go: -------------------------------------------------------------------------------- 1 | package config 2 | 3 | import ( 4 | "encoding/json" 5 | "errors" 6 | "io/ioutil" 7 | "os" 8 | "path/filepath" 9 | 10 | "github.com/thedevsaddam/dl/values" 11 | ) 12 | 13 | const ( 14 | configDirectory = ".dl" 15 | configFileName = configDirectory + "/config.json" 16 | ) 17 | 18 | var ( 19 | defaultConfig Config 20 | ) 21 | 22 | // Config represent configurations for the download manager 23 | type Config struct { 24 | AutoUpdate bool `json:"auto_update"` 25 | Directory string `json:"directory"` 26 | Concurrency uint `json:"concurrency"` 27 | SubDirMap values.MapStrSliceString `json:"sub_dir_map"` 28 | } 29 | 30 | func getConfigDir() (string, error) { 31 | homeDir, err := os.UserHomeDir() 32 | if err != nil { 33 | return "", err 34 | } 35 | return filepath.Join(homeDir, configDirectory), nil 36 | } 37 | 38 | func getConfigFileName() (string, error) { 39 | homeDir, err := os.UserHomeDir() 40 | if err != nil { 41 | return "", err 42 | } 43 | return filepath.Join(homeDir, configFileName), nil 44 | } 45 | 46 | // LoadDefaultConfig load configuration if exist 47 | func LoadDefaultConfig() error { 48 | fn, err := getConfigFileName() 49 | if err != nil { 50 | return err 51 | } 52 | if _, err := os.Stat(fn); errors.Is(err, os.ErrNotExist) { 53 | subDir := make(values.MapStrSliceString) 54 | subDir["audio"] = []string{".aif", ".cda", ".mid", ".midi", ".mp3", 55 | ".mpa", ".ogg", ".wav", ".wma", ".wpl"} 56 | 57 | subDir["video"] = []string{".3g2", ".3gp", ".avi", ".flv", ".h264", 58 | ".m4v", ".mkv", ".mov", ".mp4", ".mpg", ".mpeg", ".rm", ".swf", 59 | ".vob", ".wmv"} 60 | 61 | subDir["image"] = []string{".ai", ".bmp", ".ico", ".jpeg", ".jpg", 62 | ".png", ".ps", ".psd", ".svg", ".tif", ".tiff"} 63 | 64 | subDir["document"] = []string{".xls", ".xlsm", ".xlsx", ".ods", ".doc", 65 | ".odt", ".pdf", ".rtf", ".tex", ".txt", ".wpd", ".md"} 66 | 67 | CreateConfig(Config{ 68 | AutoUpdate: true, 69 | Concurrency: 5, 70 | Directory: "", 71 | SubDirMap: subDir, 72 | }) 73 | } 74 | contents, err := ioutil.ReadFile(fn) 75 | if err != nil { 76 | return err 77 | } 78 | return json.Unmarshal(contents, &defaultConfig) 79 | } 80 | 81 | // CreateConfig create a config file in user home directory 82 | func CreateConfig(c Config) error { 83 | bb, err := json.Marshal(c) 84 | if err != nil { 85 | return err 86 | } 87 | 88 | configDir, err := getConfigDir() 89 | if err != nil { 90 | return err 91 | } 92 | 93 | if err := os.MkdirAll(configDir, os.ModePerm); err != nil { 94 | return err 95 | } 96 | 97 | fn, err := getConfigFileName() 98 | if err != nil { 99 | return err 100 | } 101 | 102 | return ioutil.WriteFile(fn, bb, 0644) 103 | } 104 | 105 | // SetConfig set specific config file in user home directory 106 | func SetConfig(c Config) error { 107 | oldCfg := defaultConfig 108 | if c.Concurrency != 0 { 109 | oldCfg.Concurrency = c.Concurrency 110 | } 111 | 112 | if c.Directory != "" { 113 | oldCfg.Directory = c.Directory 114 | } 115 | 116 | oldCfg.AutoUpdate = c.AutoUpdate 117 | 118 | for k, extensions := range c.SubDirMap { 119 | for _, e := range extensions { 120 | oldCfg.SubDirMap.Add(k, e) 121 | } 122 | } 123 | 124 | return CreateConfig(oldCfg) 125 | } 126 | 127 | // DefaultConfig return the default config 128 | func DefaultConfig() Config { 129 | return defaultConfig 130 | } 131 | -------------------------------------------------------------------------------- /.github/workflows/release.yml: -------------------------------------------------------------------------------- 1 | name: release 2 | 3 | on: 4 | push: 5 | tags: 6 | - "v[0-9]+.*" 7 | 8 | jobs: 9 | build_release: 10 | name: build_release 11 | runs-on: ubuntu-latest 12 | steps: 13 | - name: checkout and setup 14 | uses: actions/checkout@v2 15 | with: 16 | fetch-depth: 0 17 | - name: update Golang 18 | uses: actions/setup-go@v2 19 | with: 20 | go-version: '1.17.2' 21 | - name: build binary files 22 | run: make binary 23 | - name: list directory 24 | run: ls -la && ls -la bin 25 | - name: release 26 | uses: actions/create-release@v1 27 | id: create_release 28 | with: 29 | draft: false 30 | prerelease: false 31 | release_name: ${{ github.ref }} 32 | tag_name: ${{ github.ref }} 33 | body_path: CHANGELOG.md 34 | env: 35 | GITHUB_TOKEN: ${{ github.token }} 36 | - name: upload darwin_amd64 binary 37 | uses: actions/upload-release-asset@v1 38 | env: 39 | GITHUB_TOKEN: ${{ github.token }} 40 | with: 41 | upload_url: ${{ steps.create_release.outputs.upload_url }} 42 | asset_path: bin/darwin_amd64 43 | asset_name: darwin_amd64 44 | asset_content_type: application/octet-stream 45 | - name: upload darwin_arm64 binary 46 | uses: actions/upload-release-asset@v1 47 | env: 48 | GITHUB_TOKEN: ${{ github.token }} 49 | with: 50 | upload_url: ${{ steps.create_release.outputs.upload_url }} 51 | asset_path: bin/darwin_arm64 52 | asset_name: darwin_arm64 53 | asset_content_type: application/octet-stream 54 | - name: upload linux_amd64 binary 55 | uses: actions/upload-release-asset@v1 56 | env: 57 | GITHUB_TOKEN: ${{ github.token }} 58 | with: 59 | upload_url: ${{ steps.create_release.outputs.upload_url }} 60 | asset_path: bin/linux_amd64 61 | asset_name: linux_amd64 62 | asset_content_type: application/octet-stream 63 | - name: upload linux_arm64 binary 64 | uses: actions/upload-release-asset@v1 65 | env: 66 | GITHUB_TOKEN: ${{ github.token }} 67 | with: 68 | upload_url: ${{ steps.create_release.outputs.upload_url }} 69 | asset_path: bin/linux_arm64 70 | asset_name: linux_arm64 71 | asset_content_type: application/octet-stream 72 | - name: upload linux_386 binary 73 | uses: actions/upload-release-asset@v1 74 | env: 75 | GITHUB_TOKEN: ${{ github.token }} 76 | with: 77 | upload_url: ${{ steps.create_release.outputs.upload_url }} 78 | asset_path: bin/linux_386 79 | asset_name: linux_386 80 | asset_content_type: application/octet-stream 81 | - name: upload windows_386 binary 82 | uses: actions/upload-release-asset@v1 83 | env: 84 | GITHUB_TOKEN: ${{ github.token }} 85 | with: 86 | upload_url: ${{ steps.create_release.outputs.upload_url }} 87 | asset_path: bin/windows_386.exe 88 | asset_name: windows_386.exe 89 | asset_content_type: application/octet-stream 90 | - name: upload windows_amd64 binary 91 | uses: actions/upload-release-asset@v1 92 | env: 93 | GITHUB_TOKEN: ${{ github.token }} 94 | with: 95 | upload_url: ${{ steps.create_release.outputs.upload_url }} 96 | asset_path: bin/windows_amd64.exe 97 | asset_name: windows_amd64.exe 98 | asset_content_type: application/octet-stream -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | DL 2 | --- 3 | Command-line file downloader tool 4 | 5 | ### Usage 6 | 7 | ```sh 8 | $ dl -u https://www.url.com/foo.ext 9 | ``` 10 | 11 | ![Example screenshots](example.gif) 12 | 13 | 14 | #### Installation on Mac/Linux 15 | ```bash 16 | curl https://raw.githubusercontent.com/thedevsaddam/dl/main/install.sh -o install.sh \ 17 | && chmod +x install.sh \ 18 | && ./install.sh \ 19 | && rm install.sh 20 | ``` 21 | 22 | #### Uninstallation 23 | ```bash 24 | curl https://raw.githubusercontent.com/thedevsaddam/dl/main/uninstall.sh -o uninstall.sh \ 25 | && chmod +x uninstall.sh \ 26 | && ./uninstall.sh \ 27 | && rm uninstall.sh 28 | ``` 29 | 30 | #### Windows 31 | **For windows download the binary and set environment variable so that you can access the binary from terminal** 32 | 33 | **[Download Binary](https://github.com/thedevsaddam/dl/releases)** 34 | 35 | ### Download options 36 | 37 | ```sh 38 | $ dl -u https://www.url.com/foo.ext 39 | # or with concurrency 40 | $ dl -u https://www.url.com/foo.ext -c 10 41 | # with debug mode enabled (if you are curious!) 42 | $ dl -u https://www.url.com/foo.ext -c 10 -d 43 | # with custom output file name 44 | $ dl -u https://www.url.com/foo.ext -c 10 -d -n bar.ext 45 | ``` 46 | ### Configurations 47 | 48 | **Setup destination directory** 49 | 50 | ```sh 51 | # set current directory path as destination directory 52 | $ dl config -p . 53 | # or set other directory 54 | $ dl config -p $HOME/Downloads 55 | ``` 56 | Note: If you have `destination` directory set then all files automatically will be saved there. If you want to override on the fly then use `-p .` flag to download in the current directory. 57 | By default the `destination` directory value is empty that means the file will be downloaded in the current directory. 58 | 59 | **Setup sub-directory/extensions** 60 | 61 | Note: If `destination` directory is not set then the sub-directory/extensions will NOT WORK 62 | 63 | ```sh 64 | # set sub-directory based on extensions 65 | # this will create a "binary" diectory inside root directory. 66 | # all downloads with .exe, .dmg extensions will be stored there 67 | $ dl config -s "binary:.exe,.dmg" 68 | ``` 69 | 70 | **Setup concurrency** 71 | 72 | ```sh 73 | # default concurrency is 5, you can set default value by passing -c flag in config 74 | $ dl config -c 10 75 | ``` 76 | 77 | ### Default configurations 78 | 79 |
config.json 80 |
 81 | {
 82 | 	"auto_update":true,
 83 | 	"directory":"",
 84 | 	"concurrency":5,
 85 | 	"sub_dir_map":{
 86 | 		"audio":[
 87 | 			".aif",
 88 | 			".cda",
 89 | 			".mid",
 90 | 			".midi",
 91 | 			".mp3",
 92 | 			".mpa",
 93 | 			".ogg",
 94 | 			".wav",
 95 | 			".wma",
 96 | 			".wpl"
 97 | 		],
 98 | 		"document":[
 99 | 			".xls",
100 | 			".xlsm",
101 | 			".xlsx",
102 | 			".ods",
103 | 			".doc",
104 | 			".odt",
105 | 			".pdf",
106 | 			".rtf",
107 | 			".tex",
108 | 			".txt",
109 | 			".wpd",
110 | 			".md"
111 | 		],
112 | 		"image":[
113 | 			".ai",
114 | 			".bmp",
115 | 			".ico",
116 | 			".jpeg",
117 | 			".jpg",
118 | 			".png",
119 | 			".ps",
120 | 			".psd",
121 | 			".svg",
122 | 			".tif",
123 | 			".tiff"
124 | 		],
125 | 		"video":[
126 | 			".3g2",
127 | 			".3gp",
128 | 			".avi",
129 | 			".flv",
130 | 			".h264",
131 | 			".m4v",
132 | 			".mkv",
133 | 			".mov",
134 | 			".mp4",
135 | 			".mpg",
136 | 			".mpeg",
137 | 			".rm",
138 | 			".swf",
139 | 			".vob",
140 | 			".wmv"
141 | 		]
142 | 	}
143 | }
144 | 
145 |
146 | 147 | 148 | ### Contribution 149 | Your suggestions will be more than appreciated. 150 | [Read the contribution guide here](CONTRIBUTING.md) 151 | 152 | ### See all [contributors](https://github.com/thedevsaddam/dl/graphs/contributors) 153 | 154 | ### **License** 155 | The **dl** is an open-source software licensed under the [MIT License](LICENSE.md). 156 | -------------------------------------------------------------------------------- /cmd/dl.go: -------------------------------------------------------------------------------- 1 | package cmd 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | "log" 7 | netUrl "net/url" 8 | "os" 9 | "strings" 10 | 11 | "github.com/spf13/cobra" 12 | "github.com/thedevsaddam/dl/config" 13 | "github.com/thedevsaddam/dl/downloader" 14 | "github.com/thedevsaddam/dl/logger" 15 | "github.com/thedevsaddam/dl/notifier" 16 | "github.com/thedevsaddam/dl/update" 17 | ) 18 | 19 | var logo = ` 20 | _____ _ 21 | | __ \| | 22 | | | | | | 23 | | | | | | 24 | | |__| | |____ 25 | |_____/|______| 26 | 27 | Command-line file downloader tool 28 | For more info visit: https://github.com/thedevsaddam/dl 29 | ` 30 | 31 | const ( 32 | unknown = "unknown" 33 | ) 34 | 35 | var ( 36 | url string 37 | name string 38 | concurrent int 39 | debug bool 40 | 41 | GitCommit = unknown 42 | Version = unknown 43 | BuildDate = unknown 44 | 45 | // cmdDL is the root command of DL application 46 | cmdDL = &cobra.Command{ 47 | Use: "dl", 48 | Short: "Command-line file downloader tool", 49 | Long: logo, 50 | // Args: cobra.MinimumNArgs(1), 51 | Run: startDownload, 52 | } 53 | ) 54 | 55 | // Execute executes the root command 56 | func Execute() { 57 | if err := cmdDL.Execute(); err != nil { 58 | os.Exit(1) 59 | } 60 | } 61 | 62 | func init() { 63 | cobra.OnInitialize(initConfig) 64 | cmdDL.Flags().StringVarP(&url, "url", "u", "", "url should be the address where the file will be downloaded. e.g: https://example.com/foo.jpg") 65 | cmdDL.Flags().StringVarP(&name, "name", "n", "", "destination name with extension. e.g: foo.jpg") 66 | cmdDL.Flags().StringVarP(&path, "path", "p", "", "destination directory where the file will be downloaded") 67 | cmdDL.Flags().IntVarP(&concurrent, "concurrent", "c", 0, "number of concurrent process will be running, default: 5") 68 | cmdDL.Flags().BoolVarP(&debug, "debug", "d", false, "debug print the essential logs") 69 | } 70 | 71 | func initConfig() { 72 | err := config.LoadDefaultConfig() 73 | if err != nil { 74 | log.Fatalln(err) 75 | } 76 | } 77 | 78 | // startDownload fire the whole download process and orchestrate other dependent processes 79 | func startDownload(cmd *cobra.Command, args []string) { 80 | cfg := config.DefaultConfig() 81 | 82 | if cfg.AutoUpdate { 83 | err := update.SelfUpdate(context.Background(), BuildDate, Version) 84 | if err != nil { 85 | fmt.Println("Error: failed to update dl:", err) //this error can be skipped 86 | } 87 | } 88 | 89 | url = strings.TrimSpace(url) 90 | if len(url) == 0 { 91 | return 92 | } 93 | 94 | if _, err := netUrl.ParseRequestURI(url); err != nil { 95 | fmt.Println("Error: invalid URL:", err) 96 | return 97 | } 98 | 99 | dm := downloader.New() 100 | 101 | if debug { 102 | dm.ApplyOption(downloader.WithVerbose()) 103 | dm.ApplyOption(downloader.WithLogger(logger.New(true))) 104 | } 105 | 106 | con := cfg.Concurrency 107 | if concurrent != 0 { // assuming default is 5 108 | con = uint(concurrent) 109 | } 110 | dm.ApplyOption(downloader.WithConcurrency(uint(con))) 111 | 112 | dm.ApplyOption(downloader.WithSubPathMap(cfg.SubDirMap)) 113 | 114 | if cfg.Directory != "" { 115 | dm.ApplyOption(downloader.WithFilePath(cfg.Directory)) 116 | } 117 | 118 | // if provided in flag then override the pverious path config 119 | if path != "" { 120 | // if user provide "." then set current directory as root directory 121 | if path == "." { 122 | dir, err := os.Getwd() 123 | if err != nil { 124 | log.Fatalln(err) 125 | } 126 | path = dir 127 | } 128 | dm.ApplyOption(downloader.WithFilePath(path)) 129 | dm.ApplyOption(downloader.WithSkipSubPathMap()) 130 | } 131 | 132 | if name != "" { 133 | dm.ApplyOption(downloader.WithFilename(name)) 134 | } 135 | 136 | errs := dm.Download(url).Errors() 137 | if len(errs) > 0 { 138 | fmt.Printf("\nDownload failed\n") 139 | if debug { 140 | for _, e := range errs { 141 | log.Println("Error:", e) 142 | } 143 | } 144 | os.Exit(1) 145 | return 146 | } 147 | 148 | n := notifier.New("DL [Terminal Downloader]") 149 | n.Notify("Download complete!", fmt.Sprintf("File: %s (%s)", dm.GetFileName(), dm.GetFileSize())) 150 | } 151 | -------------------------------------------------------------------------------- /downloader/downloader.go: -------------------------------------------------------------------------------- 1 | package downloader 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | "io" 7 | "net/http" 8 | "os" 9 | "os/signal" 10 | "path" 11 | "path/filepath" 12 | "strconv" 13 | "sync" 14 | "sync/atomic" 15 | "syscall" 16 | "time" 17 | 18 | "github.com/briandowns/spinner" 19 | "github.com/schollz/progressbar/v3" 20 | "github.com/thedevsaddam/dl/logger" 21 | "github.com/thedevsaddam/retry" 22 | ) 23 | 24 | const ( 25 | defaultConcurrency = 5 26 | ) 27 | 28 | // DownloadManager ... 29 | type DownloadManager struct { 30 | option option 31 | client HTTPClient 32 | 33 | stop chan os.Signal 34 | completed chan bool 35 | 36 | fileName string // filename with extension 37 | fileSize uint64 // file size in bytes 38 | totalDownloaded uint64 // total file downloaded in bytes 39 | totalChunkCompleted int32 // total completed chunks 40 | location string // where the file stored 41 | 42 | totalTimeTaken time.Duration // total time taken to complete downloading 43 | 44 | errors []error // contains all the errors 45 | 46 | mu *sync.Mutex 47 | wg *sync.WaitGroup 48 | } 49 | 50 | // New return a instance of DownloadManager with options 51 | func New(options ...OptionFunc) *DownloadManager { 52 | dm := &DownloadManager{ 53 | wg: &sync.WaitGroup{}, 54 | mu: &sync.Mutex{}, 55 | client: http.DefaultClient, 56 | 57 | errors: make([]error, 0), 58 | 59 | stop: make(chan os.Signal, 1), 60 | completed: make(chan bool, 1), 61 | } 62 | 63 | // set default options 64 | dm.option.concurrency = defaultConcurrency 65 | dm.option.log = logger.New(dm.option.verbose) // enable verbose for applying options 66 | 67 | // apply user provided options 68 | for _, option := range options { 69 | if err := option(dm); err != nil { 70 | fmt.Println("Error:", err) 71 | } 72 | } 73 | 74 | return dm 75 | } 76 | 77 | // ApplyOption apply single option to the download manager 78 | func (d *DownloadManager) ApplyOption(option OptionFunc) error { 79 | return option(d) 80 | } 81 | 82 | // addError add error to the error bag 83 | func (d *DownloadManager) addError(e error) { 84 | d.mu.Lock() 85 | d.errors = append(d.errors, e) 86 | d.mu.Unlock() 87 | } 88 | 89 | // Errors return the error bag 90 | func (d *DownloadManager) Errors() []error { 91 | return d.errors 92 | } 93 | 94 | // renderProgressBar paint & repaint progressbar 95 | func (d *DownloadManager) renderProgressBar(ctx context.Context, maxSize int) { 96 | pb := progressbar.NewOptions(maxSize, 97 | progressbar.OptionSetDescription(fmt.Sprintf("[red][0/%d][reset] Downloading:", d.option.concurrency)), 98 | progressbar.OptionFullWidth(), 99 | progressbar.OptionEnableColorCodes(true), 100 | progressbar.OptionShowBytes(true), 101 | progressbar.OptionSetPredictTime(true), 102 | progressbar.OptionShowCount(), 103 | progressbar.OptionThrottle(500*time.Millisecond), 104 | progressbar.OptionOnCompletion( 105 | func() { 106 | fmt.Printf("\nFile name: %s\n", d.fileName) 107 | fmt.Printf("File size: %s\n", humanaReadableBytes(float64(d.fileSize))) 108 | fmt.Printf("Time elapsed: %s\n", d.totalTimeTaken) 109 | fmt.Printf("Location: %s\n", d.location) 110 | }, 111 | ), 112 | ) 113 | 114 | ticker := time.NewTicker(500 * time.Millisecond) 115 | 116 | go func() { 117 | for { 118 | select { 119 | case <-d.stop: 120 | ticker.Stop() 121 | return 122 | case <-d.completed: 123 | ticker.Stop() 124 | d.option.log.Println("Download completed!") 125 | return 126 | case <-ticker.C: 127 | pb.Describe(fmt.Sprintf("[cyan][%d/%d][reset] Downloading:", d.totalChunkCompleted, d.option.concurrency)) 128 | pb.Set64(int64(d.totalDownloaded)) 129 | } 130 | } 131 | }() 132 | } 133 | 134 | // GetFileName return file name; the value will be available once the download start 135 | func (d *DownloadManager) GetFileName() string { 136 | return d.fileName 137 | } 138 | 139 | // GetFileSize return file size in human readable format; the value will be available once the download start 140 | func (d *DownloadManager) GetFileSize() string { 141 | return humanaReadableBytes(float64(d.fileSize)) 142 | } 143 | 144 | // populateFileInfo do a HTTP/HEAD request and gather meta information; MUST call before download 145 | func (d *DownloadManager) populateFileInfo(ctx context.Context, url string) error { 146 | if d.fileName == "" { 147 | d.fileName = path.Base(url) 148 | } 149 | 150 | d.option.log.Printf("Info: fetching file's meta information: %s\n", url) 151 | retryCount := 0 152 | 153 | err := retry.DoFunc(20, 200*time.Millisecond, func() error { 154 | ctx, cancel := context.WithTimeout(ctx, 3*time.Second) 155 | defer cancel() 156 | 157 | if retryCount > 0 { 158 | d.option.log.Printf("Info: retrying to fetch file's meta information [%d]", retryCount) 159 | } 160 | retryCount++ 161 | 162 | req, err := http.NewRequestWithContext(ctx, http.MethodHead, url, nil) 163 | if err != nil { 164 | d.option.log.Printf("Error: failed to create HTTP/HEAD request: %s\n", err.Error()) 165 | return err 166 | } 167 | 168 | resp, err := d.client.Do(req) 169 | if err != nil { 170 | d.option.log.Printf("Error: failed to perform HTTP/HEAD request: %s\n", err.Error()) 171 | return err 172 | } 173 | 174 | d.fileSize = uint64(resp.ContentLength) 175 | 176 | return resp.Body.Close() 177 | }) 178 | 179 | return err 180 | } 181 | 182 | // downloadChunk download single chunk from the range 183 | func (d *DownloadManager) downloadChunk(ctx context.Context, url string, min, max, chunkNo int, errCh chan error) { 184 | defer d.wg.Done() 185 | 186 | req, err := http.NewRequestWithContext(ctx, http.MethodGet, url, nil) 187 | if err != nil { 188 | d.option.log.Printf("Error[%d]: failed to create HTTP/GET request: %s\n", chunkNo, err.Error()) 189 | errCh <- err 190 | return 191 | } 192 | 193 | rangeHeader := "bytes=" + strconv.Itoa(min) + "-" + strconv.Itoa(max-1) 194 | req.Header.Add("Range", rangeHeader) 195 | resp, err := d.client.Do(req) 196 | if err != nil { 197 | d.option.log.Printf("Error[%d]: failed to perform HTTP/GET request: %s\n", chunkNo, err.Error()) 198 | errCh <- err 199 | return 200 | } 201 | defer resp.Body.Close() 202 | 203 | f, err := os.OpenFile(d.location, os.O_RDWR, 0644) 204 | if err != nil { 205 | d.option.log.Printf("Error[%d]: failed to open file: %s\n", chunkNo, err.Error()) 206 | errCh <- err 207 | return 208 | } 209 | defer f.Close() 210 | 211 | _, err = f.Seek(int64(min), 0) 212 | if err != nil { 213 | d.option.log.Printf("Error[%d]: failed to seek file: %s\n", chunkNo, err.Error()) 214 | errCh <- err 215 | return 216 | } 217 | 218 | _, err = io.Copy(f, Reader{resp.Body, &d.totalDownloaded}) 219 | if err != nil { 220 | d.option.log.Printf("Error[%d]: failed to copy file content: %s\n", chunkNo, err.Error()) 221 | errCh <- err 222 | return 223 | } 224 | 225 | atomic.AddInt32(&d.totalChunkCompleted, 1) 226 | } 227 | 228 | // Download download files based on configurations 229 | func (d *DownloadManager) Download(url string) *DownloadManager { 230 | signal.Notify(d.stop, syscall.SIGKILL, syscall.SIGINT, syscall.SIGQUIT) 231 | go func() { 232 | for range d.stop { 233 | d.option.log.Println("Operation cancelled!") 234 | fmt.Printf("\nOperation cancelled!\n") 235 | // make cursor visible if interruption happened while fetching meta 236 | io.WriteString(os.Stdout, "\033[?25h") 237 | os.Exit(1) 238 | } 239 | }() 240 | 241 | startedAt := time.Now() 242 | fmt.Println() 243 | 244 | ctx := context.Background() 245 | ctx, cancel := context.WithCancel(ctx) 246 | defer cancel() 247 | 248 | s := spinner.New(spinner.CharSets[70], 100*time.Millisecond, spinner.WithHiddenCursor(true)) // code:39 is earth for the lib 249 | s.Prefix = "Fetching file's meta information ( " 250 | s.Suffix = ")" 251 | s.Start() 252 | if err := d.populateFileInfo(ctx, url); err != nil { 253 | d.addError(err) 254 | cancel() 255 | return d 256 | } 257 | s.Stop() 258 | fmt.Println() 259 | 260 | chunkLen := int(d.fileSize) / d.option.concurrency 261 | rem := int(d.fileSize) % d.option.concurrency 262 | 263 | fileName := d.fileName 264 | if d.option.path != "" { 265 | d.option.log.Printf("Info: Root directory: %s\n", d.option.path) 266 | 267 | fileName = filepath.Join(d.option.path, d.fileName) 268 | 269 | if !d.option.skipSubPathMap { 270 | subPath := "other" 271 | if sp := d.option.subPathMap.Get(filepath.Ext(d.fileName)); sp != "" { 272 | subPath = sp 273 | } 274 | 275 | makeSubDir := filepath.Join(d.option.path, subPath) 276 | if _, err := os.Stat(makeSubDir); os.IsNotExist(err) { 277 | if err := os.MkdirAll(makeSubDir, os.ModePerm); err != nil { 278 | d.option.log.Printf("Error: failed to create sub-directory: %s\n", err.Error()) 279 | d.addError(err) 280 | cancel() 281 | return d 282 | } 283 | d.option.log.Printf("Info: Created sub-directory: %s\n", subPath) 284 | } 285 | 286 | fileName = filepath.Join(d.option.path, subPath, d.fileName) 287 | } 288 | } 289 | d.location = fileName // set location value 290 | 291 | if _, err := os.Create(fileName); err != nil { 292 | d.option.log.Printf("Error: failed to create file: %s\n", err.Error()) 293 | d.addError(err) 294 | cancel() 295 | return d 296 | } 297 | d.option.log.Printf("Info: Created file: %s\n", fileName) 298 | 299 | d.option.log.Printf("Downloading file with concurrency value: %d\n", d.option.concurrency) 300 | 301 | errsCh := make(chan error, d.option.concurrency) 302 | defer close(errsCh) 303 | 304 | // read errors 305 | go func() { 306 | for { 307 | if err := <-errsCh; err != nil { 308 | d.addError(err) 309 | if err != context.Canceled { 310 | cancel() 311 | } 312 | } 313 | } 314 | }() 315 | 316 | for i := 0; i < d.option.concurrency; i++ { 317 | d.wg.Add(1) 318 | min := chunkLen * i 319 | max := chunkLen * (i + 1) 320 | if i == d.option.concurrency-1 { 321 | max += rem 322 | } 323 | go d.downloadChunk(ctx, url, min, max, i, errsCh) 324 | } 325 | 326 | // run async task for refreshing progressbar 327 | // if file size is unknown then use infinite progress bar 328 | if d.fileSize > 0 { 329 | d.renderProgressBar(ctx, int(d.fileSize)) 330 | } else { 331 | d.renderProgressBar(ctx, -1) 332 | } 333 | d.wg.Wait() 334 | d.totalTimeTaken = time.Since(startedAt) 335 | time.Sleep(600 * time.Millisecond) 336 | fmt.Println() 337 | d.completed <- true 338 | 339 | close(d.completed) 340 | close(d.stop) 341 | 342 | return d 343 | } 344 | -------------------------------------------------------------------------------- /notifier/asset.go: -------------------------------------------------------------------------------- 1 | // Code generated by vfsgen; DO NOT EDIT. 2 | 3 | package notifier 4 | 5 | import ( 6 | "bytes" 7 | "compress/gzip" 8 | "fmt" 9 | "io" 10 | "io/ioutil" 11 | "net/http" 12 | "os" 13 | pathpkg "path" 14 | "time" 15 | ) 16 | 17 | // AssetFS statically implements the virtual filesystem provided to vfsgen. 18 | var AssetFS = func() http.FileSystem { 19 | fs := vfsgen۰FS{ 20 | "/": &vfsgen۰DirInfo{ 21 | name: "/", 22 | modTime: time.Date(2021, 11, 2, 12, 56, 45, 556174310, time.UTC), 23 | }, 24 | "/icon.png": &vfsgen۰CompressedFileInfo{ 25 | name: "icon.png", 26 | modTime: time.Date(2021, 11, 2, 12, 56, 45, 556291849, time.UTC), 27 | uncompressedSize: 9106, 28 | 29 | compressedContent: []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x02\xff\xb4\x97\xe5\x5b\x13\x8e\xf7\xb0\xb7\xc1\x18\x8c\xd1\xdd\xe5\x50\x60\xa4\x12\x82\x48\x4a\x48\x49\x8d\xd1\x23\x95\x06\x69\x10\x18\x22\x2d\x21\x31\x11\x04\xa5\x91\x1c\xdd\x32\x62\x20\x25\x21\x20\x21\xdd\x5d\x8a\x94\xf0\x5c\x9f\xef\xf5\xfc\x0b\xbf\xb7\xf7\x75\xde\x9c\xf3\xe2\xbe\xce\x1d\xfb\x4c\x57\x9d\x02\xca\x0a\x05\x00\x00\x14\x9a\x1a\xaa\x06\x00\x00\x10\x01\x00\x00\xda\x49\x49\x00\x00\x00\x99\x98\xe2\x5d\x00\x00\x00\xf4\x36\x50\x57\x06\x54\x7e\x67\xdf\x06\x00\xb8\x01\x9a\xaa\x4a\x46\x01\x56\xfb\xd9\x90\x80\x34\xe3\xa9\xbe\x5b\x7f\x65\xd2\x37\x8c\xd4\x08\x4c\x1c\xf7\x07\x96\x4c\xde\xcf\xe5\x35\x95\x95\x21\xe9\x79\xb6\xe6\xad\xf7\xa6\x9f\x15\xc4\x31\x50\x0b\x71\x0b\xee\x9a\xe1\x6b\x04\xe3\x2c\x3d\xc1\xad\x7b\xd1\x14\xc9\xbc\xca\x8e\xfc\xd0\xd7\xf7\x74\x9e\xb2\x16\x6c\x86\x8e\x64\x4f\x48\x07\xde\x3d\x3d\x0b\x3a\x38\x5d\x63\xb1\x3b\x90\xff\xfb\xf1\xb6\xf9\x74\x55\xb8\x51\xec\x19\x0f\x58\x03\x68\x80\x87\x43\xc5\xde\x9f\x6b\xba\xa7\x80\x0a\x00\x02\x00\x10\x23\x05\xc8\x00\x43\xef\x99\x00\x22\x46\xfc\x2c\x88\x63\x87\x83\x35\x80\x20\xc6\x04\xe0\xff\x1d\x7b\x1a\x99\xff\x2f\x40\xf6\xe4\x5d\x22\x7d\x9d\xa2\xe9\xf5\x7d\x0e\x60\x41\x3e\x7b\x24\x29\x37\x53\xe1\x37\x25\xc3\x35\xde\xf8\xf4\x12\xdc\x53\x63\x4d\xe0\x1c\x03\x37\x7a\x26\x07\x94\x40\x49\x7a\x6f\x5f\x9d\x99\xdd\x46\xec\x0d\xf0\xcd\xca\xa7\x15\xff\xf5\x75\x00\xc6\x42\x6c\x0d\xc3\xc7\x84\x77\xf4\x2c\x57\x03\xb8\xe8\x27\x22\xec\x6b\x15\xd2\xb2\xf2\x32\x0b\x30\x17\x50\x6a\xdc\xd0\x4f\x54\x18\x95\xd2\x02\x14\xf6\x0f\xd0\xaf\x57\x14\xda\xad\x29\xec\x0a\xec\x63\x15\xb3\x07\x4e\x63\x5e\xbe\x4a\xfa\x34\x53\x54\x50\x51\x02\x12\x40\xa7\x80\x88\x11\xa9\x6f\x26\xdd\xa4\x52\xa3\xa9\xf1\x17\x80\xef\x44\x9e\xec\x18\xc7\x16\xb7\x1d\xe9\x67\x50\x34\x8f\x0c\x63\xaf\x82\x1d\xc2\xba\x43\xb3\x46\x11\x7a\xcf\x04\x83\x29\xb4\x10\x3a\x75\x89\x13\x12\x00\x0a\x24\xda\x28\xb2\x23\x75\x45\xc2\x7a\x3a\x09\x38\x6a\xfd\xb3\x2f\xa9\x1c\xf0\xc5\xb6\x7c\x00\x70\x90\xac\x19\x76\xdc\x01\x68\x62\x8f\x89\x28\x4d\xa5\xb3\x30\x58\x27\xea\x9b\x95\x69\x62\xde\xe0\xeb\x0a\x45\x4e\x62\x05\x53\x41\x82\xf4\xdc\xe8\x2f\xd4\x83\x47\xa5\x3c\xa1\x9c\xcc\x95\xa0\xbe\x27\x51\x73\x0d\x7d\x68\x1e\x99\x0d\xa2\x00\x0e\xf1\xb3\x74\x79\x91\x67\x55\x56\x48\x0c\xc6\x41\xdd\xaf\xdb\x42\x71\xc7\x19\x10\xd6\x98\x1f\x1c\x7f\x79\xcd\x0c\xab\xe2\xe3\x05\xf4\x0a\x22\x76\x52\x5b\x8e\x9b\x40\xc4\x08\x21\x3a\xf6\x8d\x95\x8b\x89\x00\xc0\x5d\xb3\x99\x8a\xe1\x90\x8a\x24\x6b\x2f\x86\x65\x16\x57\xc7\x87\x52\x57\xca\xf3\xad\x16\x40\x10\x96\x81\x0c\x76\xbc\xa0\xc8\x6e\x64\x62\x3a\x96\xcd\x77\x45\x3d\xd2\x2c\x53\xc4\x9b\x15\xb2\xa4\x71\xfb\x4d\xc0\xe4\x9e\x22\x5e\xe2\xbe\x4e\x76\xa0\x77\x5d\x57\x80\xa7\x36\x60\x74\x60\xa8\xd2\xc2\x2e\x6b\x95\x8c\xde\x4e\xd0\xd2\xad\x99\xdf\x2e\xf1\x65\x1a\xc6\x01\x29\xdb\x43\xe4\x8b\x66\xc5\x7c\x75\xf4\x5d\x36\x6b\xf5\xa9\x5f\x9f\x9d\x98\xd9\x97\x01\x0e\xbe\x85\xbd\xb9\xf0\xf1\xfc\xe5\x16\xe5\xa4\x37\x53\x50\x26\xac\x57\xf8\x23\x0e\x4d\x8a\x52\x2b\xb5\x78\xf8\xc9\xb9\xa5\x6f\xf1\x86\xe5\x0b\x33\x77\x65\x03\x28\x03\x43\x7a\xf5\x0b\xd5\x6d\x3f\x1c\x0f\xa5\xc6\xbd\x1d\x70\xce\x58\x04\x26\x42\x80\x0f\xa4\x07\x0a\x92\xf6\x8c\x30\x36\x8f\x78\x5d\x1b\x92\x6c\x8b\x9e\x49\xde\x53\xc4\x8f\x73\x9b\x45\xf0\xf3\xdc\x50\x63\xfa\xd5\x32\x4e\xea\x29\xa2\x98\x68\x6c\xf8\x5e\x55\x00\xc1\x8b\x25\x20\x62\x44\x3b\xd1\x9d\x6f\xcf\x23\x6c\xde\x5a\xdd\x9f\xf8\xfa\x14\x18\xc5\x10\x83\xa3\xd3\xa0\x32\x50\xd4\x05\x82\xb0\x39\x5e\x34\x2b\xf1\x00\xd8\x94\xdd\xeb\xd9\x01\xc1\x67\x31\xf4\xbf\x3b\x49\xce\xc8\xb7\x55\xa0\x13\xc6\x18\x4c\xa1\xef\xa3\x37\x4d\xd3\x4c\x3b\xf7\x2a\x86\xbf\x64\xf3\x82\x2f\xf9\x06\x90\x02\xa5\x9a\xe9\xaf\x72\x01\x40\x2d\xad\x4c\x15\x0b\x57\xe1\x8f\xa5\x85\x02\xf5\xfa\x15\x78\xfd\x98\x9a\xe1\x52\x73\x7d\x22\x3d\x41\x45\xbc\x41\xd6\x14\xf5\x22\xc9\x92\x58\xfd\x70\xc9\x57\x4a\x30\xb3\x2c\x6f\x57\xc3\x2e\x4e\x51\x47\x3e\x0f\x00\xd4\xd2\xe1\x55\xb9\xbe\x0b\x68\x9f\x78\x90\xdb\x12\x75\x0f\x47\x26\xc0\x8c\xa1\x70\xad\xe2\x99\xfa\x16\xe3\xc2\xc0\x8d\x16\xd0\xb1\x8c\x89\xff\x97\xad\xab\x6f\x96\xbd\xc3\x52\x89\xdf\x7c\x11\x67\x83\xea\x3b\x63\x73\xff\x00\x6b\x51\x03\x82\xb0\x29\x46\x91\xe7\x72\x00\x11\x23\x83\xf4\x9d\x8c\x12\xcc\xf4\xe4\x6f\x6a\x58\x9f\x01\xd2\xd1\x56\xd4\x7e\xb6\x13\x4a\x8d\x4b\x81\xdf\xed\x29\x06\x34\x29\x98\x4a\x5e\xb6\x3e\x81\x7a\xb6\xc5\x31\x9f\x1e\x4a\xc9\x33\xf6\xef\x4d\xb8\x93\xa2\x12\x1c\x8a\x5e\x76\xb7\xff\xfd\x98\xf9\x88\xeb\x4a\x12\xa8\x2f\xf5\xa3\xef\xf8\x4a\xca\x07\x84\xcc\x9b\xe0\x1a\x6e\xe5\x61\xf8\x84\xc9\xcf\xf2\x50\x8f\x4e\x25\x7a\x2e\x13\xc1\xa8\x2d\xf7\x50\x69\xe3\x5c\x0d\xff\xb4\xc0\x25\x26\x5e\x48\xa8\x98\xab\xde\xe1\x7b\x89\x67\xf4\xa4\x2f\xe9\xd2\x1d\xfb\x6a\x90\x7f\x93\x96\x15\xeb\x7f\x17\xd0\x7d\x12\xe4\xee\xd0\x33\x2d\xb1\x18\x95\xb9\x69\xca\xb3\x00\x56\x9c\xff\xc4\xb7\xfb\x4f\x64\xe1\x31\x27\x80\xfb\xb1\xcb\x6d\x96\x0d\x9f\x8c\x94\xd2\x2b\x24\x9a\x2f\xd3\x96\x2f\xd4\xf6\x6a\x88\x2a\x31\x28\xd9\x10\x83\x31\xb6\x4e\xd7\x7e\x0c\x00\x22\x88\x92\xd5\x54\x7a\x19\xa0\x6f\xd5\xd2\xfe\x95\x85\x17\xf3\x84\xf2\xca\xe8\x82\xe3\x3f\x69\xdb\xff\xde\x56\xb5\x4d\x58\xa5\xf5\x7c\x45\x99\xe8\xf1\x6e\xd8\xaf\x55\x59\x80\x4a\x46\x13\x5f\xfa\x49\xb5\x85\xc1\x67\x11\xb7\xc1\x0c\xa0\x24\x89\xba\xbf\xaa\x80\xef\x67\x84\x1c\xb3\x60\x3c\x68\xf0\xca\xf6\xd5\x92\x8c\x7f\xf7\xcb\x0e\x48\x51\xbe\x3f\x38\x36\x7e\x46\xd8\x55\x56\xa9\x01\xc0\x2e\x75\x20\x90\x55\xfc\x28\x31\x79\x75\x8e\x9b\xe4\x6c\xd3\xe2\x3e\x0d\xae\x54\x5d\x31\x23\xfe\x4f\xf8\xe0\x56\xc5\xe7\xc5\x0e\xda\x28\x82\x68\x4e\x74\xec\x7e\xf4\x82\x5a\xda\xd8\x04\x73\x84\x3d\x1c\x6d\x4c\xce\xb2\xa2\x07\x64\x76\x4b\xae\xb4\x8f\xa2\x2f\x29\xc3\x0f\x9c\x0b\x4c\x7f\x09\xe0\xd8\x9d\x16\x49\x51\x6b\x05\x11\x23\x72\x2d\x63\xfe\x12\x1d\x45\xf8\xb1\x7c\x81\x0b\x7c\xd6\x08\xcf\x3e\x36\xc4\x11\x05\x80\x4d\x5d\x2b\xf2\x18\x8d\x34\xf3\x00\xc0\x32\x5a\xd4\x08\x90\x59\xd3\x2e\x82\x1e\xa7\x11\xfe\x0a\x40\xc5\x33\xc0\x59\x5d\xa2\x30\xe2\xa3\x82\xcf\x2b\x13\x1a\x81\x39\x32\x91\xd4\xd0\xc3\xa8\x78\xba\x7a\x22\x82\x04\xa1\xf4\xdc\xe8\xb1\xc9\xf4\xd7\x36\xca\xc6\xda\x48\x34\x23\x28\x43\xb9\xf6\x2c\xb5\x6c\xcf\x03\x3d\x36\x69\x7c\x42\xa3\x2c\x59\x6e\xb0\x14\x4c\x2c\x46\x63\xaa\xad\x6d\x56\x94\xa2\x08\xec\x20\xd2\x1a\x4a\xfe\x1a\xa9\x06\x11\x58\xa2\x06\xc7\x75\x8a\xd3\x88\xf3\x2f\xa0\x0c\xdf\xe9\xe3\x3b\xf0\xd0\xe3\x08\x80\x2b\xc0\x93\x34\x01\x66\x80\xb7\x81\xb6\xbd\x35\xd0\xee\x52\xcb\x04\xe9\x2b\x88\x86\x92\x60\x03\x84\xee\x2d\x50\x1a\xf0\x80\x3f\x96\xe0\x93\x48\xd1\x0f\xe6\x79\x9f\x1a\xae\x3e\x47\x87\x80\x7a\x7e\x66\xeb\xf3\x80\x3f\x96\x62\x32\x6e\xc4\xa0\xfa\x67\x51\x86\x1c\x75\xb3\xa2\x61\x20\xa1\x21\xc8\xeb\x55\xb9\x32\x42\xd1\x8d\x06\x50\x07\xea\xf9\xeb\x0d\x73\x30\xd2\xd0\x3c\x49\xf2\xe4\x2e\x4e\xf9\x15\x09\xe6\x98\x73\x10\x1e\xb9\xea\x06\xe6\xff\xa1\x6a\x88\xaf\xc2\xc7\xc5\x5c\xec\x2f\x70\x2e\xd2\x67\x6f\xd2\x2f\x35\x11\x89\x9f\xbd\xd9\x5c\x31\xa0\x49\xbe\xc5\xa4\xf7\x27\xa9\x03\x06\x8d\x5f\xa8\x1a\x6b\x02\x37\xef\xe1\xbd\xc4\x6d\xf7\xdc\x36\x65\xec\x2b\xee\xde\x10\x21\x63\xe2\xcd\x95\xbc\xb4\x34\x22\xe9\x3d\x8b\x41\x8f\xa3\xb0\xb7\x18\x86\x0d\x5b\xf3\xb9\x1f\xbf\x1e\x1a\xf4\xbb\x18\x7c\x7e\x0a\xfc\xa4\x3c\x68\x8d\xdf\xe9\x9f\xcb\x65\x0f\x7e\x31\x9a\x0a\xe2\xd4\x5f\x72\x55\xfd\x90\x91\xb3\x9a\xb5\x22\x8a\x8e\x3c\x77\x38\xfe\x17\x53\x92\x0c\xb2\x7a\x86\x51\x6a\x7b\x24\x0b\xa1\x69\x20\x90\x2f\xdf\x8b\xed\xf4\xc0\xe7\x85\x54\xa5\xbd\x85\x96\xae\xf2\x83\x17\x54\xd2\x2c\xb7\xf8\xa3\xff\x9c\xef\x48\xa3\x63\x2d\x9f\x10\x0e\xf2\x8c\x34\x80\xa2\x02\xdc\x52\x44\x6d\x73\x5a\x40\x78\x1c\xc1\x03\xbf\x12\xaa\x21\x48\xd8\x52\x01\xcb\x54\xaa\xbe\x6d\xdf\xf8\xf3\xed\x1f\x11\x62\xf6\x6a\x60\xd7\x6e\xe6\xf0\x98\xf0\x2c\x5c\xc9\x4a\x61\x62\x52\x0f\x9f\x37\xcf\x72\x7d\x93\x7e\x16\x74\x0d\x4b\xe2\xe9\xe2\x0f\x7c\xa8\xad\x00\x8c\xe7\x6c\x0a\x0e\xbc\x63\xe8\x9a\x0e\xf5\x84\x29\xbf\x0d\x59\x35\x7e\x78\x4d\x8c\x78\xd7\x43\xd7\x9e\xa9\x11\x17\x4f\x5f\x62\x80\xa6\xc9\x73\x2d\x31\x99\x3c\xa2\xc3\xd9\x02\x24\xfe\x3f\xd4\xc7\xd8\x11\xdb\xee\x3d\x11\x15\x5c\xb9\x8b\xde\x27\xe1\x6e\x78\x52\xa4\x0c\x0d\xb0\x0c\x37\x8e\xa9\xb9\xb1\x82\x8d\x73\xe1\x77\xfa\x0c\xab\xb9\xe0\x56\xda\x9f\x89\x6c\xcd\x4a\xc7\xa3\x0d\x8d\xa6\x8a\x77\x66\xe9\xa9\xe5\xd2\x1f\x57\x55\x7c\xf1\x36\xbf\x20\x42\x7d\x68\xa3\x03\x9d\xcf\x37\x3b\x79\xd6\x3f\x37\xa4\x71\x30\xa4\x7f\x42\xbd\x92\xb7\xf0\x2f\x6e\xc7\x00\xde\x0e\x0d\x38\x11\x1c\x14\xc5\xcb\x92\x00\xcb\x27\xe5\x40\x25\xed\xe5\x20\x62\xc4\x26\x25\x6c\xc4\xd2\x21\x90\x0b\x55\x7c\xc4\x3f\x1d\x4e\x03\x78\xa1\xe7\xea\xfd\x15\x45\x8c\xf0\xf6\x91\xec\x2a\xdd\xac\xac\x69\x23\x2b\xcf\x0f\x84\x14\xac\xc8\x7a\x5e\xd3\x29\x72\xf1\x49\xe8\x49\xd1\x0a\x2a\xe2\x5f\x9e\x2d\x35\x51\xeb\x9f\xe5\xd4\x5a\x1a\x1d\x64\xfb\x63\x18\x36\xe6\x3b\xbd\x68\x30\xa7\x80\xeb\x27\xcd\xc4\x46\x86\xc5\x20\x62\x44\x36\x28\x73\xf6\xe3\xb2\xa4\xea\x74\x7a\xd1\x99\x4d\xae\x97\x3f\x51\x19\x93\x02\x7b\x61\x13\x00\x41\xf9\xe5\x87\xf0\x44\x42\x4b\xa9\x31\x06\xb3\xbe\x37\xe6\x09\x80\xc9\xb7\xd5\x3c\xc7\xca\x85\x1b\x07\x26\xf7\x30\x28\x5e\x17\x57\xd4\xf6\xc5\x6f\xb6\xf3\xa1\x1f\xca\x13\x60\xfe\xdc\x2b\x09\x3f\xfc\x7e\x81\xcb\xb9\xb9\x40\x24\x5e\x81\x72\x16\xee\x6f\xeb\x74\x2d\x3d\x06\x47\x97\x35\x94\xc0\x7a\xf1\xb7\x69\xf1\x7a\x0f\x9e\x3c\x89\x3c\xd7\xae\x25\x70\xc5\xcb\xf9\xc2\x70\x6f\x07\xc2\xac\x9c\x44\xe3\xe1\x0f\x9a\xe5\x12\x1d\x62\xaa\x53\x75\x0e\x08\xb4\xa7\xdf\x21\x48\xae\x05\x10\xbc\x09\x04\x33\xe9\x61\xf2\x93\x32\x20\x69\x50\x58\xa4\x1d\x9b\xf0\x49\xb1\x66\x55\x56\x32\x25\x05\x17\xce\xe3\x3a\xda\x84\xe2\x06\xe4\x4a\x9d\x0e\xa2\x5a\x12\x81\xc8\xcd\xdf\xe0\xad\x8f\x37\x45\x22\xc3\x35\x2f\xb9\x30\x9b\x18\x38\x3d\x19\x9a\xbb\x26\x63\x37\xa9\xd1\x5b\x04\x97\xb8\xe1\xf4\xe2\x75\xff\x92\x17\xca\xd7\x50\x02\x9a\x4d\x5a\x7e\x19\xca\xf4\x9e\xeb\xf5\x75\x0d\xf7\xcb\xa7\x97\x3c\xc5\x6b\x32\x69\xc7\xd8\xa7\xca\xde\x2f\x39\x40\xd8\xd4\x5a\xc3\xdd\x39\x7a\xd5\x19\x23\xff\xa6\xcc\x69\xad\xe7\x20\xa1\x21\x42\xe1\x78\xf6\x92\x8c\x55\x02\xde\x1d\x80\x9c\x0f\x20\x2e\x27\xae\xb3\xa0\x14\x05\x61\x33\x95\x9c\xad\xe7\xd7\x63\x6a\xc2\xcf\x7c\x3d\xb4\x47\xbe\x83\x90\xfe\x0b\x0c\x02\x4d\x74\x78\x0a\xb3\x2e\x6f\x36\xdc\x4e\x2f\xca\x20\x94\xba\x81\x89\x82\x70\xd6\xd5\x69\xa6\xdc\x58\x4b\x01\x1c\xd4\xfd\x33\xf9\x3b\xfb\xf5\xc1\x34\x3e\x54\xff\x47\x8f\x93\x6f\x36\x51\xb9\x58\x07\x98\x3d\x15\xe8\x33\x2e\x68\x10\x82\xfe\x73\xc0\xa0\x5a\x65\xa5\x54\xb1\x41\xdf\x28\x24\x22\xa8\xa4\xeb\xce\xf9\xf2\xe5\x89\xf3\x63\x6f\xef\xd3\x67\x56\x56\xb9\xd3\x6a\xbe\x84\xd7\x35\xdc\x0d\x4c\x94\x9d\x39\xb6\x3f\x5d\xe7\xd7\x5f\xa0\x2d\xfd\xb6\x93\xd5\xbc\x8f\x7a\x5f\x3f\x49\xe9\x08\x3e\x63\x41\x3a\xa4\xad\x52\x3b\x24\x95\x71\xa6\x51\x3a\xa3\x15\x70\x12\x17\xdc\x62\xda\x24\xdd\x0a\xbf\x77\x78\x21\xe5\xd1\x45\x7a\x13\x2e\x48\xef\xab\xeb\x6b\xd0\xda\xda\x46\x9f\xd2\xd9\xbc\x7f\x19\x6e\x25\x9a\xab\xda\xbb\x78\x7a\x9d\x3f\x90\x06\x4f\xbb\x44\x0b\xf0\x0e\xf0\x7a\x80\x53\xbd\x21\x28\x58\xbc\x5c\xff\x03\x26\x5f\xbe\x8f\x16\x7e\x92\x96\xbd\x73\x74\x3c\x51\x12\x7c\x06\x12\x1a\xaa\x82\xf4\x59\xe4\x13\xfb\xb0\xe2\xd6\x56\x06\xbe\x2f\xbc\x59\x17\x9a\x5a\xe9\xf3\xa5\xe9\xa9\x91\x86\x53\x58\xfe\xe2\x8d\x33\x7f\xe2\x35\xb8\x35\xaa\x8c\x7f\xf9\xc2\xd6\xfe\xd7\x6c\xc4\x3d\x97\x43\x4e\x7f\xb6\x20\x67\x2e\x9c\xf2\xb5\x08\x80\x8a\x55\x20\x87\x0d\x63\x2c\xbd\x20\x6c\x7e\x13\x13\xb1\x5b\x2b\x8a\xb5\x39\xdd\xe8\x69\x5d\xa4\xc7\xfa\x77\xf5\x5e\x8f\xe9\xb6\xcf\xf2\xa2\x59\x1e\xc6\x0c\x37\x10\x46\x69\x68\x1a\xe6\xf7\xdc\x87\x6a\x3c\xa8\x70\xca\xd7\xd6\x00\x77\x71\xd9\x7b\x8d\xc0\x32\xd9\x9b\x94\x14\x83\xeb\xbf\xf9\xa2\x2b\x0a\x61\x07\x0b\x42\x42\x5a\x4e\x4f\x48\xa4\x18\x7f\x45\x7d\x4c\xf9\xaa\x36\x58\xf4\x93\x13\xa8\x55\xf5\x1a\xd9\xf0\x5c\x86\x8e\xe6\xec\x43\xba\x25\xeb\xcc\xfb\x7a\x7c\xe9\x47\x62\x41\xca\x08\x99\xde\x6f\xdc\xa5\x6e\xcd\x0c\xa8\xc9\x9b\xc3\xf9\xf7\xe6\x44\x95\x5d\x5d\x79\x24\xb4\xc6\x47\x46\xae\x88\x26\x8e\xe0\x38\x3d\x09\x95\xc7\x15\x52\x64\x28\xb3\xf4\xda\xe2\xec\x32\xae\x36\x73\x48\x79\x4e\x1b\x64\xa0\xba\x73\x88\xbd\x99\x03\x35\x39\xeb\x3a\xdf\x42\xc1\x15\xfa\x1b\x8c\x7d\x85\xe8\xb8\x3a\x2a\x7a\x9d\x55\x5d\xb6\x05\xbb\x5f\x68\x64\x97\x85\x29\x54\x13\xbe\xda\xfd\xfa\xe6\x5e\xeb\xf7\x50\xe9\xba\x40\x34\x05\xae\xab\x8d\x49\x26\x74\x7c\x23\xef\x04\xe9\x1c\xee\xfb\x53\x3e\x69\xb9\xf8\xcf\x8a\x18\x47\x08\x5c\xb8\x42\xc0\xac\xd1\x39\x16\x59\x61\xde\xab\x60\x6e\x12\x12\xb7\x08\xf9\xbd\x1b\x71\x30\x9f\x34\x3e\xd1\x09\x21\x57\x20\x90\x8b\xf6\x8b\x4a\x5e\xb8\xdd\x4e\x4e\x23\x65\xb4\x53\x2d\x23\xd8\x68\x70\x30\xc6\x09\x23\x6f\x11\x6b\x93\x17\x8f\x71\xaf\xdb\x18\x98\x4f\xb4\x75\x94\xd3\xbd\x5a\x31\xe9\x88\x06\x4a\x8e\xd9\xdc\xc3\xea\xf6\xd1\xbf\xd3\x39\xcc\xa3\x1d\xd2\xe3\xe3\x69\xa2\x71\x37\xd7\xf1\x55\xc7\x6b\x1f\xdf\xdb\xb7\x4e\xd7\xdc\xce\x9e\x4f\x40\xb2\xc8\x81\x83\x1b\xc4\x25\x7b\xa1\x92\x79\xe5\x9f\x06\xa4\x12\xbf\xb8\x3f\xc6\x29\x5b\xb4\xb5\xfe\xf4\x8b\xcd\x35\xe0\x2f\x06\x95\xb9\x33\xaf\xec\xec\x56\x45\x24\xf6\xe1\x72\x9f\xaf\x8c\xaa\xc8\xde\x8b\x3b\xba\x5a\x77\x39\x5a\xea\x5e\x91\x8f\xac\xf3\x7c\xa0\x74\xc7\x1f\x7a\xf2\x34\x58\xb0\xc6\xce\x00\x0e\xc2\x6a\x76\x65\xda\x4b\xc5\xdd\x23\xcf\xb2\x9f\xf3\xa9\xdd\x00\x09\xf5\x10\xe6\x48\x07\xa5\xa6\xbc\x89\x70\xa5\xf7\x33\xdf\x8d\xb1\x6e\x52\xc9\x0b\x51\x56\x2a\x72\x27\x3f\x18\x5b\x99\x32\xfe\xd5\x35\x25\x6a\x2b\x1d\xa3\xb1\x60\x64\x74\x54\xa4\xe9\x96\x61\x14\x8e\x71\x48\xc1\x15\x65\xac\x4f\xc7\x31\xcb\x75\xd1\xcf\x31\x32\x4b\x52\xa1\x78\x44\x28\x43\x98\x1d\x94\x60\x92\x96\xcc\x40\x84\xb0\x79\x7c\x01\x8e\xb7\x80\xe4\xe5\x8a\x02\xcc\xa1\x54\xf9\xfb\xd0\x5e\xdc\x69\x74\x4e\xac\xd2\x5d\x0a\x8d\x59\x11\x9a\x3a\x3f\xfa\x9c\xe8\xe1\x2b\xc2\x43\xb6\x06\x7a\x10\x56\xb8\xc6\xe5\x60\x62\x32\x55\x7d\x18\x88\x4c\xd6\x03\xa8\x74\x0f\x02\x87\x59\x85\x5c\x5e\x10\xe3\xbe\x2e\xfe\xfb\x5a\xf3\x9d\x76\xc2\xb9\x0b\x9a\x9c\x99\x12\x61\x84\x25\xaa\xce\xb5\xd8\x9d\xa0\x38\x1e\xb1\x5f\x5f\x59\xde\x5c\x19\x10\x12\xd1\x40\x52\x88\xfe\xdb\x74\x6b\xfb\x7b\xd3\x47\xb1\xf3\xcf\x40\x8c\xa4\x35\xfe\x06\x5b\xd7\x4e\xc6\x40\x8a\xe2\x8f\x71\xce\xeb\xe7\x55\x35\xf5\xa6\xdb\xcf\x72\x9e\x0d\x40\x47\x36\x4d\xbb\x2b\xb6\xe4\x4d\x4c\x50\x3b\x27\xc8\x01\x51\x2f\x73\xa5\x6c\x2e\xbc\x3c\x1d\x0a\x2a\x7a\x3b\x9d\x62\x37\xf7\x28\x58\x5e\xc9\xba\x33\x7b\x99\x1a\xd4\xf3\x2f\x5c\x88\xf1\xea\x6f\xe7\x05\x57\xfb\xa8\xff\x62\x8d\x33\x3d\x66\x64\x02\x61\x09\xaf\xd9\x46\xb3\x99\x1f\xe9\xf1\x80\x4f\xab\xc3\xfb\x47\x8c\xa4\x3e\xd3\xdd\xd7\x66\xa6\x2a\xe7\xb6\x86\x45\x79\x0f\x79\x4a\x7d\xd0\x29\x06\x95\x55\x2e\xba\x19\x84\xf5\xd8\x0c\xdf\xc6\xbf\x2d\x52\xf8\x16\xf5\xa3\x58\x8f\x99\x4a\x97\x6d\xf1\x45\x09\x81\x40\x68\xb2\x99\xb0\xdf\x1b\xec\x4f\x9f\x98\x33\x97\xa0\x9e\x09\x4c\x4d\xe9\xb7\xff\xbd\x48\x86\x52\x13\x72\x2e\x94\x8f\x82\x97\xe0\x5f\x3d\xe8\xa4\x95\xc6\x0f\xa2\xd0\xe0\x0b\x4f\xb1\x36\xb7\xc2\x05\xdf\xab\x97\x44\xb8\xd2\x7f\x6e\x9f\x1a\xe8\x39\x7e\x2c\xaa\x07\x0d\x78\x50\xac\x39\x2f\xb4\xb1\x2c\x04\xad\x6e\xab\x39\x5c\x6f\xcc\x71\x1d\x7d\xb3\x1b\x79\x50\x92\x9a\x2e\x47\x11\x58\xd8\x5e\xa1\x0d\x04\x0e\x3e\xad\x1f\xde\x77\x79\x2c\x83\xe5\xee\xdd\xc8\x9a\x4b\xf0\xdb\xed\x05\x09\xf5\x74\x00\x8e\xfc\xf7\x0f\xb6\x5c\xb6\xf9\xd1\xb1\x1a\x59\x85\xae\x7d\x63\x15\x39\x8a\x83\xfc\x33\x14\xa0\xc3\xa0\x89\xe5\x80\x97\x67\x69\x6a\xe0\xc0\xbf\xed\xf0\x80\x8b\x74\xff\x3b\xbe\x37\x08\x59\x0a\x36\x72\xf7\xc9\xbb\x05\x2d\x53\xc4\x08\xdf\xa0\xe6\xdc\x33\x41\xc0\x08\xdf\x40\x8e\x7f\x66\x6d\x2f\x50\xe8\x9b\x68\xb4\x4c\xdd\x58\xef\x8a\x14\x9a\xec\x8b\x01\x51\xb3\x4c\xcb\xa4\x6b\x8c\x39\xe1\xd2\xe1\xdb\xd2\x7d\xcf\xee\x18\x2d\x3a\x41\x41\x46\x9d\xa4\xaf\xff\x1e\xbb\xce\x7d\x2d\x2b\x4a\x94\xe9\x7c\x3e\xff\x75\xe6\x1e\x42\xe1\x57\xa9\x36\x35\xae\xdc\x60\xf6\x32\x94\x1d\x22\xb2\x8a\x61\x58\xb1\x26\xc2\xf9\x1a\x57\xb2\x85\xc3\x7b\xd1\x98\xf4\xde\xdc\xc9\xca\x6d\x7f\x8a\xa8\xb5\xf9\x54\x0f\x02\x9e\x8e\xf6\x70\x54\xec\x36\x81\x0a\xb7\x34\x4c\x05\xdf\x6f\x60\xb0\xc2\x2c\x9e\x99\xfb\x4d\x8b\x02\x07\x83\x92\x51\xf3\xf9\x76\x78\x07\x18\xee\xf5\xb5\xac\x58\x1b\xba\x3e\xee\xcf\x95\xb7\x10\x4e\x95\xdd\x29\xdc\x72\x6b\x6c\xc3\xaa\xa0\x70\xc2\x4a\x38\xf6\x56\xd4\x9d\x82\x50\xf9\x41\xd8\xac\x60\x70\xe0\xea\xea\x70\xce\x6b\x77\xff\xaf\x66\x83\x9d\xc8\x97\x17\xf1\x9f\x5e\x3a\xe6\xd7\xe5\x25\x30\x08\xf0\xa0\x4d\x73\x6b\xe8\x2e\xd1\xd4\x4c\x70\x2a\xbe\x2e\xc6\xb9\xf5\x44\x71\x3c\xf4\x38\x1d\x70\x39\xc7\xa0\xea\xdb\xe1\x4e\x82\x8d\xc9\x55\x99\x7d\xbf\x35\xe5\xac\x4b\xc4\x52\xf5\xf5\x44\x19\xd6\x21\x76\x4c\x39\x9e\xa4\x20\x4e\x65\x2d\x9c\x6e\x95\xed\x36\x13\x46\xd1\xc0\x44\x69\x9c\x49\x4b\xa9\xb8\x8b\xc2\x41\x51\x9a\x21\x69\x72\xef\x93\x1b\x34\x90\xb2\xc4\x46\x93\xc1\xac\x0e\x01\xc4\x1d\xb8\x9e\x56\xdd\x52\x89\xe2\xb6\x9a\x29\x25\xb3\x39\x95\x8c\x4f\xb0\xc4\x5b\x81\xc3\xf1\xb6\x4c\x77\x08\xf6\x59\x91\xf9\xe0\xc3\xad\xd1\x3d\xad\x58\x0d\xcb\xc4\xbd\xb7\x0f\xf5\xf8\x1f\x1b\xb8\x4f\xee\x7c\x12\x73\x98\xa5\x4b\x91\x82\x0c\xb4\xa0\x2d\xbf\xbb\xc2\x6d\xdf\x63\x56\x5f\x12\x7b\x8a\xcb\x88\x18\x8c\x7f\xb6\xe2\x38\x0d\x87\x2f\x3c\x32\x59\x12\x16\x8b\x69\x34\x21\xfb\xc9\x4d\x83\x7b\x60\xaf\x17\x9c\x3a\x7c\x5c\x26\x1c\xcf\x35\xc4\x06\x2c\x0f\xc6\x1f\x63\xce\x9a\x12\x5c\xb6\xc1\xe8\x58\xf3\x6e\x2b\x96\xd4\x95\xc1\x57\x3b\xd8\x63\x3b\xf5\x15\x8f\xbb\x9f\x92\x9f\x95\xcb\x1d\x06\x11\xb3\xd5\x84\x62\xaf\x43\x54\x0e\x54\xbe\x89\xba\xf9\x64\xef\x86\x7a\x5e\xd3\x89\x23\x1f\x8e\x49\x0f\x2d\x8e\x03\x84\xbd\xc3\xe1\x68\x06\x1b\xa6\xbe\x7f\xe4\x27\xb9\xc6\xa3\xce\x3c\x77\x89\x81\x83\x4d\x87\x29\x50\xad\xc3\x7c\x18\xdd\x11\xf9\x5c\x49\x5e\xc2\x46\xe9\x65\xb8\xc3\x31\x68\xb3\x97\xf7\x0f\x08\xa7\xfa\x2a\xba\xb8\x23\x4a\x77\xfb\xf0\xa9\x32\xc7\x68\x07\xd5\x41\xeb\xe6\xd9\x9b\x65\x51\x8b\xdf\x02\x1b\xed\xf7\xe6\xe5\xb4\x1e\x05\x30\x51\x2d\x39\x90\x47\x73\xaf\x38\xc4\x88\x6f\xcb\x72\xfd\x19\x95\xa0\x42\xf9\xda\x18\x73\xa8\x66\xc4\x07\xdb\x89\x5b\xdf\xcb\x0f\xb5\x20\x46\x0c\xb3\x8f\xfe\x4c\xb6\x11\xc2\xcc\xd1\xd8\x5c\x4e\xd5\x0b\x1c\x29\x73\xe1\xba\xae\xc5\x3c\x5d\x0d\x47\x93\xe0\xc6\x6d\x20\x84\xb8\x42\x99\x7f\x2f\x2a\xe6\xc9\xa4\xef\x60\x3e\xd5\x62\x2c\xe7\xf2\x41\x8d\x99\xe3\xf3\xdb\x38\x2f\xba\x62\xad\x1b\x7e\xdd\xb4\xc4\x8d\x79\x3e\x93\x5b\x3d\x4f\x8b\x38\xe6\xd4\x85\xe0\x29\x65\xa5\xe1\x74\xec\x43\x7c\x4a\x84\x71\x45\x58\x71\xc4\xaa\xef\xf1\x74\x95\xbb\x27\x31\x42\xeb\xab\x63\x82\xaf\x04\x58\x1f\x7b\x3e\x13\x09\x3c\xd8\x06\x4f\xc1\x97\x50\x68\x0c\x57\x54\xc6\x11\x14\xf7\x86\xd9\xd2\x6c\xa8\x3b\x77\x58\x21\x65\x8b\xb7\x21\x8f\xc5\x6b\x1f\x4e\x56\xdf\xb2\xd1\xe2\x35\x5d\xdb\x78\x86\xac\x69\xe3\xe5\x10\xfa\x2b\x95\x51\xd7\x46\xc1\xd0\x44\x3c\xa3\xdd\x76\xac\x69\x91\x66\xed\xc4\x42\x55\xde\x8b\x36\x26\x17\x3e\xde\xfb\x4d\x01\xe0\x28\xbb\x65\x02\x0e\x26\x57\xbd\xb3\xe2\x3b\xe4\x1b\x48\xa9\x5a\xf9\x39\x1d\x6f\x85\x6e\x07\x50\xf6\xed\x51\xed\xc3\xd1\xf5\x1a\x33\x6f\x16\xdc\xfa\x34\xc7\x67\xf9\x5e\x3d\xe0\x0c\x41\xb1\x27\x0a\x5b\x3b\x0e\x05\x51\xde\x36\xba\x46\xae\x25\xfd\xd1\x95\x58\xa0\x0d\x6b\xca\x21\x14\xa4\xd3\xb2\x18\x91\x08\xdb\x85\x17\x12\x23\xeb\x47\x59\x49\x29\xbd\xb8\xd8\x17\x17\x63\x31\x85\xef\x40\x6a\xd2\x76\x19\xe1\xa4\xf7\xd7\x89\xed\x42\xf0\xd0\x63\x0e\x00\xa5\xb8\xac\x55\xc5\x59\x1b\x31\x22\x57\xe9\xf0\x2d\xd9\x8b\x31\xd5\x16\xa1\xee\x32\xd1\x91\xa8\xe9\x6b\xbd\x4a\x84\xd5\x09\x43\x4e\xa0\x6e\xcb\xf4\xd2\x5f\xa2\xf7\x4b\x7f\x89\x8e\x67\x4e\x3a\x8c\x3a\x9d\x13\x04\x43\x52\x55\x06\x65\xd0\x5f\xc2\x8d\x85\xeb\x12\xcb\x82\x22\xa6\x13\x30\x85\x82\xb5\x1b\x48\xca\x25\x1f\x7b\xf1\x6a\xa3\x91\xd1\x3c\x0e\x94\xd2\x02\x17\xcc\xf6\x26\xdd\x2e\xee\x27\xc6\xd7\x68\xf0\xb9\x97\x46\xad\xde\x9d\xcb\x85\xe0\xbf\x2f\xd8\x15\x96\x50\xa6\xc3\x04\x9b\xf2\xfc\xbe\x5f\xa2\x17\x59\xd3\xc9\x62\x42\x87\xe1\xa4\x98\x78\x1a\x9b\x7e\xe9\x8d\x94\xda\x5f\x32\x75\x6f\x81\x58\x46\xd4\xa4\x72\x19\x13\xa6\x51\x56\xda\x9a\xfa\xe0\xa3\x48\xc8\xb1\xe2\x29\xce\xf5\x5f\x10\x67\xe4\x3d\xba\x1f\x5c\x30\xa1\xd9\x70\x86\x15\x5b\x87\xca\xdf\x73\x36\x19\xe6\xb3\xb0\x40\x0a\xd4\x4b\x3a\x4d\x51\x66\x3f\xa9\xca\x76\xfe\x63\x9f\x2f\x83\x95\x4d\x14\x60\xf0\x15\x1c\x84\x74\x7b\x2a\x43\xa1\x5f\x24\x6f\x1d\x9b\x5b\xc8\x85\x0a\x42\xc3\x79\x29\x8e\xaf\x00\xda\x85\x42\x08\xb7\x45\xb6\x1f\x66\x5e\x08\xb5\xb7\xd9\x2e\x05\x21\xf2\x78\x89\xf5\xdf\x8e\xf2\x9d\x81\x14\x28\x5b\x5d\xe4\xa2\xdf\xb8\x65\x51\xab\xaf\x3c\xad\xde\x23\x91\xaf\x9f\x4e\xd6\x17\xae\x9e\xdb\xec\x27\x99\xa6\x28\x54\xfe\x3a\x65\x1d\x08\x24\xc7\xd8\xc9\xda\xee\x59\x0d\xb3\x0e\xaa\x68\x71\xe1\x7e\x77\x09\x0e\xb9\x6c\x00\x69\x71\x0f\x9e\x4f\x0d\x45\xe9\xf1\x0c\xd0\x8e\xf4\xe9\xcf\xd4\xfa\xa1\xc1\x17\x59\xe8\x92\x8f\xa3\x9b\xc9\x2b\x92\x68\x32\xd3\xab\x06\x8e\x49\x74\xc8\xf2\xd5\xe1\xa3\x24\x7e\x1d\x03\x7b\xe3\x30\x9f\xde\xda\xf3\x4b\xb6\xed\xec\xcb\xcc\xf6\x91\xdc\xa6\x95\xa5\x81\x4b\x18\x15\x6f\x97\xfd\xa6\xec\xbd\xa7\x76\x2a\x2f\x9c\x20\x58\x2b\x14\xf8\x62\x1e\x5d\xf2\x61\x50\x09\x6f\x90\xa6\xb4\x2b\x14\xcb\x40\x2f\xce\x3f\x0f\xd1\xcc\x67\xfa\xdf\xee\x94\x23\x5f\x58\xaf\x24\x0b\x3f\x30\x85\x33\xb8\xca\x73\xb8\x65\xc5\x11\x4e\xea\xd7\x15\x44\xbf\x2b\xb7\xfa\x51\x6c\xe8\xf4\x0a\x5d\x5f\x7d\x30\xa9\x5e\xa3\xdb\x8e\x1d\xdb\x3d\x93\x4f\x24\x5a\x4f\x49\x9d\xea\x49\x89\x6b\x7d\x70\x57\x09\x2a\xec\x86\x1f\x27\x2f\xa3\x66\xaa\xd2\xe2\x2a\x65\x23\x02\x6a\x79\xab\x0d\xbb\x9f\x0b\xe7\x0d\x25\x67\x5b\xfc\x06\xb8\x64\x07\xbc\x73\xf0\x2b\x70\xde\x0b\xa6\x41\x59\x9a\xcb\x27\x44\xfc\x78\xfc\xfe\x9b\xd8\x66\xec\x97\xad\xf1\xc2\xda\xf2\x07\x55\x6d\x97\x22\x0b\xa1\x26\x2d\x19\x5f\x17\x26\xa2\x06\xfc\xd8\x93\x78\x7b\x0f\x8c\xf2\xab\x0a\xdc\x85\xeb\x26\x88\xb4\x44\xcb\xbb\x5e\xd1\xca\x70\x7e\x39\x94\x03\x6a\x79\x4b\x0d\x7b\x7c\xf3\x92\xb3\xdd\x13\x68\xe7\xd8\x06\x4e\xf9\x01\xa2\x77\x7c\xf1\xdf\xce\xac\x88\xa7\x96\xb7\x4f\xc7\x04\x2c\x83\x24\xe5\x43\x66\x03\xd8\x7f\xa8\x87\x26\x2c\x05\x73\xbd\x7a\xfb\xde\x0a\x7b\x60\xc0\x31\xd8\x4a\x77\xf5\xd4\x7e\x8a\x27\x2e\x35\x81\x57\xfb\x8a\xff\x28\x7d\x74\x40\x39\x4d\xf2\xab\xa4\xb3\x6f\x0a\x21\x9e\x35\x8a\x53\xd2\x85\xa8\xfe\x4e\xc7\x3b\xba\x0f\xa4\x28\x33\xe2\xfa\xf2\x61\x47\xe2\x23\x26\x7b\x71\x71\x86\xa7\xde\x63\x94\xe5\xdc\xa2\x44\x11\xd7\x11\xf4\xc3\x07\x5b\x2e\x5b\x4f\xd0\xb1\x33\x07\xb6\x53\xc1\xf3\x12\x5e\xd7\x09\xe7\xbb\xdc\x17\xde\x30\x85\xab\x57\x2c\x39\x97\x3f\x07\x53\x2e\xd9\x4e\xd5\x57\x47\x56\xde\xc8\x99\x8c\xa8\xa6\xe9\x8c\x96\xb7\x61\x92\x59\xd1\x02\x15\x42\x9b\xcf\x62\xe2\x7f\x3c\x74\xbc\x73\x92\x8e\x29\x7c\x18\x3f\xf5\x60\x22\xd8\xb8\x2a\x90\xaa\x60\xa1\x4d\xf8\xe9\x72\xd3\x6a\x78\x1b\x69\x79\x44\x66\x68\xc2\x41\xc5\x73\x4d\x92\x89\x04\x3e\xd1\xbe\xe6\xdb\x64\xc8\xa8\xff\x62\x55\xaf\x4a\x92\x06\x15\x6e\xda\xc2\x93\xc3\x8f\x3e\xf6\xc7\x4f\x5a\x6c\x1f\x8d\xc3\xb8\xd3\x9f\x29\x98\xcd\x7a\xfb\x9b\x73\x14\xc0\x80\x67\xa7\x9e\x1f\x2d\xf0\xfe\x47\x51\x26\x1c\x7d\x4e\xce\xeb\x5a\x3f\x75\x53\x6f\x69\x13\x19\xc0\x8f\xc9\x98\xd2\x1d\x76\xde\x7c\x82\x8e\x55\x41\x11\x74\x0b\x7c\x07\x1d\xde\x53\x76\x2a\x88\xa6\x2f\x7e\xd4\x3b\xf0\xd9\x92\xad\x9d\xa7\xd3\x1a\x39\x26\xb6\xdd\xa3\xac\x7d\x99\x3f\xe8\x9e\x91\x04\x54\x1f\x1f\x6e\x27\x45\xb5\x18\x35\x94\x1e\x5b\xc6\xd4\x44\xd7\xfb\x15\x51\xa0\x94\x42\x69\x05\x1b\xb5\x7c\x8d\x8e\x79\x71\x94\x4f\xaf\x48\xe6\xcd\x87\xd3\xb6\x1e\x39\xaf\xad\xcb\x88\x76\x32\x4c\xd5\x54\x99\x2c\x55\x7f\x18\xd1\xdc\xb9\x35\x13\xa3\x95\x8b\xa7\x67\x67\xe8\x3f\xba\xc3\xeb\xfa\x36\x3f\x85\x75\xad\x51\xe9\xbc\xf0\x33\x35\x8e\x3e\xc6\x3e\x2c\x5d\x8f\xc6\xe1\xb9\x93\xaf\x0a\x1b\x4e\xf9\x9a\x1e\x60\xed\xb4\x3f\x51\xee\x67\x45\x3c\x95\x3b\xcc\x98\xaf\x35\xd8\x4c\xdb\xcf\xff\x96\x2d\x32\xf5\x36\xa8\xad\xfc\x2d\xd7\xcd\x5f\xef\x47\x0a\x7a\xae\xb6\xcf\xcc\x43\xbf\x7f\xc2\xc8\x13\xee\x0a\xa6\x87\x50\xe6\xed\x49\x15\xa6\xeb\x54\x30\xad\xac\xb4\xd5\x44\x05\xab\xdd\xdd\x4a\xc3\x38\x38\x4b\xbd\x95\xb0\x8a\xa3\xf5\xc1\xf3\xf3\xcb\x83\x51\xb9\xbe\xa0\xa9\xa0\xed\x6c\xb7\x49\x09\xc6\xc8\x93\x0f\xd6\xfb\x47\x8c\x1e\x9f\x0d\x4f\x1b\xef\x70\xc8\x8b\xf9\xb2\x27\xca\x17\x45\xbb\x6e\x56\xb5\x9d\x71\x2e\x84\xaa\xb7\x08\x27\xec\xd5\x45\xf5\x5a\x86\xb1\xea\x3b\x6e\x2f\x47\x51\xfc\x22\x3b\x35\xc7\xf3\x20\x0d\xef\x89\x10\x23\x08\x06\x33\x96\x5e\x32\x79\xda\x2d\x2a\x85\xca\x49\xa4\x28\x4a\x08\xf6\x17\x68\xeb\x2e\x57\x07\x97\x65\x6b\xaf\xbf\x91\xd3\xb3\x1e\x36\xe5\xe3\x22\x9c\xfb\x85\xd7\xa2\xe1\xce\x88\xc0\x5a\x00\x89\xb8\x5f\x6d\x97\x97\xbd\x6b\x3d\x77\x07\x19\xec\x16\xe9\x92\x86\x29\x44\x8a\xcf\xed\x28\x44\xdf\x6b\xd5\xd7\x3a\x24\x46\x44\x13\x09\xd5\xfe\xe1\x7b\xf1\xd3\xa7\xf9\x4e\xa3\xe8\xf7\xac\x70\xca\xfd\xb9\xfe\x8d\xe0\xd9\xdf\x77\xab\x4f\x20\xe2\xc5\x8d\x0d\xe5\xb3\x57\x5c\x69\xc8\x6f\x1e\x9a\x3f\xb6\x3e\xdb\x04\x30\xd2\xf8\xa5\x62\xc3\x0b\x9b\x75\x62\xe2\x09\xa9\x23\xce\x4e\x7a\xf8\xf1\xbc\x4c\x61\x37\x29\x9e\x81\x16\xa7\xed\x0f\x98\x75\x4f\xf4\x9f\xfe\x26\xa2\x6d\x9d\x02\x39\x9f\xb6\xd3\x8d\xfb\x1a\x5a\xa9\x0a\x8f\x1c\xf7\xce\x21\x47\xa7\xa2\xe3\x97\xb2\x1e\xde\x84\x77\xeb\xe3\x0c\xd3\x66\x6a\x99\x29\x52\xb2\x68\xf8\x10\x1d\x2e\x2d\x66\x2f\x59\x56\xbf\x28\x56\x3e\x93\x35\x17\xa2\x00\x64\x38\x5f\xe0\xc9\xfd\xd9\xb4\x5c\x1f\x7d\xa0\x03\x0a\xdc\x5a\x3c\x70\x8e\x1d\x8a\xe6\x9c\x05\x7a\x7f\x72\xc3\x09\x16\x16\x7d\xaf\xff\xa9\x87\x3f\x98\xaf\x37\x5c\xeb\x49\x4f\x6f\xea\x1a\x37\x66\xce\x51\xea\x59\x9b\xeb\x16\xeb\x20\xb3\xf8\xe7\x86\x9e\x6f\x22\x45\xb5\xd4\xb8\xba\xd9\x69\x85\xa7\xf7\xcf\xf1\x61\x14\x2a\x12\xc4\x02\x3d\xac\x88\xa6\x94\x9c\xac\xf3\x83\x85\xb6\x2d\xfa\xbd\xbf\x3f\x06\x4b\x2f\x66\x9c\x33\x5f\x9e\x46\x27\x29\x9b\x9a\x9a\x26\xa0\x22\xd7\xd5\x97\xfa\x42\xe2\x1c\xc1\x77\xe8\xa6\xdb\x20\xc7\x82\x8b\x24\xfc\x2f\xd3\x30\xe9\x88\x48\xca\xcb\xd6\x42\x3c\xad\x57\x74\x53\x80\xf0\x97\xe5\xce\x98\xc0\xbc\xff\x24\x0b\xd1\xd7\xce\xf4\xa4\x23\xc9\xbe\x13\xf6\xed\x0c\x2b\x1c\xd6\x93\x54\x51\x65\xbe\x22\x97\xb8\xc1\xea\xe7\x5a\x90\x1b\xcc\x46\xf8\x07\x3b\x99\xeb\xe4\x96\x07\x23\x57\xa9\x79\xd0\x4e\xf4\xdf\x13\x1d\xa5\x00\x5a\xda\x55\x87\x2e\xea\xe5\xb1\x97\xbf\x59\x71\x41\xf5\x1f\x62\xb0\x5f\xc6\xbb\xf5\xad\x33\xa5\xe9\xf6\xe7\x1a\xd3\xd3\xd1\xfd\x7d\x5a\xc7\x87\xcf\xad\xd3\xaf\x75\xc6\x10\xfe\xbe\x9a\x1f\x13\xee\xd1\x0d\xda\xff\x7e\x2f\xd6\x41\xc4\x9e\xb4\x2b\x6d\xe4\x14\x8e\x71\x48\x4b\x61\x9c\xae\x06\xa2\x6c\xb5\x30\xcb\x8c\x6f\x8a\x9a\xc8\x45\x81\x65\x81\x03\x48\xf6\x1f\x48\xd9\xb0\xfb\xf4\x7b\x51\x2c\x49\xfc\x0b\xbd\xce\x53\x7b\xcd\xa8\x4b\x85\xed\x7c\x82\xc6\x01\xfd\x1a\x96\x33\x1f\xa5\x12\xc9\xf0\x9c\x67\xa0\x47\xd9\x7e\x1f\xde\xaf\xec\x28\x1c\x45\x86\x32\x33\xaa\xfd\x92\xb0\x8e\x87\x9e\xa8\xe3\x3f\x87\xb8\xd0\xd2\xf9\x9c\xd0\xe2\x7a\xec\xf5\xc5\x9d\xea\xdc\x59\xa4\xd6\xb4\xdf\x36\x89\x1c\x37\xbf\xe1\x53\xd3\xed\xaa\xb4\x6c\x75\xc9\xf4\x2c\x40\x13\x0e\xc0\x4b\x2f\x6c\xdb\x66\xd9\x93\x78\x8a\xbc\x5c\x32\xc5\x3e\x31\x2f\x26\x0d\x2e\x29\xe3\x25\x50\xcf\xee\x0f\x9b\x52\x96\x73\x5e\x3f\x30\x52\x6c\xa9\xfd\xf8\x01\x28\x88\xdb\x87\xa3\xfb\x75\x9e\xbf\xd8\x5b\xdb\x5c\x6c\x70\xef\x16\xce\x2f\x8c\x2f\xa0\x08\x0d\x85\xbf\x07\xfe\x91\x7b\x3f\xb0\x47\x5f\xca\x5d\x1f\x57\x4a\x8d\xa3\xef\x5f\x7b\xfb\x14\x4b\xa4\xf5\x86\x63\x25\x10\x60\xf6\x50\x05\x88\x17\xc2\x3b\xcf\xf9\xc0\x5f\x57\xc0\x5b\x6f\x6d\x15\x6f\x1f\x37\x1d\xe6\xf4\x04\x5f\x84\x5d\x5e\x48\x0c\x7d\x69\xa4\x9a\xe2\x82\x44\xd9\xed\x86\x0f\x0e\xeb\x24\x4d\x1b\xca\xe7\x1d\xa1\xe3\xb9\x3b\x20\xb0\xa8\x76\x60\x09\x17\x33\x70\xf0\x97\x11\x9b\xf3\x3c\x3f\x3a\x96\xec\xb1\x09\x0b\x6b\x0c\xa5\x9d\x15\x10\xd9\x88\xd4\xcb\x55\xc9\xf4\x71\xbb\x38\xaf\xe6\x3b\x6e\x4c\x75\xf0\xa3\xa8\x18\xd7\xc2\x3f\x55\x2c\x73\x8f\xdd\x98\x4f\xf8\x48\x7b\x21\x1d\x27\x6b\x8f\x75\xc9\xbc\x26\xad\x2e\xcd\x6f\x82\x1d\x98\xd8\x26\x62\x1c\x8a\x5a\x48\xe6\x1a\xc8\x50\x3f\x01\x01\xfd\x4b\xcf\x1e\x64\x9d\x82\x70\xb3\x52\x96\x89\x68\x97\xed\x9e\x51\x11\x75\xbf\xde\x8f\x77\x8b\xf9\x27\xe0\x77\xef\x52\xd9\xf5\xea\x12\x72\xda\x1f\x4a\xfa\x0e\x04\x7a\x97\x2f\xc8\x51\xad\x3f\xb2\xac\xcd\x11\x64\xe3\x5f\x98\x93\xef\x21\x58\x2d\xe4\x1b\xcf\x1a\x5a\x66\x63\x0a\xcd\x24\xae\x58\xa7\x89\xcb\x45\x00\xa1\xf5\xa2\xce\x4e\x23\xee\x10\x24\x74\x2e\x69\x75\x36\x41\x15\x2a\xc7\x4d\xb6\xb7\x23\x24\xda\x73\x44\x7e\xfb\xee\x99\x63\xb5\x5c\xc4\x74\x61\xae\xfb\x8c\xc9\x38\x57\x75\x5b\x6b\x85\xae\x8e\xca\x0b\xb8\xc2\xce\x82\x18\x17\x19\x2a\x4a\xd3\xe9\x2b\x8f\x39\x06\xde\x55\xe3\xa9\xc8\x6f\x38\xb6\x8f\x87\xd6\xe7\x44\xbd\x2d\x72\xb9\x63\xe3\x27\xbf\xe3\x19\xb3\x3a\x65\x5e\x97\xdc\x61\x20\xeb\xf9\x99\xda\xae\x57\xb7\xfb\x8c\xa3\xf5\xce\x3e\x2d\xe7\xa3\x77\xda\xaa\xed\x61\x55\xad\x1e\x8d\x04\xbb\x08\x4c\xa1\x74\x20\x63\x43\xe3\x7f\x76\xa4\x61\x2e\x60\x93\x32\x65\xf6\x9f\xaf\xfc\x05\x43\x34\x8b\x66\xc5\xec\x1f\xf4\x37\xda\x2e\x91\xc5\x6e\x6e\x8a\xfc\xef\xbf\x3c\x2f\x52\xf5\x12\x3f\x7c\x3a\xd4\x51\x53\xdd\x06\x8b\x62\xa4\x86\xbc\x30\x43\x91\xa2\x18\xe3\x2a\xaa\xca\x86\x63\x24\xfa\x95\x3e\x3c\x1d\x76\x32\xbf\xb6\x58\x0c\x8a\xa9\x82\x8c\x1a\x3a\x15\x3b\x4e\x7a\x0b\xe1\x5a\x1a\x33\xc3\x23\xc6\xbf\xba\x71\x0f\x26\x77\x3e\x5f\x8a\xa2\x79\xcf\x9f\xa6\x55\xce\xd2\x16\xb2\xf7\xe0\xfa\x6c\x8e\x2b\x45\x56\x61\x33\xa1\x3b\x27\x45\xc9\xb1\x7f\x0f\xd5\x4a\x8c\xe8\x2b\x52\xdb\x61\xee\xb3\xed\x99\x6e\x36\x6b\x93\x84\xa2\x56\x3e\x9d\x5e\xd5\xcb\xa0\xed\xd9\xa4\x41\x42\x34\xe5\x29\xf3\x50\xe8\x3c\x63\xd8\x35\x43\x4e\xe0\x99\x64\xec\x9b\xc0\x42\xf9\x77\xe9\xe6\xde\x41\xad\xef\x4e\x64\x17\x18\x81\x83\xc7\x02\xa5\x3e\xc9\x36\x24\xbc\xae\x79\x8c\x1e\x09\x40\xa4\xde\x02\xd1\xfa\xf4\x67\x02\x90\x6f\xae\x89\x0c\x35\x6c\x78\xa3\xb8\xf9\xfb\xa7\x43\x55\x39\x28\x1c\xc0\xaf\xd7\xd2\x3c\x66\xae\x54\x1d\x39\x34\x01\xc9\xe9\xd9\x10\xee\xd0\xba\xf3\x2b\x23\x8c\xed\x06\xf1\x78\x52\xc3\xd4\xd2\x2e\x1e\xb3\x9e\x69\x44\xa1\x94\x16\x52\x42\x30\xb7\xc3\xc0\x83\x28\x4f\x8a\x3b\xd1\x23\xd8\x16\xe3\x77\xad\x60\x14\x47\x56\x47\x52\xe2\xb0\x02\x66\xfa\xb0\x34\x54\x53\xcf\x23\x91\x6c\x55\x2d\x2f\xac\xe3\x71\xc2\x86\xf7\xa5\x8a\x37\xee\x15\xc1\x4c\x33\xfb\x75\x8d\x76\xf9\x88\xf8\x2b\x42\x3c\xd6\xcb\x41\x8b\xed\xbf\xd0\x2e\xdb\x4d\xcb\x67\x17\x1e\x63\x2d\xdb\x69\x87\x9a\xbc\x20\xc8\xa0\x8d\xad\x1c\x2a\x00\xa3\xca\x36\x8b\x51\x26\xde\xb2\xb8\x1e\x98\x1f\xb0\x0c\xf9\x85\x66\x66\x9a\xca\xf9\x7d\xb8\x97\x9d\x7a\x9e\x7f\x15\x3a\x7f\x76\x28\x64\x99\x02\x71\x89\x5b\x2e\x2d\xd1\x01\x4b\xdb\x99\x8c\xb1\x44\xed\xee\x30\x46\x10\x23\x4c\xec\x77\xee\xab\xce\x7c\x30\x93\x97\xa4\x44\x75\x45\x88\x85\xc1\xd8\x67\x93\xe4\x7f\xb2\x46\x46\x54\xe1\x24\x32\x2b\xd5\xd4\x76\x04\xeb\xdc\x2e\x89\xc6\x0d\x0a\x0c\xa9\x76\xa2\xe6\xbe\xac\xe6\x32\x07\xf7\xfd\xf9\xb6\xb7\x70\x3e\x48\xd7\xec\x0d\x89\xe4\x00\x0a\x02\x11\x0a\x4c\x20\xac\x50\x8d\x47\xb7\x52\x69\xac\x0f\x99\x97\xf8\x3b\x23\x0b\x07\x5f\x9c\x8a\x2c\x5f\x25\xae\xce\xd5\x8f\x09\xfd\x44\x83\x62\x8d\x37\x7d\x1d\x19\xb2\xc1\x2d\x09\x67\xaa\xc8\x72\x05\xd8\xd5\xb7\x86\xf1\x8f\xaf\xd5\x75\x7c\x8a\x21\x8f\xca\x4e\xe0\x4b\xdc\x9a\x28\x71\x2d\x2c\x74\x68\x5a\xca\x8b\x9a\x2b\x8b\x37\x57\x5a\xf6\x07\xbf\x5f\xdc\x9c\x4f\xb4\x98\x1e\x2b\xd6\xc7\xd7\x74\xfb\x57\x84\xc4\x81\x0f\x2a\x05\x19\x64\x38\x67\x5c\x0b\x91\x9f\x12\xda\xbb\x68\xad\xde\x34\xb9\x79\xc0\x12\x00\x58\x24\x4f\x7d\x1d\x1d\x79\x26\xe4\x93\xbf\xec\x25\x67\x99\xab\xda\x37\x8a\xfc\x83\x9e\xc4\x6c\x0a\xff\x22\xab\xf7\xf7\xd9\x20\x03\x3d\x1d\x0c\x37\x22\x6a\x80\x41\x1d\xa8\xb3\x8c\xc7\xf8\xc1\x11\x23\xcf\x40\xd4\x8e\x57\x57\x00\xda\x58\x59\xab\xfc\x17\x43\xb1\x8a\xb9\xd9\x2f\x50\x39\xda\xf1\xa7\x4c\x09\xab\xf9\x90\x85\x75\xd3\x5c\xaf\x76\x67\x55\x56\xa3\xd4\xe8\x7d\x39\x0f\xda\x33\x2c\xac\xce\xe8\x79\xb1\x9f\x1a\xfe\xa5\xb3\xa3\xf3\x75\x0b\xbb\xfe\x59\x0b\xa7\xe8\x30\x08\x2b\xac\x3e\x23\xc7\x82\xb2\x05\xd6\x36\xa5\xec\xcc\x35\x16\xaf\x08\x09\xbe\x9b\x76\x9b\xf3\xb7\xe9\x2a\x80\xbc\x7b\x6f\x32\xca\x3d\x22\x17\xff\xbd\xab\x0a\x9c\xf9\x3d\x7f\xe2\xbe\x23\xfb\x1c\x16\xb3\x3e\x3d\x41\xda\x97\x17\x93\xc7\x84\x1f\xf8\x13\xe0\x44\x89\x73\x6d\x91\xf4\x81\xe2\x0c\x0c\x0c\x46\x73\x55\x5a\xcf\x6d\x8a\x6d\x83\x94\x6f\x6f\x42\x3c\x7b\x96\x39\x8c\x37\x9d\xfe\x97\x92\x99\xd7\x17\xb0\x28\xf6\xc5\xc2\x59\xbe\xe7\xd2\xdc\xe8\x87\xb2\x0a\xb1\xfe\xa7\xcf\x96\x1b\x02\xf1\x35\xcb\x53\xcf\x84\x71\x56\xd6\xb8\x67\x91\x46\xb1\x65\x0d\x1a\x7a\xea\x57\x67\xfb\xce\xdc\x93\x0d\x6e\x6c\xf3\x7e\x0a\xd7\x5b\xe4\x8f\x14\x4c\x6e\x76\x9a\x0b\xf2\xe4\x91\x87\xd9\x65\xad\x54\x55\x2c\xa3\x20\x84\xb4\xd3\x51\xef\xeb\x27\xb4\xfe\x96\xbf\x61\x2e\x02\x79\x43\xc9\x33\x43\x1b\x20\xa1\xa1\x24\xa2\xe8\xcf\xca\xcf\x85\x48\xa2\xcc\xd0\xa6\xcb\xa9\xb3\x8f\x91\x55\xa6\x49\x04\x2d\xac\xed\x05\x74\xbb\x92\x62\xd2\xef\xa5\xd6\x15\x77\x4a\x56\x80\x07\xa2\xfe\x5f\xe0\x97\xaf\x66\xe8\x66\x01\xbf\xe3\xa4\xb2\xf8\x70\x5f\xc1\x3c\xd7\x2f\x34\x41\x59\xe4\xe5\x03\x65\x88\xe3\x47\xbb\x74\x80\xa2\x0e\x6f\xff\xfb\xb8\x29\x8f\x18\x82\x12\x7c\xc3\x14\x2e\x28\x47\x3e\xd2\x5b\x75\x55\xf1\x50\x72\x21\xa6\xd3\xa1\x9e\x02\x84\x9d\x8c\x13\xda\x19\x49\x36\xef\xdc\xc9\x19\x82\x20\x85\xeb\x0a\x82\x6f\x04\xe3\x8c\x2d\xe1\xd2\x20\x21\xb9\x60\x3a\xc6\xb0\x36\x7a\xeb\x57\x17\x3a\xf9\x9d\xee\x02\x4d\x94\x73\xf1\x24\x65\x74\x3d\xcf\xeb\xc9\x50\x89\x5a\x4d\x36\x8d\xaf\xa7\x40\x83\xbc\x2f\x9a\xc1\x28\x39\xbf\xeb\x58\x49\x17\x69\x45\x0b\xe3\x7f\x8b\x35\x3d\x26\x46\xca\x0d\x79\x27\xdd\xb8\x66\x34\xf1\xcb\xa7\x57\x0f\xdd\x1f\xc8\x0e\xf3\x80\xb0\x3f\x24\x40\xdd\xee\xe0\x0a\x08\x12\x5e\xd7\xd3\x78\x00\xa9\xb5\xf7\x95\xc0\xd5\x84\xdd\x48\xde\x58\xec\xf4\xf9\xd2\xf4\xd8\x66\xa5\x3c\xe5\xfe\x4e\xfb\xcb\x2a\x40\xc4\x8f\x9e\x42\x4d\xf3\x42\x49\x73\xd7\x10\xfc\xe7\xae\x42\xab\xe6\x7d\xa6\xc7\xdd\x12\xbf\x91\xa3\x9c\xe8\x58\x2b\x9d\x5f\x71\xbd\x22\x68\x06\x06\x06\xbb\xc5\xaf\x16\x7b\x83\xfd\x15\x97\x43\x2a\xba\xc3\x87\x81\xe7\x0e\xab\x1b\xe7\xb7\x26\x66\x37\x88\xc7\x60\x39\x28\xc4\x2e\xcc\xd4\xa4\x50\xa7\x24\x27\x2a\x7f\x67\xfe\x4e\x66\x19\x86\x70\xcc\x6f\x8b\x90\x77\xdb\xc9\x01\x00\x88\x14\x35\x55\x95\x8c\x8e\xbf\xa7\xca\xbe\x69\xdc\x60\x41\x86\x40\x84\x72\xe1\x67\xdd\xe2\xbf\xd9\x4c\xb9\x50\xb2\x3e\xd5\x85\x4e\xba\x9a\x8b\xe7\x0c\xe9\xe7\x05\x79\x56\xe1\xaa\x73\xda\x65\x8d\x6b\x89\x8c\x94\xd9\x53\x47\xd0\xbc\x3d\xe7\x5a\xfa\x3a\x08\x6a\xd2\xc4\xcc\x21\x83\x2a\xca\x2e\x01\xfa\xbd\x02\x4f\x1b\xff\xde\x9f\x31\x87\xc8\xcb\xe1\xc9\x93\x56\x10\x31\x62\x7f\x96\x65\xe2\xa5\x48\x9e\x6b\x81\x52\x83\xfd\xf0\x34\x04\xb1\xac\xcb\x94\x13\xfe\xe0\x17\x55\x94\xb8\x1a\xf1\x36\x23\x3a\xfd\x04\xb6\x46\xff\x57\xc5\xca\x94\xf9\x02\x2e\xff\xcc\xc8\x2b\x83\x66\xf9\x6a\x81\x04\x38\x38\xc5\x23\x06\xd1\xf7\xcb\x9a\xe1\x9c\x26\x2f\xdf\xd9\x92\xb8\x10\xc3\xc9\x34\xf9\x58\xba\x3d\x64\x41\x81\x1d\x94\xd6\xd2\xd8\xa3\x3f\xa6\xd8\xf1\x54\x96\x94\x30\x57\x01\x80\x83\x01\x3a\x0c\x66\x1f\x63\xef\xd5\xda\x73\x3d\x7a\x0e\x18\xfc\x5c\x56\xc1\xe9\x76\x60\x5c\x52\x55\x3d\x29\x18\x70\x3f\x0d\x59\xa7\x24\xe0\x61\x79\x61\x3a\x46\xe2\xd0\x76\x52\x5b\xc7\xcb\x77\xd3\xff\xce\xd6\xb5\xd8\xbe\x22\x1c\x04\x42\x55\x18\xba\x29\x98\xe1\x6b\x86\xae\x43\x97\x68\xa7\xbf\x72\x31\x76\xfb\xa8\x66\x38\x58\x3f\xda\x04\x94\xc9\x0e\xf3\x84\x32\x62\x34\x01\x30\xd3\x60\xfb\x99\xad\xdc\x44\x0d\x60\x98\x00\x8e\x16\x56\x4b\x6d\x33\xae\x22\xae\x33\x85\x0f\xc4\x97\x82\x7f\x4e\x0b\x7a\x72\xb8\xd6\x90\xd8\xe7\xd0\x73\x83\xd3\x84\x70\x10\x3c\xa2\x0e\xaf\x5d\x6e\x5b\x38\x90\xc5\x62\xf8\xa3\x19\x4f\x7b\x1c\x19\xc0\xcf\x7c\x00\xe8\x33\x06\xac\x8d\x38\x4b\xab\x41\x6a\x94\xa1\xc9\xa0\x7e\xfa\xa5\x0c\x08\x9a\xdf\x16\x81\x2d\x2f\x35\x0d\xf3\x97\xc2\x95\xe6\x1f\xf4\x27\xa9\xb1\x54\x82\xe2\x23\x76\x35\x6a\x7b\xb8\x5b\x0b\x00\x02\xdc\x65\xf8\xf7\x25\x78\x6d\xfb\x5a\xb8\xdf\xee\x2a\x25\xda\xb8\xec\x4e\x91\xd2\x83\xee\xf4\xa5\x26\x10\xac\x6f\x4e\x98\xf3\x8f\x1e\x34\x00\x05\xf4\x6a\x6d\x24\x85\x91\xd3\xd8\x54\xc9\xc2\x75\xfd\x81\x65\x95\xce\x1f\x5e\x51\x33\x7f\x8f\xbf\x05\x0c\xe8\x7a\x79\xc6\xed\xac\x41\x04\x96\x2c\xc0\xd8\xd7\x36\x34\x03\x38\x6a\x85\xda\xb5\x78\x2b\xe1\xc4\xee\x76\x7c\xa9\x90\xd1\x7a\xd6\x13\xaf\xd7\x5b\x5e\xc6\x0a\x97\x8d\xd7\x75\x32\x34\x13\x1c\x02\xe8\x7c\xd0\xee\xaa\x89\xc1\x3a\xea\x8d\xeb\xd4\xf9\x19\x8f\x94\xac\x40\xcb\x19\x09\x6e\x27\x6e\x3a\xa9\xd8\x56\x81\x04\x93\xaf\x80\xa2\xc0\x07\xcd\x95\xdf\xf7\xd5\x83\xca\xa8\x03\x13\x13\xd0\xd4\x3f\x68\xa7\x30\x76\xc2\x79\x7b\x86\x9b\x32\x3f\x9b\xee\x2e\x10\x61\x2d\xda\x56\x66\x4c\x4e\x65\x7a\x04\xc3\x98\x49\x00\x2f\xae\x27\x0c\x1a\xed\x93\xaf\xef\x80\x59\x4d\x3e\x33\xe3\xfd\x01\x5f\x21\x38\x5a\x76\x17\x6a\xbb\x8e\x16\xe3\x07\x61\x00\x2d\x4e\xdb\xe1\xe4\x44\x58\x5a\x9e\xb0\x41\x72\x38\xd4\x9e\x1b\xd3\x80\xfe\x06\x50\x57\xbb\xae\xcd\xdb\xf1\xe7\x26\x52\xa4\x6b\xe4\xff\x70\x7d\x96\x01\x62\x5f\x29\x29\x7f\x05\x58\xd9\x93\x3e\x36\xfd\x67\x78\x25\xa7\xfe\xd8\x00\x47\x47\xd3\x30\xab\x35\x76\xc5\x84\xb2\x1a\xe0\x25\x28\x43\xcf\x55\x81\x20\xac\x1e\xad\x8e\x4d\x0a\xc8\xea\x19\x06\xb3\x1e\x89\x30\x80\x15\x60\xf4\xe8\xb9\xd1\x17\x77\xc6\xe8\xf9\x05\x96\xc0\x60\x52\x94\xd5\x37\x5e\x82\xe2\xff\xd9\x68\xf8\x2d\xa4\x4f\x2a\xea\x53\xd3\xaa\xce\x34\x00\x00\x00\x68\x3e\xd1\x55\xad\x54\x46\xbf\xfe\x7f\x01\x00\x00\xff\xff\xce\x71\x20\x86\x92\x23\x00\x00"), 30 | }, 31 | } 32 | fs["/"].(*vfsgen۰DirInfo).entries = []os.FileInfo{ 33 | fs["/icon.png"].(os.FileInfo), 34 | } 35 | 36 | return fs 37 | }() 38 | 39 | type vfsgen۰FS map[string]interface{} 40 | 41 | func (fs vfsgen۰FS) Open(path string) (http.File, error) { 42 | path = pathpkg.Clean("/" + path) 43 | f, ok := fs[path] 44 | if !ok { 45 | return nil, &os.PathError{Op: "open", Path: path, Err: os.ErrNotExist} 46 | } 47 | 48 | switch f := f.(type) { 49 | case *vfsgen۰CompressedFileInfo: 50 | gr, err := gzip.NewReader(bytes.NewReader(f.compressedContent)) 51 | if err != nil { 52 | // This should never happen because we generate the gzip bytes such that they are always valid. 53 | panic("unexpected error reading own gzip compressed bytes: " + err.Error()) 54 | } 55 | return &vfsgen۰CompressedFile{ 56 | vfsgen۰CompressedFileInfo: f, 57 | gr: gr, 58 | }, nil 59 | case *vfsgen۰DirInfo: 60 | return &vfsgen۰Dir{ 61 | vfsgen۰DirInfo: f, 62 | }, nil 63 | default: 64 | // This should never happen because we generate only the above types. 65 | panic(fmt.Sprintf("unexpected type %T", f)) 66 | } 67 | } 68 | 69 | // vfsgen۰CompressedFileInfo is a static definition of a gzip compressed file. 70 | type vfsgen۰CompressedFileInfo struct { 71 | name string 72 | modTime time.Time 73 | compressedContent []byte 74 | uncompressedSize int64 75 | } 76 | 77 | func (f *vfsgen۰CompressedFileInfo) Readdir(count int) ([]os.FileInfo, error) { 78 | return nil, fmt.Errorf("cannot Readdir from file %s", f.name) 79 | } 80 | func (f *vfsgen۰CompressedFileInfo) Stat() (os.FileInfo, error) { return f, nil } 81 | 82 | func (f *vfsgen۰CompressedFileInfo) GzipBytes() []byte { 83 | return f.compressedContent 84 | } 85 | 86 | func (f *vfsgen۰CompressedFileInfo) Name() string { return f.name } 87 | func (f *vfsgen۰CompressedFileInfo) Size() int64 { return f.uncompressedSize } 88 | func (f *vfsgen۰CompressedFileInfo) Mode() os.FileMode { return 0444 } 89 | func (f *vfsgen۰CompressedFileInfo) ModTime() time.Time { return f.modTime } 90 | func (f *vfsgen۰CompressedFileInfo) IsDir() bool { return false } 91 | func (f *vfsgen۰CompressedFileInfo) Sys() interface{} { return nil } 92 | 93 | // vfsgen۰CompressedFile is an opened compressedFile instance. 94 | type vfsgen۰CompressedFile struct { 95 | *vfsgen۰CompressedFileInfo 96 | gr *gzip.Reader 97 | grPos int64 // Actual gr uncompressed position. 98 | seekPos int64 // Seek uncompressed position. 99 | } 100 | 101 | func (f *vfsgen۰CompressedFile) Read(p []byte) (n int, err error) { 102 | if f.grPos > f.seekPos { 103 | // Rewind to beginning. 104 | err = f.gr.Reset(bytes.NewReader(f.compressedContent)) 105 | if err != nil { 106 | return 0, err 107 | } 108 | f.grPos = 0 109 | } 110 | if f.grPos < f.seekPos { 111 | // Fast-forward. 112 | _, err = io.CopyN(ioutil.Discard, f.gr, f.seekPos-f.grPos) 113 | if err != nil { 114 | return 0, err 115 | } 116 | f.grPos = f.seekPos 117 | } 118 | n, err = f.gr.Read(p) 119 | f.grPos += int64(n) 120 | f.seekPos = f.grPos 121 | return n, err 122 | } 123 | func (f *vfsgen۰CompressedFile) Seek(offset int64, whence int) (int64, error) { 124 | switch whence { 125 | case io.SeekStart: 126 | f.seekPos = 0 + offset 127 | case io.SeekCurrent: 128 | f.seekPos += offset 129 | case io.SeekEnd: 130 | f.seekPos = f.uncompressedSize + offset 131 | default: 132 | panic(fmt.Errorf("invalid whence value: %v", whence)) 133 | } 134 | return f.seekPos, nil 135 | } 136 | func (f *vfsgen۰CompressedFile) Close() error { 137 | return f.gr.Close() 138 | } 139 | 140 | // vfsgen۰DirInfo is a static definition of a directory. 141 | type vfsgen۰DirInfo struct { 142 | name string 143 | modTime time.Time 144 | entries []os.FileInfo 145 | } 146 | 147 | func (d *vfsgen۰DirInfo) Read([]byte) (int, error) { 148 | return 0, fmt.Errorf("cannot Read from directory %s", d.name) 149 | } 150 | func (d *vfsgen۰DirInfo) Close() error { return nil } 151 | func (d *vfsgen۰DirInfo) Stat() (os.FileInfo, error) { return d, nil } 152 | 153 | func (d *vfsgen۰DirInfo) Name() string { return d.name } 154 | func (d *vfsgen۰DirInfo) Size() int64 { return 0 } 155 | func (d *vfsgen۰DirInfo) Mode() os.FileMode { return 0755 | os.ModeDir } 156 | func (d *vfsgen۰DirInfo) ModTime() time.Time { return d.modTime } 157 | func (d *vfsgen۰DirInfo) IsDir() bool { return true } 158 | func (d *vfsgen۰DirInfo) Sys() interface{} { return nil } 159 | 160 | // vfsgen۰Dir is an opened dir instance. 161 | type vfsgen۰Dir struct { 162 | *vfsgen۰DirInfo 163 | pos int // Position within entries for Seek and Readdir. 164 | } 165 | 166 | func (d *vfsgen۰Dir) Seek(offset int64, whence int) (int64, error) { 167 | if offset == 0 && whence == io.SeekStart { 168 | d.pos = 0 169 | return 0, nil 170 | } 171 | return 0, fmt.Errorf("unsupported Seek in directory %s", d.name) 172 | } 173 | 174 | func (d *vfsgen۰Dir) Readdir(count int) ([]os.FileInfo, error) { 175 | if d.pos >= len(d.entries) && count > 0 { 176 | return nil, io.EOF 177 | } 178 | if count <= 0 || count > len(d.entries)-d.pos { 179 | count = len(d.entries) - d.pos 180 | } 181 | e := d.entries[d.pos : d.pos+count] 182 | d.pos += count 183 | return e, nil 184 | } 185 | -------------------------------------------------------------------------------- /go.sum: -------------------------------------------------------------------------------- 1 | cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= 2 | cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= 3 | cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= 4 | cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU= 5 | cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= 6 | cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc= 7 | cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0= 8 | cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To= 9 | cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4= 10 | cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M= 11 | cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc= 12 | cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk= 13 | cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs= 14 | cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc= 15 | cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY= 16 | cloud.google.com/go v0.72.0/go.mod h1:M+5Vjvlc2wnp6tjzE102Dw08nGShTscUx2nZMufOKPI= 17 | cloud.google.com/go v0.74.0/go.mod h1:VV1xSbzvo+9QJOxLDaJfTjx5e+MePCpCWwvftOeQmWk= 18 | cloud.google.com/go v0.78.0/go.mod h1:QjdrLG0uq+YwhjoVOLsS1t7TW8fs36kLs4XO5R5ECHg= 19 | cloud.google.com/go v0.79.0/go.mod h1:3bzgcEeQlzbuEAYu4mrWhKqWjmpprinYgKJLgKHnbb8= 20 | cloud.google.com/go v0.81.0/go.mod h1:mk/AM35KwGk/Nm2YSeZbxXdrNK3KZOYHmLkOqC2V6E0= 21 | cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= 22 | cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE= 23 | cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc= 24 | cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg= 25 | cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc= 26 | cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ= 27 | cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= 28 | cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk= 29 | cloud.google.com/go/firestore v1.1.0/go.mod h1:ulACoGHTpvq5r8rxGJ4ddJZBZqakUQqClKRT5SZwBmk= 30 | cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= 31 | cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw= 32 | cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA= 33 | cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU= 34 | cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw= 35 | cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos= 36 | cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk= 37 | cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs= 38 | cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= 39 | dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= 40 | github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= 41 | github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= 42 | github.com/Masterminds/semver v1.5.0 h1:H65muMkzWKEuNDnfl9d70GUjFniHKHRbFPGBuZ3QEww= 43 | github.com/Masterminds/semver v1.5.0/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y= 44 | github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= 45 | github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= 46 | github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= 47 | github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= 48 | github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= 49 | github.com/bketelsen/crypt v0.0.4/go.mod h1:aI6NrJ0pMGgvZKL1iVgXLnfIFJtfV+bKCoqOes/6LfM= 50 | github.com/briandowns/spinner v1.16.0 h1:DFmp6hEaIx2QXXuqSJmtfSBSAjRmpGiKG6ip2Wm/yOs= 51 | github.com/briandowns/spinner v1.16.0/go.mod h1:QOuQk7x+EaDASo80FEXwlwiA+j/PPIcX3FScO+3/ZPQ= 52 | github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= 53 | github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= 54 | github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= 55 | github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= 56 | github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= 57 | github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= 58 | github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= 59 | github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= 60 | github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= 61 | github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= 62 | github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= 63 | github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 64 | github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= 65 | github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 66 | github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= 67 | github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= 68 | github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= 69 | github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po= 70 | github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= 71 | github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= 72 | github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= 73 | github.com/fatih/color v1.7.0 h1:DkWD4oS2D8LGGgTQ6IvwJJXSL5Vp2ffcQg58nFV38Ys= 74 | github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= 75 | github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= 76 | github.com/gen2brain/beeep v0.0.0-20210529141713-5586760f0cc1 h1:Xh9mvwEmhbdXlRSsgn+N0zj/NqnKvpeqL08oKDHln2s= 77 | github.com/gen2brain/beeep v0.0.0-20210529141713-5586760f0cc1/go.mod h1:ElSskYZe3oM8kThaHGJ+kiN2yyUMVXMZ7WxF9QqLDS8= 78 | github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= 79 | github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= 80 | github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= 81 | github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= 82 | github.com/go-toast/toast v0.0.0-20190211030409-01e6764cf0a4 h1:qZNfIGkIANxGv/OqtnntR4DfOY2+BgwR60cAcu/i3SE= 83 | github.com/go-toast/toast v0.0.0-20190211030409-01e6764cf0a4/go.mod h1:kW3HQ4UdaAyrUCSSDR4xUzBKW6O2iA4uHhk7AtyYp10= 84 | github.com/godbus/dbus/v5 v5.0.3/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= 85 | github.com/godbus/dbus/v5 v5.0.4 h1:9349emZab16e7zQvpmsbtjc18ykshndd8y2PG3sgJbA= 86 | github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= 87 | github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= 88 | github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= 89 | github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= 90 | github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= 91 | github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= 92 | github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= 93 | github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= 94 | github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= 95 | github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= 96 | github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= 97 | github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= 98 | github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4= 99 | github.com/golang/mock v1.5.0/go.mod h1:CWnOUgYIOo4TcNZ0wHX3YZCqsaM1I1Jvs6v3mP3KVu8= 100 | github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= 101 | github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= 102 | github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= 103 | github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= 104 | github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= 105 | github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk= 106 | github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= 107 | github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= 108 | github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= 109 | github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= 110 | github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= 111 | github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= 112 | github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= 113 | github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= 114 | github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= 115 | github.com/golang/protobuf v1.5.1/go.mod h1:DopwsBzvsk0Fs44TXzsVbJyPhcCPeIwnvohx4u74HPM= 116 | github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= 117 | github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= 118 | github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= 119 | github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= 120 | github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= 121 | github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= 122 | github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= 123 | github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= 124 | github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= 125 | github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= 126 | github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= 127 | github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= 128 | github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= 129 | github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= 130 | github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= 131 | github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= 132 | github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= 133 | github.com/google/martian/v3 v3.1.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= 134 | github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= 135 | github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= 136 | github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= 137 | github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= 138 | github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= 139 | github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= 140 | github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= 141 | github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= 142 | github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= 143 | github.com/google/pprof v0.0.0-20210122040257-d980be63207e/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= 144 | github.com/google/pprof v0.0.0-20210226084205-cbba55b83ad5/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= 145 | github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= 146 | github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= 147 | github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= 148 | github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= 149 | github.com/gopherjs/gopherjs v0.0.0-20180825215210-0210a2f0f73c/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= 150 | github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8= 151 | github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= 152 | github.com/gopherjs/gopherwasm v1.1.0 h1:fA2uLoctU5+T3OhOn2vYP0DVT6pxc7xhTlBB1paATqQ= 153 | github.com/gopherjs/gopherwasm v1.1.0/go.mod h1:SkZ8z7CWBz5VXbhJel8TxCmAcsQqzgWGR/8nMhyhZSI= 154 | github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= 155 | github.com/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q= 156 | github.com/hashicorp/consul/sdk v0.1.1/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8= 157 | github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= 158 | github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= 159 | github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= 160 | github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= 161 | github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= 162 | github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU= 163 | github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU= 164 | github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4= 165 | github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= 166 | github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= 167 | github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90= 168 | github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= 169 | github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= 170 | github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= 171 | github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64= 172 | github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ= 173 | github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I= 174 | github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc= 175 | github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= 176 | github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= 177 | github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM= 178 | github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= 179 | github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= 180 | github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= 181 | github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= 182 | github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= 183 | github.com/k0kubun/go-ansi v0.0.0-20180517002512-3bf9e2903213/go.mod h1:vNUNkEQ1e29fT/6vq2aBdFsgNPmy8qMdSay1npru+Sw= 184 | github.com/kardianos/osext v0.0.0-20190222173326-2bc1f35cddc0 h1:iQTw/8FWTuc7uiaSepXwyf3o52HaUYcV+Tu66S3F5GA= 185 | github.com/kardianos/osext v0.0.0-20190222173326-2bc1f35cddc0/go.mod h1:1NbS8ALrpOvjt0rHPNLyCIeMtbizbir8U//inJ+zuB8= 186 | github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= 187 | github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= 188 | github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= 189 | github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= 190 | github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= 191 | github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= 192 | github.com/magiconair/properties v1.8.5/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60= 193 | github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= 194 | github.com/mattn/go-colorable v0.1.2 h1:/bC9yWikZXAL9uJdulbSfyVNIR3n3trXl+v8+1sx8mU= 195 | github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= 196 | github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= 197 | github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= 198 | github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y= 199 | github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= 200 | github.com/mattn/go-runewidth v0.0.13 h1:lTGmDsbAYt5DmK6OnoV7EuIF1wEIFAcxld6ypU4OSgU= 201 | github.com/mattn/go-runewidth v0.0.13/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= 202 | github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= 203 | github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc= 204 | github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db h1:62I3jR2EmQ4l5rM/4FEfDWcRD+abF5XlKShorW5LRoQ= 205 | github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db/go.mod h1:l0dey0ia/Uv7NcFFVbCLtqEBQbrT4OCwCSKTEv6enCw= 206 | github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= 207 | github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI= 208 | github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS42BGNg= 209 | github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY= 210 | github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= 211 | github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= 212 | github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= 213 | github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= 214 | github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= 215 | github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= 216 | github.com/nu7hatch/gouuid v0.0.0-20131221200532-179d4d0c4d8d h1:VhgPp6v9qf9Agr/56bj7Y/xa04UccTW04VP0Qed4vnQ= 217 | github.com/nu7hatch/gouuid v0.0.0-20131221200532-179d4d0c4d8d/go.mod h1:YUTz3bUH2ZwIWBy3CJBeOBEugqcmXREj14T+iG/4k4U= 218 | github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= 219 | github.com/pelletier/go-toml v1.9.3/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c= 220 | github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= 221 | github.com/pkg/sftp v1.10.1/go.mod h1:lYOWFsE0bwd1+KfKJaKeuokY15vzFx25BLbzYYoAxZI= 222 | github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= 223 | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= 224 | github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= 225 | github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= 226 | github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY= 227 | github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= 228 | github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= 229 | github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= 230 | github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= 231 | github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= 232 | github.com/schollz/progressbar/v3 v3.8.3 h1:FnLGl3ewlDUP+YdSwveXBaXs053Mem/du+wr7XSYKl8= 233 | github.com/schollz/progressbar/v3 v3.8.3/go.mod h1:pWnVCjSBZsT2X3nx9HfRdnCDrpbevliMeoEVhStwHko= 234 | github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= 235 | github.com/shurcooL/httpfs v0.0.0-20190707220628-8d4bc4ba7749 h1:bUGsEnyNbVPw06Bs80sCeARAlK8lhwqGyi6UT8ymuGk= 236 | github.com/shurcooL/httpfs v0.0.0-20190707220628-8d4bc4ba7749/go.mod h1:ZY1cvUeJuFPAdZ/B6v7RHavJWZn2YPVFQ1OSXhCGOkg= 237 | github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= 238 | github.com/shurcooL/vfsgen v0.0.0-20200824052919-0d455de96546 h1:pXY9qYc/MP5zdvqWEUH6SjNiu7VhSjuVFTFiTcphaLU= 239 | github.com/shurcooL/vfsgen v0.0.0-20200824052919-0d455de96546/go.mod h1:TrYk7fJVaAttu97ZZKrO9UbRa8izdowaMIZcxYMbVaw= 240 | github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= 241 | github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= 242 | github.com/spf13/afero v1.6.0/go.mod h1:Ai8FlHk4v/PARR026UzYexafAt9roJ7LcLMAmO6Z93I= 243 | github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= 244 | github.com/spf13/cobra v1.2.1 h1:+KmjbUw1hriSNMF55oPrkZcb27aECyrj8V2ytv7kWDw= 245 | github.com/spf13/cobra v1.2.1/go.mod h1:ExllRjgxM/piMAM+3tAZvg8fsklGAf3tPfi+i8t68Nk= 246 | github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo= 247 | github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= 248 | github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= 249 | github.com/spf13/viper v1.8.1/go.mod h1:o0Pch8wJ9BVSWGQMbra6iw0oQ5oktSIBaujf1rJH9Ns= 250 | github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= 251 | github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= 252 | github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= 253 | github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= 254 | github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= 255 | github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= 256 | github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= 257 | github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= 258 | github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= 259 | github.com/tadvi/systray v0.0.0-20190226123456-11a2b8fa57af h1:6yITBqGTE2lEeTPG04SN9W+iWHCRyHqlVYILiSXziwk= 260 | github.com/tadvi/systray v0.0.0-20190226123456-11a2b8fa57af/go.mod h1:4F09kP5F+am0jAwlQLddpoMDM+iewkxxt6nxUQ5nq5o= 261 | github.com/thedevsaddam/retry v0.0.0-20200324223450-9769a859cc6d h1:U8ZUZKRBI+Xgo3QWD/alCQ2vIysyl0Efx8yCJWPdaGQ= 262 | github.com/thedevsaddam/retry v0.0.0-20200324223450-9769a859cc6d/go.mod h1:2rz2mY+1qEXG47loLDkV+ZJHGFwmhax5rOTpP+5aR80= 263 | github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= 264 | github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= 265 | github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= 266 | github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= 267 | github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= 268 | go.etcd.io/etcd/api/v3 v3.5.0/go.mod h1:cbVKeC6lCfl7j/8jBhAK6aIYO9XOjdptoxU/nLQcPvs= 269 | go.etcd.io/etcd/client/pkg/v3 v3.5.0/go.mod h1:IJHfcCEKxYu1Os13ZdwCwIUTUVGYTSAM3YSwc9/Ac1g= 270 | go.etcd.io/etcd/client/v2 v2.305.0/go.mod h1:h9puh54ZTgAKtEbut2oe9P4L/oqKCVB6xsXlzd7alYQ= 271 | go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= 272 | go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= 273 | go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= 274 | go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= 275 | go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= 276 | go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= 277 | go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E= 278 | go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= 279 | go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= 280 | go.uber.org/zap v1.17.0/go.mod h1:MXVU+bhUf/A7Xi2HNOnopQOrmycQ5Ih87HtOu4q5SSo= 281 | golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= 282 | golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= 283 | golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= 284 | golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= 285 | golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= 286 | golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= 287 | golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= 288 | golang.org/x/crypto v0.0.0-20210817164053-32db794688a5 h1:HWj/xjIHfjYU5nVXpTM0s39J9CbLn7Cc5a7IC5rwsMQ= 289 | golang.org/x/crypto v0.0.0-20210817164053-32db794688a5/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= 290 | golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= 291 | golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= 292 | golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= 293 | golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek= 294 | golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY= 295 | golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= 296 | golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= 297 | golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= 298 | golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= 299 | golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= 300 | golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= 301 | golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= 302 | golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= 303 | golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= 304 | golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= 305 | golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= 306 | golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= 307 | golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= 308 | golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= 309 | golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs= 310 | golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= 311 | golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= 312 | golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= 313 | golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= 314 | golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= 315 | golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= 316 | golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= 317 | golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= 318 | golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= 319 | golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= 320 | golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= 321 | golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= 322 | golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= 323 | golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= 324 | golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= 325 | golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= 326 | golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= 327 | golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= 328 | golang.org/x/net v0.0.0-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= 329 | golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= 330 | golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= 331 | golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= 332 | golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= 333 | golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= 334 | golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= 335 | golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= 336 | golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= 337 | golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= 338 | golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= 339 | golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= 340 | golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= 341 | golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= 342 | golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= 343 | golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= 344 | golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= 345 | golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= 346 | golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= 347 | golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= 348 | golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= 349 | golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= 350 | golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= 351 | golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= 352 | golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= 353 | golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= 354 | golang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= 355 | golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= 356 | golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= 357 | golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= 358 | golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= 359 | golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc= 360 | golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= 361 | golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= 362 | golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= 363 | golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= 364 | golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= 365 | golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= 366 | golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= 367 | golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= 368 | golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= 369 | golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= 370 | golang.org/x/oauth2 v0.0.0-20210220000619-9bb904979d93/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= 371 | golang.org/x/oauth2 v0.0.0-20210313182246-cd4f82c27b84/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= 372 | golang.org/x/oauth2 v0.0.0-20210402161424-2e8d93401602/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= 373 | golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 374 | golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 375 | golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 376 | golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 377 | golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 378 | golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 379 | golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 380 | golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 381 | golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 382 | golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 383 | golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 384 | golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 385 | golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 386 | golang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 387 | golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 388 | golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 389 | golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 390 | golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 391 | golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 392 | golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 393 | golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 394 | golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 395 | golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 396 | golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 397 | golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 398 | golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 399 | golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 400 | golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 401 | golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 402 | golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 403 | golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 404 | golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 405 | golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 406 | golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 407 | golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 408 | golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 409 | golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 410 | golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 411 | golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 412 | golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 413 | golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 414 | golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 415 | golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 416 | golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 417 | golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 418 | golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 419 | golang.org/x/sys v0.0.0-20210220050731-9a76102bfb43/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 420 | golang.org/x/sys v0.0.0-20210305230114-8fe3ee5dd75b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 421 | golang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 422 | golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 423 | golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 424 | golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 425 | golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 426 | golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 427 | golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 428 | golang.org/x/sys v0.0.0-20210910150752-751e447fb3d0 h1:xrCZDmdtoloIiooiA9q0OQb9r8HejIHYoHGhGCe1pGg= 429 | golang.org/x/sys v0.0.0-20210910150752-751e447fb3d0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 430 | golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= 431 | golang.org/x/term v0.0.0-20210615171337-6886f2dfbf5b h1:9zKuko04nR4gjZ4+DNjHqRlAJqbJETHwiNKDqTfOjfE= 432 | golang.org/x/term v0.0.0-20210615171337-6886f2dfbf5b/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= 433 | golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= 434 | golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= 435 | golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= 436 | golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= 437 | golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= 438 | golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= 439 | golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= 440 | golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= 441 | golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= 442 | golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= 443 | golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= 444 | golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= 445 | golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= 446 | golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= 447 | golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= 448 | golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= 449 | golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= 450 | golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= 451 | golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= 452 | golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= 453 | golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= 454 | golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= 455 | golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= 456 | golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= 457 | golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= 458 | golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= 459 | golang.org/x/tools v0.0.0-20191112195655-aa38f8e97acc/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= 460 | golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= 461 | golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= 462 | golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= 463 | golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= 464 | golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= 465 | golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= 466 | golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= 467 | golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= 468 | golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= 469 | golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= 470 | golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= 471 | golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= 472 | golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= 473 | golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= 474 | golang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= 475 | golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= 476 | golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= 477 | golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8= 478 | golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= 479 | golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= 480 | golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= 481 | golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= 482 | golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= 483 | golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= 484 | golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= 485 | golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= 486 | golang.org/x/tools v0.0.0-20200904185747-39188db58858/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE= 487 | golang.org/x/tools v0.0.0-20201110124207-079ba7bd75cd/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= 488 | golang.org/x/tools v0.0.0-20201201161351-ac6f37ff4c2a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= 489 | golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= 490 | golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= 491 | golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= 492 | golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= 493 | golang.org/x/tools v0.1.2 h1:kRBLX7v7Af8W7Gdbbc908OJcdgtK8bOz9Uaj8/F1ACA= 494 | golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= 495 | golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= 496 | golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= 497 | golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= 498 | golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= 499 | google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= 500 | google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= 501 | google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= 502 | google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= 503 | google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= 504 | google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= 505 | google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= 506 | google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= 507 | google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= 508 | google.golang.org/api v0.19.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= 509 | google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= 510 | google.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= 511 | google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= 512 | google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= 513 | google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM= 514 | google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc= 515 | google.golang.org/api v0.35.0/go.mod h1:/XrVsuzM0rZmrsbjJutiuftIzeuTQcEeaYcSk/mQ1dg= 516 | google.golang.org/api v0.36.0/go.mod h1:+z5ficQTmoYpPn8LCUNVpK5I7hwkpjbcgqA7I34qYtE= 517 | google.golang.org/api v0.40.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjRCQ8= 518 | google.golang.org/api v0.41.0/go.mod h1:RkxM5lITDfTzmyKFPt+wGrCJbVfniCr2ool8kTBzRTU= 519 | google.golang.org/api v0.43.0/go.mod h1:nQsDGjRXMo4lvh5hP0TKqF244gqhGcr/YSIykhUk/94= 520 | google.golang.org/api v0.44.0/go.mod h1:EBOGZqzyhtvMDoxwS97ctnh0zUmYY6CxqXsc1AvkYD8= 521 | google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= 522 | google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= 523 | google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= 524 | google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= 525 | google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= 526 | google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= 527 | google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= 528 | google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= 529 | google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= 530 | google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= 531 | google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= 532 | google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= 533 | google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= 534 | google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= 535 | google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= 536 | google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= 537 | google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= 538 | google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= 539 | google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= 540 | google.golang.org/genproto v0.0.0-20200115191322-ca5a22157cba/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= 541 | google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= 542 | google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA= 543 | google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= 544 | google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= 545 | google.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= 546 | google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= 547 | google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= 548 | google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= 549 | google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= 550 | google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= 551 | google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= 552 | google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U= 553 | google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= 554 | google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA= 555 | google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= 556 | google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= 557 | google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= 558 | google.golang.org/genproto v0.0.0-20200904004341-0bd0a958aa1d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= 559 | google.golang.org/genproto v0.0.0-20201109203340-2640f1f9cdfb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= 560 | google.golang.org/genproto v0.0.0-20201201144952-b05cb90ed32e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= 561 | google.golang.org/genproto v0.0.0-20201210142538-e3217bee35cc/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= 562 | google.golang.org/genproto v0.0.0-20201214200347-8c77b98c765d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= 563 | google.golang.org/genproto v0.0.0-20210222152913-aa3ee6e6a81c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= 564 | google.golang.org/genproto v0.0.0-20210303154014-9728d6b83eeb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= 565 | google.golang.org/genproto v0.0.0-20210310155132-4ce2db91004e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= 566 | google.golang.org/genproto v0.0.0-20210319143718-93e7006c17a6/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= 567 | google.golang.org/genproto v0.0.0-20210402141018-6c239bbf2bb1/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A= 568 | google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= 569 | google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= 570 | google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= 571 | google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= 572 | google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= 573 | google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= 574 | google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= 575 | google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= 576 | google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= 577 | google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60= 578 | google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= 579 | google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= 580 | google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= 581 | google.golang.org/grpc v1.31.1/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= 582 | google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0= 583 | google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= 584 | google.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA51WJ8= 585 | google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= 586 | google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= 587 | google.golang.org/grpc v1.36.1/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= 588 | google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= 589 | google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= 590 | google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= 591 | google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= 592 | google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= 593 | google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= 594 | google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= 595 | google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= 596 | google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= 597 | google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4= 598 | google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= 599 | google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= 600 | google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= 601 | gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= 602 | gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= 603 | gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= 604 | gopkg.in/ini.v1 v1.62.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= 605 | gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= 606 | gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= 607 | gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= 608 | gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= 609 | gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 610 | gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo= 611 | gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 612 | honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= 613 | honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= 614 | honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= 615 | honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= 616 | honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= 617 | honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= 618 | honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= 619 | rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= 620 | rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= 621 | rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= 622 | --------------------------------------------------------------------------------