mirror of https://github.com/Xhofe/alist
				
				
				
			feat: add doge driver (#6201)
* feat: add doge driver * doc: 补充readme文档 * fix: 对齐meta信息 * fix: 调整结构体名字,与driver保持一致 * perf: merge to s3 * Rename goge.go to doge.go --------- Co-authored-by: Andy Hsu <i@nn.ci>pull/5315/head v3.33.0
							parent
							
								
									9c84b6596f
								
							
						
					
					
						commit
						cf08aa3668
					
				| 
						 | 
				
			
			@ -0,0 +1,44 @@
 | 
			
		|||
root = "."
 | 
			
		||||
testdata_dir = "testdata"
 | 
			
		||||
tmp_dir = "tmp"
 | 
			
		||||
 | 
			
		||||
[build]
 | 
			
		||||
args_bin = ["server"]
 | 
			
		||||
bin = "./tmp/main"
 | 
			
		||||
cmd = "go build -o ./tmp/main ."
 | 
			
		||||
delay = 0
 | 
			
		||||
exclude_dir = ["assets", "tmp", "vendor", "testdata"]
 | 
			
		||||
exclude_file = []
 | 
			
		||||
exclude_regex = ["_test.go"]
 | 
			
		||||
exclude_unchanged = false
 | 
			
		||||
follow_symlink = false
 | 
			
		||||
full_bin = ""
 | 
			
		||||
include_dir = []
 | 
			
		||||
include_ext = ["go", "tpl", "tmpl", "html"]
 | 
			
		||||
include_file = []
 | 
			
		||||
kill_delay = "0s"
 | 
			
		||||
log = "build-errors.log"
 | 
			
		||||
poll = false
 | 
			
		||||
poll_interval = 0
 | 
			
		||||
rerun = false
 | 
			
		||||
rerun_delay = 500
 | 
			
		||||
send_interrupt = false
 | 
			
		||||
stop_on_error = false
 | 
			
		||||
 | 
			
		||||
[color]
 | 
			
		||||
app = ""
 | 
			
		||||
build = "yellow"
 | 
			
		||||
main = "magenta"
 | 
			
		||||
runner = "green"
 | 
			
		||||
watcher = "cyan"
 | 
			
		||||
 | 
			
		||||
[log]
 | 
			
		||||
main_only = false
 | 
			
		||||
time = false
 | 
			
		||||
 | 
			
		||||
[misc]
 | 
			
		||||
clean_on_exit = false
 | 
			
		||||
 | 
			
		||||
[screen]
 | 
			
		||||
clear_on_rebuild = false
 | 
			
		||||
keep_scroll = true
 | 
			
		||||
| 
						 | 
				
			
			@ -24,6 +24,7 @@ output/
 | 
			
		|||
*.json
 | 
			
		||||
/build
 | 
			
		||||
/data/
 | 
			
		||||
/tmp/
 | 
			
		||||
/log/
 | 
			
		||||
/lang/
 | 
			
		||||
/daemon/
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -76,6 +76,7 @@ English | [中文](./README_cn.md)| [日本語](./README_ja.md) | [Contributing]
 | 
			
		|||
    - [X] Cloudreve
 | 
			
		||||
    - [x] [Dropbox](https://www.dropbox.com/)
 | 
			
		||||
    - [x] [FeijiPan](https://www.feijipan.com/)
 | 
			
		||||
    - [x] [dogecloud](https://www.dogecloud.com/product/oss)
 | 
			
		||||
- [x] Easy to deploy and out-of-the-box
 | 
			
		||||
- [x] File preview (PDF, markdown, code, plain text, ...)
 | 
			
		||||
- [x] Image preview in gallery mode
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -75,6 +75,7 @@
 | 
			
		|||
    - [X] Cloudreve
 | 
			
		||||
    - [x] [Dropbox](https://www.dropbox.com/)
 | 
			
		||||
    - [x] [飞机盘](https://www.feijipan.com/)
 | 
			
		||||
    - [x] [多吉云](https://www.dogecloud.com/product/oss)
 | 
			
		||||
- [x] 部署方便,开箱即用
 | 
			
		||||
- [x] 文件预览(PDF、markdown、代码、纯文本……)
 | 
			
		||||
- [x] 画廊模式下的图像预览
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -76,6 +76,7 @@
 | 
			
		|||
    - [X] Cloudreve
 | 
			
		||||
    - [x] [Dropbox](https://www.dropbox.com/)
 | 
			
		||||
    - [x] [FeijiPan](https://www.feijipan.com/)
 | 
			
		||||
    - [x] [dogecloud](https://www.dogecloud.com/product/oss)
 | 
			
		||||
- [x] デプロイが簡単で、すぐに使える
 | 
			
		||||
- [x] ファイルプレビュー (PDF, マークダウン, コード, プレーンテキスト, ...)
 | 
			
		||||
- [x] ギャラリーモードでの画像プレビュー
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -0,0 +1,62 @@
 | 
			
		|||
package s3
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"crypto/hmac"
 | 
			
		||||
	"crypto/sha1"
 | 
			
		||||
	"encoding/hex"
 | 
			
		||||
	"encoding/json"
 | 
			
		||||
	"io"
 | 
			
		||||
	"net/http"
 | 
			
		||||
	"strings"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type TmpTokenResponse struct {
 | 
			
		||||
	Code int                  `json:"code"`
 | 
			
		||||
	Msg  string               `json:"msg"`
 | 
			
		||||
	Data TmpTokenResponseData `json:"data,omitempty"`
 | 
			
		||||
}
 | 
			
		||||
type TmpTokenResponseData struct {
 | 
			
		||||
	Credentials Credentials `json:"Credentials"`
 | 
			
		||||
}
 | 
			
		||||
type Credentials struct {
 | 
			
		||||
	AccessKeyId     string `json:"accessKeyId,omitempty"`
 | 
			
		||||
	SecretAccessKey string `json:"secretAccessKey,omitempty"`
 | 
			
		||||
	SessionToken    string `json:"sessionToken,omitempty"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func getCredentials(AccessKey, SecretKey string) (rst Credentials, err error) {
 | 
			
		||||
	apiPath := "/auth/tmp_token.json"
 | 
			
		||||
	reqBody, err := json.Marshal(map[string]interface{}{"channel": "OSS_FULL", "scopes": []string{"*"}})
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return rst, err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	signStr := apiPath + "\n" + string(reqBody)
 | 
			
		||||
	hmacObj := hmac.New(sha1.New, []byte(SecretKey))
 | 
			
		||||
	hmacObj.Write([]byte(signStr))
 | 
			
		||||
	sign := hex.EncodeToString(hmacObj.Sum(nil))
 | 
			
		||||
	Authorization := "TOKEN " + AccessKey + ":" + sign
 | 
			
		||||
 | 
			
		||||
	req, err := http.NewRequest("POST", "https://api.dogecloud.com"+apiPath, strings.NewReader(string(reqBody)))
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return rst, err
 | 
			
		||||
	}
 | 
			
		||||
	req.Header.Add("Content-Type", "application/json")
 | 
			
		||||
	req.Header.Add("Authorization", Authorization)
 | 
			
		||||
	client := http.Client{}
 | 
			
		||||
	resp, err := client.Do(req)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return rst, err
 | 
			
		||||
	}
 | 
			
		||||
	defer resp.Body.Close()
 | 
			
		||||
	ret, err := io.ReadAll(resp.Body)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return rst, err
 | 
			
		||||
	}
 | 
			
		||||
	var tmpTokenResp TmpTokenResponse
 | 
			
		||||
	err = json.Unmarshal(ret, &tmpTokenResp)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return rst, err
 | 
			
		||||
	}
 | 
			
		||||
	return tmpTokenResp.Data.Credentials, nil
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -26,10 +26,12 @@ type S3 struct {
 | 
			
		|||
	Session    *session.Session
 | 
			
		||||
	client     *s3.S3
 | 
			
		||||
	linkClient *s3.S3
 | 
			
		||||
 | 
			
		||||
	config driver.Config
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (d *S3) Config() driver.Config {
 | 
			
		||||
	return config
 | 
			
		||||
	return d.config
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (d *S3) GetAddition() driver.Additional {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -22,15 +22,25 @@ type Addition struct {
 | 
			
		|||
	AddFilenameToDisposition bool   `json:"add_filename_to_disposition" help:"Add filename to Content-Disposition header."`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
var config = driver.Config{
 | 
			
		||||
	Name:        "S3",
 | 
			
		||||
	DefaultRoot: "/",
 | 
			
		||||
	LocalSort:   true,
 | 
			
		||||
	CheckStatus: true,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func init() {
 | 
			
		||||
	op.RegisterDriver(func() driver.Driver {
 | 
			
		||||
		return &S3{}
 | 
			
		||||
		return &S3{
 | 
			
		||||
			config: driver.Config{
 | 
			
		||||
				Name:        "S3",
 | 
			
		||||
				DefaultRoot: "/",
 | 
			
		||||
				LocalSort:   true,
 | 
			
		||||
				CheckStatus: true,
 | 
			
		||||
			},
 | 
			
		||||
		}
 | 
			
		||||
	})
 | 
			
		||||
	op.RegisterDriver(func() driver.Driver {
 | 
			
		||||
		return &S3{
 | 
			
		||||
			config: driver.Config{
 | 
			
		||||
				Name:        "Doge",
 | 
			
		||||
				DefaultRoot: "/",
 | 
			
		||||
				LocalSort:   true,
 | 
			
		||||
				CheckStatus: true,
 | 
			
		||||
			},
 | 
			
		||||
		}
 | 
			
		||||
	})
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -21,13 +21,21 @@ import (
 | 
			
		|||
// do others that not defined in Driver interface
 | 
			
		||||
 | 
			
		||||
func (d *S3) initSession() error {
 | 
			
		||||
	var err error
 | 
			
		||||
	accessKeyID, secretAccessKey, sessionToken := d.AccessKeyID, d.SecretAccessKey, d.SessionToken
 | 
			
		||||
	if d.config.Name == "Doge" {
 | 
			
		||||
		credentialsTmp, err := getCredentials(d.AccessKeyID, d.SecretAccessKey)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return err
 | 
			
		||||
		}
 | 
			
		||||
		accessKeyID, secretAccessKey, sessionToken = credentialsTmp.AccessKeyId, credentialsTmp.SecretAccessKey, credentialsTmp.SessionToken
 | 
			
		||||
	}
 | 
			
		||||
	cfg := &aws.Config{
 | 
			
		||||
		Credentials:      credentials.NewStaticCredentials(d.AccessKeyID, d.SecretAccessKey, d.SessionToken),
 | 
			
		||||
		Credentials:      credentials.NewStaticCredentials(accessKeyID, secretAccessKey, sessionToken),
 | 
			
		||||
		Region:           &d.Region,
 | 
			
		||||
		Endpoint:         &d.Endpoint,
 | 
			
		||||
		S3ForcePathStyle: aws.Bool(d.ForcePathStyle),
 | 
			
		||||
	}
 | 
			
		||||
	var err error
 | 
			
		||||
	d.Session, err = session.NewSession(cfg)
 | 
			
		||||
	return err
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										16
									
								
								go.sum
								
								
								
								
							
							
						
						
									
										16
									
								
								go.sum
								
								
								
								
							| 
						 | 
				
			
			@ -447,8 +447,6 @@ github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o
 | 
			
		|||
github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
 | 
			
		||||
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
 | 
			
		||||
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
 | 
			
		||||
github.com/t3rm1n4l/go-mega v0.0.0-20230228171823-a01a2cda13ca h1:I9rVnNXdIkij4UvMT7OmKhH9sOIvS8iXkxfPdnn9wQA=
 | 
			
		||||
github.com/t3rm1n4l/go-mega v0.0.0-20230228171823-a01a2cda13ca/go.mod h1:suDIky6yrK07NnaBadCB4sS0CqFOvUK91lH7CR+JlDA=
 | 
			
		||||
github.com/t3rm1n4l/go-mega v0.0.0-20240219080617-d494b6a8ace7 h1:Jtcrb09q0AVWe3BGe8qtuuGxNSHWGkTWr43kHTJ+CpA=
 | 
			
		||||
github.com/t3rm1n4l/go-mega v0.0.0-20240219080617-d494b6a8ace7/go.mod h1:suDIky6yrK07NnaBadCB4sS0CqFOvUK91lH7CR+JlDA=
 | 
			
		||||
github.com/tklauser/go-sysconf v0.3.11 h1:89WgdJhk5SNwJfu+GKyYveZ4IaJ7xAkecBo+KdJV0CM=
 | 
			
		||||
| 
						 | 
				
			
			@ -507,12 +505,8 @@ golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0
 | 
			
		|||
golang.org/x/crypto v0.1.0/go.mod h1:RecgLatLF4+eUMCP1PoPZQb+cVrJcOPbHkTkbkB9sbw=
 | 
			
		||||
golang.org/x/crypto v0.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58=
 | 
			
		||||
golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4=
 | 
			
		||||
golang.org/x/crypto v0.18.0 h1:PGVlW0xEltQnzFZ55hkuX5+KLyrMYhHld1YHO4AKcdc=
 | 
			
		||||
golang.org/x/crypto v0.18.0/go.mod h1:R0j02AL6hcrfOiy9T4ZYp/rcWeMxM3L6QYxlOuEG1mg=
 | 
			
		||||
golang.org/x/crypto v0.19.0 h1:ENy+Az/9Y1vSrlrvBSyna3PITt4tiZLf7sgCjZBX7Wo=
 | 
			
		||||
golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU=
 | 
			
		||||
golang.org/x/exp v0.0.0-20240110193028-0dcbfd608b1e h1:723BNChdd0c2Wk6WOE320qGBiPtYx0F0Bbm1kriShfE=
 | 
			
		||||
golang.org/x/exp v0.0.0-20240110193028-0dcbfd608b1e/go.mod h1:iRJReGqOEeBhDZGkGbynYwcHlctCvnjTYIamk7uXpHI=
 | 
			
		||||
golang.org/x/exp v0.0.0-20240222234643-814bf88cf225 h1:LfspQV/FYTatPTr/3HzIcmiUFH7PGP+OQ6mgDYo3yuQ=
 | 
			
		||||
golang.org/x/exp v0.0.0-20240222234643-814bf88cf225/go.mod h1:CxmFvTBINI24O/j8iY7H1xHzx2i4OsyguNBmN/uPtqc=
 | 
			
		||||
golang.org/x/image v0.0.0-20191009234506-e7c1f5e7dbb8/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
 | 
			
		||||
| 
						 | 
				
			
			@ -532,8 +526,6 @@ golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco=
 | 
			
		|||
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
 | 
			
		||||
golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
 | 
			
		||||
golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE=
 | 
			
		||||
golang.org/x/net v0.20.0 h1:aCL9BSgETF1k+blQaYUBx9hJ9LOGP3gAVemcZlf1Kpo=
 | 
			
		||||
golang.org/x/net v0.20.0/go.mod h1:z8BVo6PvndSri0LbOE3hAn0apkU+1YvI6E70E9jsnvY=
 | 
			
		||||
golang.org/x/net v0.21.0 h1:AQyQV4dYCvJ7vGmJyKki9+PBdyvhkSd8EIx/qb0AYv4=
 | 
			
		||||
golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44=
 | 
			
		||||
golang.org/x/oauth2 v0.16.0 h1:aDkGMBSYxElaoP81NpoUoz2oo2R2wHdZpGToUxfyQrQ=
 | 
			
		||||
| 
						 | 
				
			
			@ -542,8 +534,6 @@ golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJ
 | 
			
		|||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 | 
			
		||||
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 | 
			
		||||
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 | 
			
		||||
golang.org/x/sync v0.5.0 h1:60k92dhOjHxJkrqnwsfl8KuaHbn/5dl0lUPUklKo3qE=
 | 
			
		||||
golang.org/x/sync v0.5.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
 | 
			
		||||
golang.org/x/sync v0.6.0 h1:5BMeUDZ7vkXGfEr1x9B4bRcTH4lpkTkpdh0T/J+qjbQ=
 | 
			
		||||
golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
 | 
			
		||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 | 
			
		||||
| 
						 | 
				
			
			@ -573,8 +563,6 @@ golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 | 
			
		|||
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 | 
			
		||||
golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 | 
			
		||||
golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 | 
			
		||||
golang.org/x/sys v0.16.0 h1:xWw16ngr6ZMtmxDyKyIgsE93KNKz5HKmMa3b8ALHidU=
 | 
			
		||||
golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
 | 
			
		||||
golang.org/x/sys v0.17.0 h1:25cE3gD+tdBA7lp7QfhuV+rJiE9YXTcS3VG1SqssI/Y=
 | 
			
		||||
golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
 | 
			
		||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
 | 
			
		||||
| 
						 | 
				
			
			@ -583,8 +571,6 @@ golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
 | 
			
		|||
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
 | 
			
		||||
golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=
 | 
			
		||||
golang.org/x/term v0.13.0/go.mod h1:LTmsnFJwVN6bCy1rVCoS+qHT1HhALEFxKncY3WNNh4U=
 | 
			
		||||
golang.org/x/term v0.16.0 h1:m+B6fahuftsE9qjo0VWp2FW0mB3MTJvR0BaMQrq0pmE=
 | 
			
		||||
golang.org/x/term v0.16.0/go.mod h1:yn7UURbUtPyrVJPGPq404EukNFxcm/foM+bV/bfcDsY=
 | 
			
		||||
golang.org/x/term v0.17.0 h1:mkTF7LCd6WGJNL3K1Ad7kwxNfYAW6a8a8QqtMblp/4U=
 | 
			
		||||
golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk=
 | 
			
		||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
 | 
			
		||||
| 
						 | 
				
			
			@ -610,8 +596,6 @@ golang.org/x/tools v0.0.0-20190829051458-42f498d34c4d/go.mod h1:b+2E5dAYhXwXZwtn
 | 
			
		|||
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
 | 
			
		||||
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
 | 
			
		||||
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
 | 
			
		||||
golang.org/x/tools v0.16.0 h1:GO788SKMRunPIBCXiQyo2AaexLstOrVhuAL5YwsckQM=
 | 
			
		||||
golang.org/x/tools v0.16.0/go.mod h1:kYVVN6I1mBNoB1OX+noeBjbRk4IUEPa7JJ+TJMEooJ0=
 | 
			
		||||
golang.org/x/tools v0.18.0 h1:k8NLag8AGHnn+PHbl7g43CtqZAwG60vZkLqgyZgIHgQ=
 | 
			
		||||
golang.org/x/tools v0.18.0/go.mod h1:GL7B4CwcLLeo59yx/9UWWuNOW1n3VZ4f5axWfML7Lcg=
 | 
			
		||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue