├── .gitignore ├── README.md ├── main_test.go ├── Makefile ├── .github └── workflows │ └── release.yml ├── go.mod ├── main.go └── go.sum /.gitignore: -------------------------------------------------------------------------------- 1 | .idea 2 | /dist 3 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # go-unpkg-downloader 2 | 3 | unpkg.com 批量下载工具,[releases](https://github.com/TMaize/go-unpkg-downloader/releases) 4 | 5 | ``` 6 | unpkg download tool 7 | 8 | Usage: 9 | go-unpkg-downloader pkg [flags] 10 | 11 | Flags: 12 | -d, --dist string download save path (default "./dist") 13 | -h, --help help for go-unpkg-downloader 14 | 15 | ``` 16 | 17 | ```sh 18 | go-unpkg-downloader vue 19 | go-unpkg-downloader vue@2.6.11 20 | go-unpkg-downloader vue@2.6.11/types 21 | go-unpkg-downloader https://unpkg.com/browse/vue@2.6.11/types/ 22 | go-unpkg-downloader @koa/router 23 | go-unpkg-downloader https://unpkg.com/@koa/router@10.1.1/package.json 24 | ``` 25 | -------------------------------------------------------------------------------- /main_test.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "testing" 6 | ) 7 | 8 | func TestGetStdUrl(t *testing.T) { 9 | fmt.Println(GetStdUrl("vue")) 10 | fmt.Println(GetStdUrl("vue@2.6.14")) 11 | fmt.Println(GetStdUrl("vue@2.6.11/types")) 12 | fmt.Println(GetStdUrl("https://unpkg.com/browse/vue@2.6.11/types/")) 13 | 14 | fmt.Println(GetStdUrl("@koa/router")) 15 | fmt.Println(GetStdUrl("https://unpkg.com/@koa/router@10.1.1/package.json")) 16 | } 17 | 18 | func TestParsePage(t *testing.T) { 19 | data := ParsePage("https://unpkg.com/browse/vue@2.6.11/types/") 20 | fmt.Println(data.PackageName, data.PackageVersion, data.FileName, data.isFile()) 21 | 22 | data = ParsePage("https://unpkg.com/browse/@koa/router@10.1.1/package.json") 23 | fmt.Println(data.PackageName, data.PackageVersion, data.FileName, data.isFile()) 24 | } 25 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | .PHONY: build clean win linux mac mac2 2 | 3 | DIST=go-unpkg-downloader 4 | 5 | build: clean win linux mac mac2 6 | clean: 7 | rm -rf dist 8 | mkdir -p dist 9 | win: 10 | GOOS=windows GOARCH=amd64 go build -o ./dist/$(DIST).exe main.go 11 | cd dist && 7z a -sdel $(DIST)-win32-x64.zip $(DIST).exe 12 | linux: 13 | GOOS=linux GOARCH=amd64 go build -o ./dist/$(DIST) main.go 14 | cd dist && 7z a -sdel $(DIST)-linux-x64.tar $(DIST) 15 | cd dist && 7z a -sdel $(DIST)-linux-x64.tar.gz $(DIST)-linux-x64.tar 16 | mac: 17 | GOOS=darwin GOARCH=amd64 go build -o ./dist/$(DIST) main.go 18 | cd dist && 7z a -sdel $(DIST)-darwin-x64.tar $(DIST) 19 | cd dist && 7z a -sdel $(DIST)-darwin-x64.tar.gz $(DIST)-darwin-x64.tar 20 | mac2: 21 | GOOS=darwin GOARCH=arm64 go build -o ./dist/$(DIST) main.go 22 | cd dist && 7z a -sdel $(DIST)-darwin-arm64.tar $(DIST) 23 | cd dist && 7z a -sdel $(DIST)-darwin-arm64.tar.gz $(DIST)-darwin-arm64.tar 24 | -------------------------------------------------------------------------------- /.github/workflows/release.yml: -------------------------------------------------------------------------------- 1 | name: Release 2 | 3 | on: 4 | push: 5 | tags: 6 | - 'v*' 7 | 8 | jobs: 9 | 10 | build: 11 | runs-on: ubuntu-latest 12 | steps: 13 | - uses: actions/checkout@v3 14 | with: 15 | ref: ${{ github.ref }} 16 | 17 | - name: Set up Go 18 | uses: actions/setup-go@v3 19 | with: 20 | go-version: 1.18 21 | 22 | - name: env 23 | run: | 24 | env 25 | echo ------- 26 | echo ${{ github.ref }} 27 | echo ------- 28 | echo ${{ github.ref_name }} 29 | 30 | - name: Build 31 | run: make 32 | 33 | - name: Create Release 34 | uses: softprops/action-gh-release@v1 35 | with: 36 | token: ${{ secrets.GITHUB_TOKEN }} # settings/Actions/General (Read and write permissions) 37 | files: | 38 | dist/go-unpkg-downloader-darwin-arm64.tar.gz 39 | dist/go-unpkg-downloader-darwin-x64.tar.gz 40 | dist/go-unpkg-downloader-linux-x64.tar.gz 41 | dist/go-unpkg-downloader-win32-x64.zip 42 | -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module go-unpkg-downloader 2 | 3 | go 1.18 4 | 5 | require ( 6 | github.com/guonaihong/gout v0.3.7 7 | github.com/spf13/cobra v1.7.0 8 | ) 9 | 10 | require ( 11 | github.com/andybalholm/brotli v1.0.5 // indirect 12 | github.com/bytedance/sonic v1.9.1 // indirect 13 | github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 // indirect 14 | github.com/gabriel-vasile/mimetype v1.4.2 // indirect 15 | github.com/go-playground/locales v0.14.1 // indirect 16 | github.com/go-playground/universal-translator v0.18.1 // indirect 17 | github.com/go-playground/validator/v10 v10.14.1 // indirect 18 | github.com/goccy/go-json v0.10.2 // indirect 19 | github.com/inconshreveable/mousetrap v1.1.0 // indirect 20 | github.com/json-iterator/go v1.1.12 // indirect 21 | github.com/klauspost/cpuid/v2 v2.2.5 // indirect 22 | github.com/leodido/go-urn v1.2.4 // indirect 23 | github.com/mattn/go-isatty v0.0.19 // indirect 24 | github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect 25 | github.com/modern-go/reflect2 v1.0.2 // indirect 26 | github.com/pkg/errors v0.9.1 // indirect 27 | github.com/spf13/pflag v1.0.5 // indirect 28 | github.com/twitchyliquid64/golang-asm v0.15.1 // indirect 29 | golang.org/x/arch v0.3.0 // indirect 30 | golang.org/x/crypto v0.9.0 // indirect 31 | golang.org/x/net v0.10.0 // indirect 32 | golang.org/x/sys v0.8.0 // indirect 33 | golang.org/x/text v0.9.0 // indirect 34 | google.golang.org/protobuf v1.30.0 // indirect 35 | gopkg.in/yaml.v2 v2.4.0 // indirect 36 | ) 37 | -------------------------------------------------------------------------------- /main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "encoding/json" 5 | "errors" 6 | "fmt" 7 | "github.com/guonaihong/gout" 8 | "github.com/spf13/cobra" 9 | "io/ioutil" 10 | "net/url" 11 | "os" 12 | "path/filepath" 13 | "regexp" 14 | "sort" 15 | "strings" 16 | ) 17 | 18 | type PageData struct { 19 | FileName string `json:"filename"` 20 | PackageName string `json:"packageName"` 21 | PackageVersion string `json:"packageVersion"` 22 | Target Target `json:"target"` 23 | } 24 | 25 | type Target struct { 26 | Path string `json:"path"` 27 | Type string `json:"type"` 28 | Details map[string]interface{} `json:"details"` 29 | } 30 | 31 | func (data PageData) isFile() bool { 32 | return data.Target.Type == "file" 33 | } 34 | 35 | func (data PageData) getBrowseUrl() string { 36 | return "https://unpkg.com/browse/" + data.PackageName + "@" + data.PackageVersion + data.FileName 37 | } 38 | 39 | func (data PageData) getDownloadUrl() string { 40 | return "https://unpkg.com/" + data.PackageName + "@" + data.PackageVersion + data.FileName 41 | } 42 | 43 | func (data PageData) getChildren() []PageData { 44 | list := make([]PageData, 0) 45 | if data.Target.Details == nil { 46 | return list 47 | } 48 | keys := make([]string, 0) 49 | sort.Strings(keys) 50 | for key := range data.Target.Details { 51 | keys = append(keys, key) 52 | } 53 | 54 | for _, key := range keys { 55 | 56 | var item = data.Target.Details[key].(map[string]interface{}) 57 | var fileType = item["type"].(string) 58 | var filePath = item["path"].(string) 59 | var fileName = item["path"].(string) 60 | if fileType == "directory" { 61 | fileName = fileName + "/" 62 | } 63 | list = append(list, PageData{ 64 | FileName: fileName, 65 | PackageName: data.PackageName, 66 | PackageVersion: data.PackageVersion, 67 | Target: Target{Path: filePath, Type: fileType, Details: nil}, 68 | }) 69 | } 70 | return list 71 | } 72 | 73 | //--------------------------------------------- 74 | 75 | func ParsePage(url string) PageData { 76 | html := "" 77 | var code int 78 | pageData := PageData{} 79 | err := gout.GET(url).BindBody(&html).Code(&code).Do() 80 | if err != nil { 81 | panic(err) 82 | } 83 | jsonRule := regexp.MustCompile(`window.__DATA__ =(.+?)`) 84 | result := jsonRule.FindAllStringSubmatch(html, 1) 85 | if len(result) != 1 || len(result[0]) != 2 { 86 | panic("not found __DATA__ at " + url) 87 | } 88 | err = json.Unmarshal([]byte(result[0][1]), &pageData) 89 | if err != nil { 90 | panic("unmarshal __DATA__ error") 91 | } 92 | return pageData 93 | } 94 | 95 | func DownloadDir(browseUrl, dest string) { 96 | data := ParsePage(browseUrl) 97 | children := data.getChildren() 98 | for _, item := range children { 99 | if item.isFile() { 100 | DownloadFile(item.getDownloadUrl(), dest) 101 | } else { 102 | DownloadDir(item.getBrowseUrl(), dest) 103 | } 104 | } 105 | } 106 | 107 | func DownloadFile(downloadUrl, dest string) { 108 | parse, err := url.Parse(downloadUrl) 109 | if err != nil { 110 | panic(err) 111 | } 112 | dest, err = filepath.Abs(dest) 113 | if err != nil { 114 | panic(err) 115 | } 116 | savePath := filepath.Join(dest, parse.Path) 117 | 118 | fmt.Printf("%s\n%s\n\n", downloadUrl, strings.ReplaceAll(savePath, "\\", "/")) 119 | 120 | raw := make([]byte, 0) 121 | var code int 122 | err = gout.GET(downloadUrl).BindBody(&raw).Code(&code).Do() 123 | if err != nil { 124 | panic(err) 125 | } 126 | if code != 200 { 127 | panic(fmt.Sprint(code, "error", downloadUrl)) 128 | } 129 | 130 | _, err = os.Stat(filepath.Join(savePath, "..")) 131 | if err != nil { 132 | err = os.MkdirAll(filepath.Join(savePath, ".."), os.ModePerm) 133 | if err != nil { 134 | panic(err) 135 | } 136 | } 137 | err = ioutil.WriteFile(savePath, raw, 0766) 138 | if err != nil { 139 | panic(err) 140 | } 141 | } 142 | 143 | func GetStdUrl(pkg string) string { 144 | pkg = strings.Replace(pkg, "http:", "", 1) 145 | pkg = strings.Replace(pkg, "https:", "", 1) 146 | pkg = strings.Replace(pkg, "unpkg.com/browse", "", 1) 147 | pkg = strings.Replace(pkg, "unpkg.com", "", 1) 148 | reg := regexp.MustCompile("/{2,}") 149 | pkg = string(reg.ReplaceAll([]byte(pkg), []byte("/"))) 150 | if strings.HasPrefix(pkg, "/") { 151 | pkg = pkg[1:] 152 | } 153 | 154 | browseUrl := "https://unpkg.com/browse/" + pkg 155 | 156 | var statusCode int 157 | err := gout.HEAD(browseUrl).Code(&statusCode).Do() 158 | if err != nil { 159 | panic(err) 160 | } 161 | 162 | if statusCode != 200 && !strings.HasSuffix(browseUrl, "/") { 163 | browseUrl = browseUrl + "/" 164 | err = gout.HEAD(browseUrl).Code(&statusCode).Do() 165 | if err != nil { 166 | panic(err) 167 | } 168 | 169 | if statusCode != 200 { 170 | panic(fmt.Sprintf("can't access %s %d", browseUrl, statusCode)) 171 | } 172 | } 173 | return browseUrl 174 | } 175 | 176 | func main() { 177 | var dist = "./dist" 178 | 179 | command := &cobra.Command{ 180 | Use: "go-unpkg-downloader pkg [flags]", 181 | Short: "unpkg download tool", 182 | Args: func(cmd *cobra.Command, args []string) error { 183 | if len(args) == 0 { 184 | return errors.New("require pkg address") 185 | } 186 | return nil 187 | }, 188 | Run: func(cmd *cobra.Command, args []string) { 189 | pkg := args[0] 190 | data := ParsePage(GetStdUrl(pkg)) 191 | 192 | fmt.Printf("%s@%s\n\n", data.PackageName, data.PackageVersion) 193 | 194 | if data.isFile() { 195 | DownloadFile(data.getDownloadUrl(), dist) 196 | } else { 197 | DownloadDir(data.getBrowseUrl(), dist) 198 | } 199 | }, 200 | } 201 | command.Flags().StringVarP(&dist, "dist", "d", dist, "download save path") 202 | 203 | if err := command.Execute(); err != nil { 204 | fmt.Println(err) 205 | os.Exit(1) 206 | } 207 | } 208 | -------------------------------------------------------------------------------- /go.sum: -------------------------------------------------------------------------------- 1 | github.com/andybalholm/brotli v1.0.5 h1:8uQZIdzKmjc/iuPu7O2ioW48L81FgatrcpfFmiq/cCs= 2 | github.com/andybalholm/brotli v1.0.5/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig= 3 | github.com/bytedance/sonic v1.5.0/go.mod h1:ED5hyg4y6t3/9Ku1R6dU/4KyJ48DZ4jPhfY1O2AihPM= 4 | github.com/bytedance/sonic v1.9.1 h1:6iJ6NqdoxCDr6mbY8h18oSO+cShGSMRGCEo7F2h0x8s= 5 | github.com/bytedance/sonic v1.9.1/go.mod h1:i736AoUSYt75HyZLoJW9ERYxcy6eaN6h4BZXU064P/U= 6 | github.com/chenzhuoyu/base64x v0.0.0-20211019084208-fb5309c8db06/go.mod h1:DH46F32mSOjUmXrMHnKwZdA8wcEefY7UVqBKYGjpdQY= 7 | github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 h1:qSGYFH7+jGhDF8vLC+iwCD4WpbV1EBDSzWkJODFLams= 8 | github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311/go.mod h1:b583jCggY9gE99b6G5LEC39OIiVsWj+R97kbl5odCEk= 9 | github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= 10 | github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 11 | github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= 12 | github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 13 | github.com/gabriel-vasile/mimetype v1.4.2 h1:w5qFW6JKBz9Y393Y4q372O9A7cUSequkh1Q7OhCmWKU= 14 | github.com/gabriel-vasile/mimetype v1.4.2/go.mod h1:zApsH/mKG4w07erKIaJPFiX0Tsq9BFQgN3qGY5GnNgA= 15 | github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE= 16 | github.com/gin-gonic/gin v1.7.7 h1:3DoBmSbJbZAWqXJC3SLjAPfutPJJRN1U5pALB7EeTTs= 17 | github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s= 18 | github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA= 19 | github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY= 20 | github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY= 21 | github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY= 22 | github.com/go-playground/validator/v10 v10.14.1 h1:9c50NUPC30zyuKprjL3vNZ0m5oG+jU0zvx4AqHGnv4k= 23 | github.com/go-playground/validator/v10 v10.14.1/go.mod h1:9iXMNT7sEkjXb0I+enO7QXmzG6QCsPWY4zveKFVRSyU= 24 | github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU= 25 | github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= 26 | github.com/golang/protobuf v1.5.0 h1:LUVKkCeviFUMKqHa4tXIIij/lbhnMbP7Fn5wKdKkRh4= 27 | github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= 28 | github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU= 29 | github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= 30 | github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= 31 | github.com/google/uuid v1.1.1 h1:Gkbcsh/GbpXz7lPftLA3P6TYMwjCLYm83jiFQZF/3gY= 32 | github.com/guonaihong/gout v0.3.7 h1:4UTlvelmdLUZjkIqyBDmXS8Fl90wZ6TNqRQRHIAgN7E= 33 | github.com/guonaihong/gout v0.3.7/go.mod h1:wDXeuyeZR6MtaHbytO9RLcKW4iCDrWD6/KF1QwDtbRc= 34 | github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= 35 | github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= 36 | github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= 37 | github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= 38 | github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= 39 | github.com/klauspost/cpuid/v2 v2.2.5 h1:0E5MSMDEoAulmXNFquVs//DdoomxaoTY1kUhbc/qbZg= 40 | github.com/klauspost/cpuid/v2 v2.2.5/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws= 41 | github.com/leodido/go-urn v1.2.4 h1:XlAE/cm/ms7TE/VMVoduSpNBoyc2dOxHs5MZSwAN63Q= 42 | github.com/leodido/go-urn v1.2.4/go.mod h1:7ZrI8mTSeBSHl/UaRyKQW1qZeMgak41ANeCNaVckg+4= 43 | github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA= 44 | github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= 45 | github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= 46 | github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= 47 | github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= 48 | github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= 49 | github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= 50 | github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= 51 | github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= 52 | github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= 53 | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= 54 | github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= 55 | github.com/spf13/cobra v1.7.0 h1:hyqWnYt1ZQShIddO5kBpj3vu05/++x6tJ6dg8EC572I= 56 | github.com/spf13/cobra v1.7.0/go.mod h1:uLxZILRyS/50WlhOIKD7W6V5bgeIt+4sICxh6uRMrb0= 57 | github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= 58 | github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= 59 | github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= 60 | github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= 61 | github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= 62 | github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= 63 | github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= 64 | github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= 65 | github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= 66 | github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= 67 | github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8= 68 | github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= 69 | github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI= 70 | github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08= 71 | github.com/ugorji/go/codec v1.1.7 h1:2SvQaVZ1ouYrrKKwoSk2pzd4A9evlKJb9oTL+OaLUSs= 72 | golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8= 73 | golang.org/x/arch v0.3.0 h1:02VY4/ZcO/gBOH6PUaoiptASxtXU10jazRCP865E97k= 74 | golang.org/x/arch v0.3.0/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8= 75 | golang.org/x/crypto v0.9.0 h1:LF6fAI+IutBocDJ2OT0Q1g8plpYljMZ4+lty+dsqw3g= 76 | golang.org/x/crypto v0.9.0/go.mod h1:yrmDGqONDYtNj3tH8X9dzUun2m2lzPa9ngI6/RUPGR0= 77 | golang.org/x/net v0.10.0 h1:X2//UzNDwYmtCLn7To6G58Wr6f5ahEAQgKNzv9Y951M= 78 | golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= 79 | golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 80 | golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 81 | golang.org/x/sys v0.8.0 h1:EBmGv8NaZBZTWvrbjNoL6HVt+IVy3QDQpJs7VRIw3tU= 82 | golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 83 | golang.org/x/text v0.9.0 h1:2sjJmO8cDvYveuX97RDLsxlyUxLl+GHoLxBiRdHllBE= 84 | golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= 85 | golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4= 86 | golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= 87 | google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= 88 | google.golang.org/protobuf v1.30.0 h1:kPPoIgf3TsEvrm0PFe15JQ+570QVxYzEvvHqChK+cng= 89 | google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= 90 | gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= 91 | gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= 92 | gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= 93 | gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= 94 | gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 95 | gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= 96 | gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 97 | rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4= 98 | --------------------------------------------------------------------------------