[
  {
    "path": ".bingo/.gitignore",
    "content": "\n# Ignore everything\n*\n\n# But not these files:\n!.gitignore\n!*.mod\n!*.sum\n!README.md\n!Variables.mk\n!variables.env\n\n*tmp.mod\n"
  },
  {
    "path": ".bingo/README.md",
    "content": "# Project Development Dependencies.\n\nThis is directory which stores Go modules with pinned buildable package that is used within this repository, managed by https://github.com/bwplotka/bingo.\n\n* Run `bingo get` to install all tools having each own module file in this directory.\n* Run `bingo get <tool>` to install <tool> that have own module file in this directory.\n* For Makefile: Make sure to put `include .bingo/Variables.mk` in your Makefile, then use $(<upper case tool name>) variable where <tool> is the .bingo/<tool>.mod.\n* For shell: Run `source .bingo/variables.env` to source all environment variable for each tool.\n* For go: Import `.bingo/variables.go` to for variable names.\n* See https://github.com/bwplotka/bingo or -h on how to add, remove or change binaries dependencies.\n\n## Requirements\n\n* Go 1.14+\n"
  },
  {
    "path": ".bingo/Variables.mk",
    "content": "# Auto generated binary variables helper managed by https://github.com/bwplotka/bingo v0.9. DO NOT EDIT.\n# All tools are designed to be build inside $GOBIN.\nBINGO_DIR := $(dir $(lastword $(MAKEFILE_LIST)))\nGOPATH ?= $(shell go env GOPATH)\nGOBIN  ?= $(firstword $(subst :, ,${GOPATH}))/bin\nGO     ?= $(shell which go)\n\n# Below generated variables ensure that every time a tool under each variable is invoked, the correct version\n# will be used; reinstalling only if needed.\n# For example for bingo variable:\n#\n# In your main Makefile (for non array binaries):\n#\n#include .bingo/Variables.mk # Assuming -dir was set to .bingo .\n#\n#command: $(BINGO)\n#\t@echo \"Running bingo\"\n#\t@$(BINGO) <flags/args..>\n#\nBINGO := $(GOBIN)/bingo-v0.9.0\n$(BINGO): $(BINGO_DIR)/bingo.mod\n\t@# Install binary/ries using Go 1.14+ build command. This is using bwplotka/bingo-controlled, separate go module with pinned dependencies.\n\t@echo \"(re)installing $(GOBIN)/bingo-v0.9.0\"\n\t@cd $(BINGO_DIR) && GOWORK=off $(GO) build -mod=mod -modfile=bingo.mod -o=$(GOBIN)/bingo-v0.9.0 \"github.com/bwplotka/bingo\"\n\nBUF := $(GOBIN)/buf-v1.55.1\n$(BUF): $(BINGO_DIR)/buf.mod\n\t@# Install binary/ries using Go 1.14+ build command. This is using bwplotka/bingo-controlled, separate go module with pinned dependencies.\n\t@echo \"(re)installing $(GOBIN)/buf-v1.55.1\"\n\t@cd $(BINGO_DIR) && GOWORK=off $(GO) build -mod=mod -modfile=buf.mod -o=$(GOBIN)/buf-v1.55.1 \"github.com/bufbuild/buf/cmd/buf\"\n\nCOPYRIGHT := $(GOBIN)/copyright-v0.0.0-20210326193628-425a09c04e05\n$(COPYRIGHT): $(BINGO_DIR)/copyright.mod\n\t@# Install binary/ries using Go 1.14+ build command. This is using bwplotka/bingo-controlled, separate go module with pinned dependencies.\n\t@echo \"(re)installing $(GOBIN)/copyright-v0.0.0-20210326193628-425a09c04e05\"\n\t@cd $(BINGO_DIR) && GOWORK=off $(GO) build -mod=mod -modfile=copyright.mod -o=$(GOBIN)/copyright-v0.0.0-20210326193628-425a09c04e05 \"github.com/efficientgo/tools/copyright\"\n\nGOIMPORTS := $(GOBIN)/goimports-v0.7.0\n$(GOIMPORTS): $(BINGO_DIR)/goimports.mod\n\t@# Install binary/ries using Go 1.14+ build command. This is using bwplotka/bingo-controlled, separate go module with pinned dependencies.\n\t@echo \"(re)installing $(GOBIN)/goimports-v0.7.0\"\n\t@cd $(BINGO_DIR) && GOWORK=off $(GO) build -mod=mod -modfile=goimports.mod -o=$(GOBIN)/goimports-v0.7.0 \"golang.org/x/tools/cmd/goimports\"\n\nGOLANGCI_LINT := $(GOBIN)/golangci-lint-v2.3.0\n$(GOLANGCI_LINT): $(BINGO_DIR)/golangci-lint.mod\n\t@# Install binary/ries using Go 1.14+ build command. This is using bwplotka/bingo-controlled, separate go module with pinned dependencies.\n\t@echo \"(re)installing $(GOBIN)/golangci-lint-v2.3.0\"\n\t@cd $(BINGO_DIR) && GOWORK=off $(GO) build -mod=mod -modfile=golangci-lint.mod -o=$(GOBIN)/golangci-lint-v2.3.0 \"github.com/golangci/golangci-lint/v2/cmd/golangci-lint\"\n\nMDOX := $(GOBIN)/mdox-v0.9.0\n$(MDOX): $(BINGO_DIR)/mdox.mod\n\t@# Install binary/ries using Go 1.14+ build command. This is using bwplotka/bingo-controlled, separate go module with pinned dependencies.\n\t@echo \"(re)installing $(GOBIN)/mdox-v0.9.0\"\n\t@cd $(BINGO_DIR) && GOWORK=off $(GO) build -mod=mod -modfile=mdox.mod -o=$(GOBIN)/mdox-v0.9.0 \"github.com/bwplotka/mdox\"\n\nMISSPELL := $(GOBIN)/misspell-v0.3.4\n$(MISSPELL): $(BINGO_DIR)/misspell.mod\n\t@# Install binary/ries using Go 1.14+ build command. This is using bwplotka/bingo-controlled, separate go module with pinned dependencies.\n\t@echo \"(re)installing $(GOBIN)/misspell-v0.3.4\"\n\t@cd $(BINGO_DIR) && GOWORK=off $(GO) build -mod=mod -modfile=misspell.mod -o=$(GOBIN)/misspell-v0.3.4 \"github.com/client9/misspell/cmd/misspell\"\n\nPROTOC_GEN_GO_GRPC := $(GOBIN)/protoc-gen-go-grpc-v1.5.1\n$(PROTOC_GEN_GO_GRPC): $(BINGO_DIR)/protoc-gen-go-grpc.mod\n\t@# Install binary/ries using Go 1.14+ build command. This is using bwplotka/bingo-controlled, separate go module with pinned dependencies.\n\t@echo \"(re)installing $(GOBIN)/protoc-gen-go-grpc-v1.5.1\"\n\t@cd $(BINGO_DIR) && GOWORK=off $(GO) build -mod=mod -modfile=protoc-gen-go-grpc.mod -o=$(GOBIN)/protoc-gen-go-grpc-v1.5.1 \"google.golang.org/grpc/cmd/protoc-gen-go-grpc\"\n\nPROTOC_GEN_GO := $(GOBIN)/protoc-gen-go-v1.36.6\n$(PROTOC_GEN_GO): $(BINGO_DIR)/protoc-gen-go.mod\n\t@# Install binary/ries using Go 1.14+ build command. This is using bwplotka/bingo-controlled, separate go module with pinned dependencies.\n\t@echo \"(re)installing $(GOBIN)/protoc-gen-go-v1.36.6\"\n\t@cd $(BINGO_DIR) && GOWORK=off $(GO) build -mod=mod -modfile=protoc-gen-go.mod -o=$(GOBIN)/protoc-gen-go-v1.36.6 \"google.golang.org/protobuf/cmd/protoc-gen-go\"\n\n"
  },
  {
    "path": ".bingo/bingo.mod",
    "content": "module _ // Auto generated by https://github.com/bwplotka/bingo. DO NOT EDIT\n\ngo 1.14\n\nrequire github.com/bwplotka/bingo v0.9.0\n"
  },
  {
    "path": ".bingo/bingo.sum",
    "content": "github.com/Masterminds/semver v1.5.0 h1:H65muMkzWKEuNDnfl9d70GUjFniHKHRbFPGBuZ3QEww=\ngithub.com/Masterminds/semver v1.5.0/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y=\ngithub.com/bwplotka/bingo v0.9.0 h1:slnsdJYExR4iRalHR6/ZiYnr9vSazOuFGmc2LdX293g=\ngithub.com/bwplotka/bingo v0.9.0/go.mod h1:GxC/y/xbmOK5P29cn+B3HuOSw0s2gruddT3r+rDizDw=\ngithub.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=\ngithub.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=\ngithub.com/creack/pty v1.1.18/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4=\ngithub.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=\ngithub.com/efficientgo/core v1.0.0-rc.0 h1:jJoA0N+C4/knWYVZ6GrdHOtDyrg8Y/TR4vFpTaqTsqs=\ngithub.com/efficientgo/core v1.0.0-rc.0/go.mod h1:kQa0V74HNYMfuJH6jiPiwNdpWXl4xd/K4tzlrcvYDQI=\ngithub.com/frankban/quicktest v1.14.5/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0=\ngithub.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=\ngithub.com/google/renameio/v2 v2.0.0/go.mod h1:BtmJXm5YlszgC+TD4HOEEUFgkJP3nLxehU6hfe7jRt4=\ngithub.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=\ngithub.com/inconshreveable/mousetrap v1.0.1 h1:U3uMjPSQEBMNp1lFxmllqCPM6P5u/Xq7Pgzkat/bFNc=\ngithub.com/inconshreveable/mousetrap v1.0.1/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=\ngithub.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=\ngithub.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=\ngithub.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA=\ngithub.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=\ngithub.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=\ngithub.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs=\ngithub.com/rogpeppe/go-internal v1.10.1-0.20230524175051-ec119421bb97/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA=\ngithub.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=\ngithub.com/spf13/cobra v1.5.0 h1:X+jTBEBqF0bHN+9cSMgmfuvv2VHJ9ezmFNf9Y/XstYU=\ngithub.com/spf13/cobra v1.5.0/go.mod h1:dWXEIy2H428czQCjInthrTRUg7yKbok+2Qi/yBIJoUM=\ngithub.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=\ngithub.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=\ngithub.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=\ngolang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=\ngolang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=\ngolang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=\ngolang.org/x/mod v0.9.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=\ngolang.org/x/mod v0.12.0 h1:rmsUpXtvNzj340zd98LZ4KntptpfRHwpFOHG188oHXc=\ngolang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=\ngolang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=\ngolang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=\ngolang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=\ngolang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sync v0.2.0 h1:PUR+T4wwASmuSTYdKjYHI5TD22Wy5ogLU5qZCOLxBrI=\ngolang.org/x/sync v0.2.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=\ngolang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.8.0 h1:EBmGv8NaZBZTWvrbjNoL6HVt+IVy3QDQpJs7VRIw3tU=\ngolang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=\ngolang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=\ngolang.org/x/term v0.8.0 h1:n5xxQn2i3PC0yLAbjTpNT85q/Kgzcr2gIoX9OrJUols=\ngolang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=\ngolang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=\ngolang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=\ngolang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=\ngolang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=\ngolang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=\ngolang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=\ngolang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=\ngopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=\ngopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=\nmvdan.cc/editorconfig v0.2.0/go.mod h1:lvnnD3BNdBYkhq+B4uBuFFKatfp02eB6HixDvEz91C0=\nmvdan.cc/sh/v3 v3.7.0 h1:lSTjdP/1xsddtaKfGg7Myu7DnlHItd3/M2tomOcNNBg=\nmvdan.cc/sh/v3 v3.7.0/go.mod h1:K2gwkaesF/D7av7Kxl0HbF5kGOd2ArupNTX3X44+8l8=\n"
  },
  {
    "path": ".bingo/buf.mod",
    "content": "module _ // Auto generated by https://github.com/bwplotka/bingo. DO NOT EDIT\n\ngo 1.24\n\ntoolchain go1.24.0\n\nrequire github.com/bufbuild/buf v1.55.1 // cmd/buf\n"
  },
  {
    "path": ".bingo/buf.sum",
    "content": "buf.build/gen/go/bufbuild/bufplugin/connectrpc/go v1.18.1-20250121211742-6d880cc6cc8d.1/go.mod h1:Xixf9QIALSxyoVWM9LH3ga3BNO1vvY+SS37XmNPT5ho=\nbuf.build/gen/go/bufbuild/bufplugin/protocolbuffers/go v1.36.6-20250121211742-6d880cc6cc8d.1 h1:f6miF8tK6H+Ktad24WpnNfpHO75GRGk0rhJ1mxPXqgA=\nbuf.build/gen/go/bufbuild/bufplugin/protocolbuffers/go v1.36.6-20250121211742-6d880cc6cc8d.1/go.mod h1:rvbyamNtvJ4o3ExeCmaG5/6iHnu0vy0E+UQ+Ph0om8s=\nbuf.build/gen/go/bufbuild/protovalidate/connectrpc/go v1.18.1-20250423154025-7712fb530c57.1/go.mod h1:XfHG9+bdnDRfPzvMUk4zHjapM8kZGfbmiIgmNIBZnZw=\nbuf.build/gen/go/bufbuild/protovalidate/protocolbuffers/go v1.36.6-20250613105001-9f2d3c737feb.1 h1:AUL6VF5YWL01j/1H/DQbPUSDkEwYqwVCNw7yhbpOxSQ=\nbuf.build/gen/go/bufbuild/protovalidate/protocolbuffers/go v1.36.6-20250613105001-9f2d3c737feb.1/go.mod h1:avRlCjnFzl98VPaeCtJ24RrV/wwHFzB8sWXhj26+n/U=\nbuf.build/gen/go/bufbuild/registry/connectrpc/go v1.18.1-20250606164443-9d1800bf4ccc.1 h1:x7juyChlm/fXZyuJTdBeMzHwAMhPJkP0qE4/IpwpGX4=\nbuf.build/gen/go/bufbuild/registry/connectrpc/go v1.18.1-20250606164443-9d1800bf4ccc.1/go.mod h1:vi8xjh+6SQRvLQYnyVFZ7kOBrFevwFudusxWVc6E58A=\nbuf.build/gen/go/bufbuild/registry/protocolbuffers/go v1.36.6-20250606164443-9d1800bf4ccc.1 h1:iiP7EL8EWrWmxn9qPDQTFdVSu04qIrmglpyjC10K4IU=\nbuf.build/gen/go/bufbuild/registry/protocolbuffers/go v1.36.6-20250606164443-9d1800bf4ccc.1/go.mod h1:bUPpZtzAkcnTA7OLfKCvkvkxEAC6dG/ZIlbnbUJicL4=\nbuf.build/gen/go/pluginrpc/pluginrpc/protocolbuffers/go v1.36.6-20241007202033-cf42259fcbfc.1 h1:trcsXBDm8exui7mvndZnvworCyBq1xuMnod2N0j79K8=\nbuf.build/gen/go/pluginrpc/pluginrpc/protocolbuffers/go v1.36.6-20241007202033-cf42259fcbfc.1/go.mod h1:OUbhXurY+VHFGn9FBxcRy8UB7HXk9NvJ2qCgifOMypQ=\nbuf.build/go/app v0.1.0 h1:nlqD/h0rhIN73ZoiDElprrPiO2N6JV+RmNK34K29Ihg=\nbuf.build/go/app v0.1.0/go.mod h1:0XVOYemubVbxNXVY0DnsVgWeGkcbbAvjDa1fmhBC+Wo=\nbuf.build/go/bufplugin v0.9.0 h1:ktZJNP3If7ldcWVqh46XKeiYJVPxHQxCfjzVQDzZ/lo=\nbuf.build/go/bufplugin v0.9.0/go.mod h1:Z0CxA3sKQ6EPz/Os4kJJneeRO6CjPeidtP1ABh5jPPY=\nbuf.build/go/interrupt v1.1.0 h1:olBuhgv9Sav4/9pkSLoxgiOsZDgM5VhRhvRpn3DL0lE=\nbuf.build/go/interrupt v1.1.0/go.mod h1:ql56nXPG1oHlvZa6efNC7SKAQ/tUjS6z0mhJl0gyeRM=\nbuf.build/go/protovalidate v0.13.1 h1:6loHDTWdY/1qmqmt1MijBIKeN4T9Eajrqb9isT1W1s8=\nbuf.build/go/protovalidate v0.13.1/go.mod h1:C/QcOn/CjXRn5udUwYBiLs8y1TGy7RS+GOSKqjS77aU=\nbuf.build/go/protoyaml v0.6.0 h1:Nzz1lvcXF8YgNZXk+voPPwdU8FjDPTUV4ndNTXN0n2w=\nbuf.build/go/protoyaml v0.6.0/go.mod h1:RgUOsBu/GYKLDSIRgQXniXbNgFlGEZnQpRAUdLAFV2Q=\nbuf.build/go/spdx v0.2.0 h1:IItqM0/cMxvFJJumcBuP8NrsIzMs/UYjp/6WSpq8LTw=\nbuf.build/go/spdx v0.2.0/go.mod h1:bXdwQFem9Si3nsbNy8aJKGPoaPi5DKwdeEp5/ArZ6w8=\nbuf.build/go/standard v0.1.0 h1:g98T9IyvAl0vS3Pq8iVk6Cvj2ZiFvoUJRtfyGa0120U=\nbuf.build/go/standard v0.1.0/go.mod h1:PiqpHz/7ZFq+kqvYhc/SK3lxFIB9N/aiH2CFC2JHIQg=\ncel.dev/expr v0.24.0 h1:56OvJKSH3hDGL0ml5uSxZmz3/3Pq4tJ+fb1unVLAFcY=\ncel.dev/expr v0.24.0/go.mod h1:hLPLo1W4QUmuYdA72RBX06QTs6MXw941piREPl3Yfiw=\ncloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=\ncloud.google.com/go v0.31.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=\ncloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=\ncloud.google.com/go v0.37.0/go.mod h1:TS1dMSSfndXH133OKGwekG838Om/cQT0BUHV3HcBgoo=\ncloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU=\ncloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU=\ncloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY=\ncloud.google.com/go v0.44.3/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY=\ncloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc=\ncloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0=\ncloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To=\ncloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4=\ncloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M=\ncloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc=\ncloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk=\ncloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs=\ncloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc=\ncloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY=\ncloud.google.com/go v0.72.0/go.mod h1:M+5Vjvlc2wnp6tjzE102Dw08nGShTscUx2nZMufOKPI=\ncloud.google.com/go v0.74.0/go.mod h1:VV1xSbzvo+9QJOxLDaJfTjx5e+MePCpCWwvftOeQmWk=\ncloud.google.com/go v0.75.0/go.mod h1:VGuuCn7PG0dwsd5XPVm2Mm3wlh3EL55/79EKB6hlPTY=\ncloud.google.com/go v0.78.0/go.mod h1:QjdrLG0uq+YwhjoVOLsS1t7TW8fs36kLs4XO5R5ECHg=\ncloud.google.com/go v0.79.0/go.mod h1:3bzgcEeQlzbuEAYu4mrWhKqWjmpprinYgKJLgKHnbb8=\ncloud.google.com/go v0.81.0/go.mod h1:mk/AM35KwGk/Nm2YSeZbxXdrNK3KZOYHmLkOqC2V6E0=\ncloud.google.com/go v0.83.0/go.mod h1:Z7MJUsANfY0pYPdw0lbnivPx4/vhy/e2FEkSkF7vAVY=\ncloud.google.com/go v0.84.0/go.mod h1:RazrYuxIK6Kb7YrzzhPoLmCVzl7Sup4NrbKPg8KHSUM=\ncloud.google.com/go v0.87.0/go.mod h1:TpDYlFy7vuLzZMMZ+B6iRiELaY7z/gJPaqbMx6mlWcY=\ncloud.google.com/go v0.90.0/go.mod h1:kRX0mNRHe0e2rC6oNakvwQqzyDmg57xJ+SZU1eT2aDQ=\ncloud.google.com/go v0.93.3/go.mod h1:8utlLll2EF5XMAV15woO4lSbWQlk8rer9aLOfLh7+YI=\ncloud.google.com/go v0.94.1/go.mod h1:qAlAugsXlC+JWO+Bke5vCtc9ONxjQT3drlTTnAplMW4=\ncloud.google.com/go v0.97.0/go.mod h1:GF7l59pYBVlXQIBLx3a761cZ41F9bBH3JUlihCt2Udc=\ncloud.google.com/go v0.99.0/go.mod h1:w0Xx2nLzqWJPuozYQX+hFfCSI8WioryfRDzkoI/Y2ZA=\ncloud.google.com/go v0.100.1/go.mod h1:fs4QogzfH5n2pBXBP9vRiU+eCny7lD2vmFZy79Iuw1U=\ncloud.google.com/go v0.100.2/go.mod h1:4Xra9TjzAeYHrl5+oeLlzbM2k3mjVhZh4UqTZ//w99A=\ncloud.google.com/go v0.102.0/go.mod h1:oWcCzKlqJ5zgHQt9YsaeTY9KzIvjyy0ArmiBUgpQ+nc=\ncloud.google.com/go v0.102.1/go.mod h1:XZ77E9qnTEnrgEOvr4xzfdX5TRo7fB4T2F4O6+34hIU=\ncloud.google.com/go v0.104.0/go.mod h1:OO6xxXdJyvuJPcEPBLN9BJPD+jep5G1+2U5B5gkRYtA=\ncloud.google.com/go v0.105.0/go.mod h1:PrLgOJNe5nfE9UMxKxgXj4mD3voiP+YQ6gdt6KMFOKM=\ncloud.google.com/go v0.107.0/go.mod h1:wpc2eNrD7hXUTy8EKS10jkxpZBjASrORK7goS+3YX2I=\ncloud.google.com/go v0.110.0/go.mod h1:SJnCLqQ0FCFGSZMUNUf84MV3Aia54kn7pi8st7tMzaY=\ncloud.google.com/go v0.112.1/go.mod h1:+Vbu+Y1UU+I1rjmzeMOb/8RfkKJK2Gyxi1X6jJCZLo4=\ncloud.google.com/go/accessapproval v1.4.0/go.mod h1:zybIuC3KpDOvotz59lFe5qxRZx6C75OtwbisN56xYB4=\ncloud.google.com/go/accessapproval v1.5.0/go.mod h1:HFy3tuiGvMdcd/u+Cu5b9NkO1pEICJ46IR82PoUdplw=\ncloud.google.com/go/accessapproval v1.6.0/go.mod h1:R0EiYnwV5fsRFiKZkPHr6mwyk2wxUJ30nL4j2pcFY2E=\ncloud.google.com/go/accessapproval v1.7.5/go.mod h1:g88i1ok5dvQ9XJsxpUInWWvUBrIZhyPDPbk4T01OoJ0=\ncloud.google.com/go/accesscontextmanager v1.3.0/go.mod h1:TgCBehyr5gNMz7ZaH9xubp+CE8dkrszb4oK9CWyvD4o=\ncloud.google.com/go/accesscontextmanager v1.4.0/go.mod h1:/Kjh7BBu/Gh83sv+K60vN9QE5NJcd80sU33vIe2IFPE=\ncloud.google.com/go/accesscontextmanager v1.6.0/go.mod h1:8XCvZWfYw3K/ji0iVnp+6pu7huxoQTLmxAbVjbloTtM=\ncloud.google.com/go/accesscontextmanager v1.7.0/go.mod h1:CEGLewx8dwa33aDAZQujl7Dx+uYhS0eay198wB/VumQ=\ncloud.google.com/go/accesscontextmanager v1.8.5/go.mod h1:TInEhcZ7V9jptGNqN3EzZ5XMhT6ijWxTGjzyETwmL0Q=\ncloud.google.com/go/aiplatform v1.22.0/go.mod h1:ig5Nct50bZlzV6NvKaTwmplLLddFx0YReh9WfTO5jKw=\ncloud.google.com/go/aiplatform v1.24.0/go.mod h1:67UUvRBKG6GTayHKV8DBv2RtR1t93YRu5B1P3x99mYY=\ncloud.google.com/go/aiplatform v1.27.0/go.mod h1:Bvxqtl40l0WImSb04d0hXFU7gDOiq9jQmorivIiWcKg=\ncloud.google.com/go/aiplatform v1.35.0/go.mod h1:7MFT/vCaOyZT/4IIFfxH4ErVg/4ku6lKv3w0+tFTgXQ=\ncloud.google.com/go/aiplatform v1.36.1/go.mod h1:WTm12vJRPARNvJ+v6P52RDHCNe4AhvjcIZ/9/RRHy/k=\ncloud.google.com/go/aiplatform v1.60.0/go.mod h1:eTlGuHOahHprZw3Hio5VKmtThIOak5/qy6pzdsqcQnM=\ncloud.google.com/go/analytics v0.11.0/go.mod h1:DjEWCu41bVbYcKyvlws9Er60YE4a//bK6mnhWvQeFNI=\ncloud.google.com/go/analytics v0.12.0/go.mod h1:gkfj9h6XRf9+TS4bmuhPEShsh3hH8PAZzm/41OOhQd4=\ncloud.google.com/go/analytics v0.17.0/go.mod h1:WXFa3WSym4IZ+JiKmavYdJwGG/CvpqiqczmL59bTD9M=\ncloud.google.com/go/analytics v0.18.0/go.mod h1:ZkeHGQlcIPkw0R/GW+boWHhCOR43xz9RN/jn7WcqfIE=\ncloud.google.com/go/analytics v0.19.0/go.mod h1:k8liqf5/HCnOUkbawNtrWWc+UAzyDlW89doe8TtoDsE=\ncloud.google.com/go/analytics v0.23.0/go.mod h1:YPd7Bvik3WS95KBok2gPXDqQPHy08TsCQG6CdUCb+u0=\ncloud.google.com/go/apigateway v1.3.0/go.mod h1:89Z8Bhpmxu6AmUxuVRg/ECRGReEdiP3vQtk4Z1J9rJk=\ncloud.google.com/go/apigateway v1.4.0/go.mod h1:pHVY9MKGaH9PQ3pJ4YLzoj6U5FUDeDFBllIz7WmzJoc=\ncloud.google.com/go/apigateway v1.5.0/go.mod h1:GpnZR3Q4rR7LVu5951qfXPJCHquZt02jf7xQx7kpqN8=\ncloud.google.com/go/apigateway v1.6.5/go.mod h1:6wCwvYRckRQogyDDltpANi3zsCDl6kWi0b4Je+w2UiI=\ncloud.google.com/go/apigeeconnect v1.3.0/go.mod h1:G/AwXFAKo0gIXkPTVfZDd2qA1TxBXJ3MgMRBQkIi9jc=\ncloud.google.com/go/apigeeconnect v1.4.0/go.mod h1:kV4NwOKqjvt2JYR0AoIWo2QGfoRtn/pkS3QlHp0Ni04=\ncloud.google.com/go/apigeeconnect v1.5.0/go.mod h1:KFaCqvBRU6idyhSNyn3vlHXc8VMDJdRmwDF6JyFRqZ8=\ncloud.google.com/go/apigeeconnect v1.6.5/go.mod h1:MEKm3AiT7s11PqTfKE3KZluZA9O91FNysvd3E6SJ6Ow=\ncloud.google.com/go/apigeeregistry v0.4.0/go.mod h1:EUG4PGcsZvxOXAdyEghIdXwAEi/4MEaoqLMLDMIwKXY=\ncloud.google.com/go/apigeeregistry v0.5.0/go.mod h1:YR5+s0BVNZfVOUkMa5pAR2xGd0A473vA5M7j247o1wM=\ncloud.google.com/go/apigeeregistry v0.6.0/go.mod h1:BFNzW7yQVLZ3yj0TKcwzb8n25CFBri51GVGOEUcgQsc=\ncloud.google.com/go/apigeeregistry v0.8.3/go.mod h1:aInOWnqF4yMQx8kTjDqHNXjZGh/mxeNlAf52YqtASUs=\ncloud.google.com/go/apikeys v0.4.0/go.mod h1:XATS/yqZbaBK0HOssf+ALHp8jAlNHUgyfprvNcBIszU=\ncloud.google.com/go/apikeys v0.5.0/go.mod h1:5aQfwY4D+ewMMWScd3hm2en3hCj+BROlyrt3ytS7KLI=\ncloud.google.com/go/apikeys v0.6.0/go.mod h1:kbpXu5upyiAlGkKrJgQl8A0rKNNJ7dQ377pdroRSSi8=\ncloud.google.com/go/appengine v1.4.0/go.mod h1:CS2NhuBuDXM9f+qscZ6V86m1MIIqPj3WC/UoEuR1Sno=\ncloud.google.com/go/appengine v1.5.0/go.mod h1:TfasSozdkFI0zeoxW3PTBLiNqRmzraodCWatWI9Dmak=\ncloud.google.com/go/appengine v1.6.0/go.mod h1:hg6i0J/BD2cKmDJbaFSYHFyZkgBEfQrDg/X0V5fJn84=\ncloud.google.com/go/appengine v1.7.0/go.mod h1:eZqpbHFCqRGa2aCdope7eC0SWLV1j0neb/QnMJVWx6A=\ncloud.google.com/go/appengine v1.8.5/go.mod h1:uHBgNoGLTS5di7BvU25NFDuKa82v0qQLjyMJLuPQrVo=\ncloud.google.com/go/area120 v0.5.0/go.mod h1:DE/n4mp+iqVyvxHN41Vf1CR602GiHQjFPusMFW6bGR4=\ncloud.google.com/go/area120 v0.6.0/go.mod h1:39yFJqWVgm0UZqWTOdqkLhjoC7uFfgXRC8g/ZegeAh0=\ncloud.google.com/go/area120 v0.7.0/go.mod h1:a3+8EUD1SX5RUcCs3MY5YasiO1z6yLiNLRiFrykbynY=\ncloud.google.com/go/area120 v0.7.1/go.mod h1:j84i4E1RboTWjKtZVWXPqvK5VHQFJRF2c1Nm69pWm9k=\ncloud.google.com/go/area120 v0.8.5/go.mod h1:BcoFCbDLZjsfe4EkCnEq1LKvHSK0Ew/zk5UFu6GMyA0=\ncloud.google.com/go/artifactregistry v1.6.0/go.mod h1:IYt0oBPSAGYj/kprzsBjZ/4LnG/zOcHyFHjWPCi6SAQ=\ncloud.google.com/go/artifactregistry v1.7.0/go.mod h1:mqTOFOnGZx8EtSqK/ZWcsm/4U8B77rbcLP6ruDU2Ixk=\ncloud.google.com/go/artifactregistry v1.8.0/go.mod h1:w3GQXkJX8hiKN0v+at4b0qotwijQbYUqF2GWkZzAhC0=\ncloud.google.com/go/artifactregistry v1.9.0/go.mod h1:2K2RqvA2CYvAeARHRkLDhMDJ3OXy26h3XW+3/Jh2uYc=\ncloud.google.com/go/artifactregistry v1.11.1/go.mod h1:lLYghw+Itq9SONbCa1YWBoWs1nOucMH0pwXN1rOBZFI=\ncloud.google.com/go/artifactregistry v1.11.2/go.mod h1:nLZns771ZGAwVLzTX/7Al6R9ehma4WUEhZGWV6CeQNQ=\ncloud.google.com/go/artifactregistry v1.12.0/go.mod h1:o6P3MIvtzTOnmvGagO9v/rOjjA0HmhJ+/6KAXrmYDCI=\ncloud.google.com/go/artifactregistry v1.14.7/go.mod h1:0AUKhzWQzfmeTvT4SjfI4zjot72EMfrkvL9g9aRjnnM=\ncloud.google.com/go/asset v1.5.0/go.mod h1:5mfs8UvcM5wHhqtSv8J1CtxxaQq3AdBxxQi2jGW/K4o=\ncloud.google.com/go/asset v1.7.0/go.mod h1:YbENsRK4+xTiL+Ofoj5Ckf+O17kJtgp3Y3nn4uzZz5s=\ncloud.google.com/go/asset v1.8.0/go.mod h1:mUNGKhiqIdbr8X7KNayoYvyc4HbbFO9URsjbytpUaW0=\ncloud.google.com/go/asset v1.9.0/go.mod h1:83MOE6jEJBMqFKadM9NLRcs80Gdw76qGuHn8m3h8oHQ=\ncloud.google.com/go/asset v1.10.0/go.mod h1:pLz7uokL80qKhzKr4xXGvBQXnzHn5evJAEAtZiIb0wY=\ncloud.google.com/go/asset v1.11.1/go.mod h1:fSwLhbRvC9p9CXQHJ3BgFeQNM4c9x10lqlrdEUYXlJo=\ncloud.google.com/go/asset v1.12.0/go.mod h1:h9/sFOa4eDIyKmH6QMpm4eUK3pDojWnUhTgJlk762Hg=\ncloud.google.com/go/asset v1.17.2/go.mod h1:SVbzde67ehddSoKf5uebOD1sYw8Ab/jD/9EIeWg99q4=\ncloud.google.com/go/assuredworkloads v1.5.0/go.mod h1:n8HOZ6pff6re5KYfBXcFvSViQjDwxFkAkmUFffJRbbY=\ncloud.google.com/go/assuredworkloads v1.6.0/go.mod h1:yo2YOk37Yc89Rsd5QMVECvjaMKymF9OP+QXWlKXUkXw=\ncloud.google.com/go/assuredworkloads v1.7.0/go.mod h1:z/736/oNmtGAyU47reJgGN+KVoYoxeLBoj4XkKYscNI=\ncloud.google.com/go/assuredworkloads v1.8.0/go.mod h1:AsX2cqyNCOvEQC8RMPnoc0yEarXQk6WEKkxYfL6kGIo=\ncloud.google.com/go/assuredworkloads v1.9.0/go.mod h1:kFuI1P78bplYtT77Tb1hi0FMxM0vVpRC7VVoJC3ZoT0=\ncloud.google.com/go/assuredworkloads v1.10.0/go.mod h1:kwdUQuXcedVdsIaKgKTp9t0UJkE5+PAVNhdQm4ZVq2E=\ncloud.google.com/go/assuredworkloads v1.11.5/go.mod h1:FKJ3g3ZvkL2D7qtqIGnDufFkHxwIpNM9vtmhvt+6wqk=\ncloud.google.com/go/automl v1.5.0/go.mod h1:34EjfoFGMZ5sgJ9EoLsRtdPSNZLcfflJR39VbVNS2M0=\ncloud.google.com/go/automl v1.6.0/go.mod h1:ugf8a6Fx+zP0D59WLhqgTDsQI9w07o64uf/Is3Nh5p8=\ncloud.google.com/go/automl v1.7.0/go.mod h1:RL9MYCCsJEOmt0Wf3z9uzG0a7adTT1fe+aObgSpkCt8=\ncloud.google.com/go/automl v1.8.0/go.mod h1:xWx7G/aPEe/NP+qzYXktoBSDfjO+vnKMGgsApGJJquM=\ncloud.google.com/go/automl v1.12.0/go.mod h1:tWDcHDp86aMIuHmyvjuKeeHEGq76lD7ZqfGLN6B0NuU=\ncloud.google.com/go/automl v1.13.5/go.mod h1:MDw3vLem3yh+SvmSgeYUmUKqyls6NzSumDm9OJ3xJ1Y=\ncloud.google.com/go/baremetalsolution v0.3.0/go.mod h1:XOrocE+pvK1xFfleEnShBlNAXf+j5blPPxrhjKgnIFc=\ncloud.google.com/go/baremetalsolution v0.4.0/go.mod h1:BymplhAadOO/eBa7KewQ0Ppg4A4Wplbn+PsFKRLo0uI=\ncloud.google.com/go/baremetalsolution v0.5.0/go.mod h1:dXGxEkmR9BMwxhzBhV0AioD0ULBmuLZI8CdwalUxuss=\ncloud.google.com/go/baremetalsolution v1.2.4/go.mod h1:BHCmxgpevw9IEryE99HbYEfxXkAEA3hkMJbYYsHtIuY=\ncloud.google.com/go/batch v0.3.0/go.mod h1:TR18ZoAekj1GuirsUsR1ZTKN3FC/4UDnScjT8NXImFE=\ncloud.google.com/go/batch v0.4.0/go.mod h1:WZkHnP43R/QCGQsZ+0JyG4i79ranE2u8xvjq/9+STPE=\ncloud.google.com/go/batch v0.7.0/go.mod h1:vLZN95s6teRUqRQ4s3RLDsH8PvboqBK+rn1oevL159g=\ncloud.google.com/go/batch v1.8.0/go.mod h1:k8V7f6VE2Suc0zUM4WtoibNrA6D3dqBpB+++e3vSGYc=\ncloud.google.com/go/beyondcorp v0.2.0/go.mod h1:TB7Bd+EEtcw9PCPQhCJtJGjk/7TC6ckmnSFS+xwTfm4=\ncloud.google.com/go/beyondcorp v0.3.0/go.mod h1:E5U5lcrcXMsCuoDNyGrpyTm/hn7ne941Jz2vmksAxW8=\ncloud.google.com/go/beyondcorp v0.4.0/go.mod h1:3ApA0mbhHx6YImmuubf5pyW8srKnCEPON32/5hj+RmM=\ncloud.google.com/go/beyondcorp v0.5.0/go.mod h1:uFqj9X+dSfrheVp7ssLTaRHd2EHqSL4QZmH4e8WXGGU=\ncloud.google.com/go/beyondcorp v1.0.4/go.mod h1:Gx8/Rk2MxrvWfn4WIhHIG1NV7IBfg14pTKv1+EArVcc=\ncloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o=\ncloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE=\ncloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc=\ncloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg=\ncloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc=\ncloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ=\ncloud.google.com/go/bigquery v1.42.0/go.mod h1:8dRTJxhtG+vwBKzE5OseQn/hiydoQN3EedCaOdYmxRA=\ncloud.google.com/go/bigquery v1.43.0/go.mod h1:ZMQcXHsl+xmU1z36G2jNGZmKp9zNY5BUua5wDgmNCfw=\ncloud.google.com/go/bigquery v1.44.0/go.mod h1:0Y33VqXTEsbamHJvJHdFmtqHvMIY28aK1+dFsvaChGc=\ncloud.google.com/go/bigquery v1.47.0/go.mod h1:sA9XOgy0A8vQK9+MWhEQTY6Tix87M/ZurWFIxmF9I/E=\ncloud.google.com/go/bigquery v1.48.0/go.mod h1:QAwSz+ipNgfL5jxiaK7weyOhzdoAy1zFm0Nf1fysJac=\ncloud.google.com/go/bigquery v1.49.0/go.mod h1:Sv8hMmTFFYBlt/ftw2uN6dFdQPzBlREY9yBh7Oy7/4Q=\ncloud.google.com/go/bigquery v1.59.1/go.mod h1:VP1UJYgevyTwsV7desjzNzDND5p6hZB+Z8gZJN1GQUc=\ncloud.google.com/go/billing v1.4.0/go.mod h1:g9IdKBEFlItS8bTtlrZdVLWSSdSyFUZKXNS02zKMOZY=\ncloud.google.com/go/billing v1.5.0/go.mod h1:mztb1tBc3QekhjSgmpf/CV4LzWXLzCArwpLmP2Gm88s=\ncloud.google.com/go/billing v1.6.0/go.mod h1:WoXzguj+BeHXPbKfNWkqVtDdzORazmCjraY+vrxcyvI=\ncloud.google.com/go/billing v1.7.0/go.mod h1:q457N3Hbj9lYwwRbnlD7vUpyjq6u5U1RAOArInEiD5Y=\ncloud.google.com/go/billing v1.12.0/go.mod h1:yKrZio/eu+okO/2McZEbch17O5CB5NpZhhXG6Z766ss=\ncloud.google.com/go/billing v1.13.0/go.mod h1:7kB2W9Xf98hP9Sr12KfECgfGclsH3CQR0R08tnRlRbc=\ncloud.google.com/go/billing v1.18.2/go.mod h1:PPIwVsOOQ7xzbADCwNe8nvK776QpfrOAUkvKjCUcpSE=\ncloud.google.com/go/binaryauthorization v1.1.0/go.mod h1:xwnoWu3Y84jbuHa0zd526MJYmtnVXn0syOjaJgy4+dM=\ncloud.google.com/go/binaryauthorization v1.2.0/go.mod h1:86WKkJHtRcv5ViNABtYMhhNWRrD1Vpi//uKEy7aYEfI=\ncloud.google.com/go/binaryauthorization v1.3.0/go.mod h1:lRZbKgjDIIQvzYQS1p99A7/U1JqvqeZg0wiI5tp6tg0=\ncloud.google.com/go/binaryauthorization v1.4.0/go.mod h1:tsSPQrBd77VLplV70GUhBf/Zm3FsKmgSqgm4UmiDItk=\ncloud.google.com/go/binaryauthorization v1.5.0/go.mod h1:OSe4OU1nN/VswXKRBmciKpo9LulY41gch5c68htf3/Q=\ncloud.google.com/go/binaryauthorization v1.8.1/go.mod h1:1HVRyBerREA/nhI7yLang4Zn7vfNVA3okoAR9qYQJAQ=\ncloud.google.com/go/certificatemanager v1.3.0/go.mod h1:n6twGDvcUBFu9uBgt4eYvvf3sQ6My8jADcOVwHmzadg=\ncloud.google.com/go/certificatemanager v1.4.0/go.mod h1:vowpercVFyqs8ABSmrdV+GiFf2H/ch3KyudYQEMM590=\ncloud.google.com/go/certificatemanager v1.6.0/go.mod h1:3Hh64rCKjRAX8dXgRAyOcY5vQ/fE1sh8o+Mdd6KPgY8=\ncloud.google.com/go/certificatemanager v1.7.5/go.mod h1:uX+v7kWqy0Y3NG/ZhNvffh0kuqkKZIXdvlZRO7z0VtM=\ncloud.google.com/go/channel v1.8.0/go.mod h1:W5SwCXDJsq/rg3tn3oG0LOxpAo6IMxNa09ngphpSlnk=\ncloud.google.com/go/channel v1.9.0/go.mod h1:jcu05W0my9Vx4mt3/rEHpfxc9eKi9XwsdDL8yBMbKUk=\ncloud.google.com/go/channel v1.11.0/go.mod h1:IdtI0uWGqhEeatSB62VOoJ8FSUhJ9/+iGkJVqp74CGE=\ncloud.google.com/go/channel v1.12.0/go.mod h1:VkxCGKASi4Cq7TbXxlaBezonAYpp1GCnKMY6tnMQnLU=\ncloud.google.com/go/channel v1.17.5/go.mod h1:FlpaOSINDAXgEext0KMaBq/vwpLMkkPAw9b2mApQeHc=\ncloud.google.com/go/cloudbuild v1.3.0/go.mod h1:WequR4ULxlqvMsjDEEEFnOG5ZSRSgWOywXYDb1vPE6U=\ncloud.google.com/go/cloudbuild v1.4.0/go.mod h1:5Qwa40LHiOXmz3386FrjrYM93rM/hdRr7b53sySrTqA=\ncloud.google.com/go/cloudbuild v1.6.0/go.mod h1:UIbc/w9QCbH12xX+ezUsgblrWv+Cv4Tw83GiSMHOn9M=\ncloud.google.com/go/cloudbuild v1.7.0/go.mod h1:zb5tWh2XI6lR9zQmsm1VRA+7OCuve5d8S+zJUul8KTg=\ncloud.google.com/go/cloudbuild v1.9.0/go.mod h1:qK1d7s4QlO0VwfYn5YuClDGg2hfmLZEb4wQGAbIgL1s=\ncloud.google.com/go/cloudbuild v1.15.1/go.mod h1:gIofXZSu+XD2Uy+qkOrGKEx45zd7s28u/k8f99qKals=\ncloud.google.com/go/clouddms v1.3.0/go.mod h1:oK6XsCDdW4Ib3jCCBugx+gVjevp2TMXFtgxvPSee3OM=\ncloud.google.com/go/clouddms v1.4.0/go.mod h1:Eh7sUGCC+aKry14O1NRljhjyrr0NFC0G2cjwX0cByRk=\ncloud.google.com/go/clouddms v1.5.0/go.mod h1:QSxQnhikCLUw13iAbffF2CZxAER3xDGNHjsTAkQJcQA=\ncloud.google.com/go/clouddms v1.7.4/go.mod h1:RdrVqoFG9RWI5AvZ81SxJ/xvxPdtcRhFotwdE79DieY=\ncloud.google.com/go/cloudtasks v1.5.0/go.mod h1:fD92REy1x5woxkKEkLdvavGnPJGEn8Uic9nWuLzqCpY=\ncloud.google.com/go/cloudtasks v1.6.0/go.mod h1:C6Io+sxuke9/KNRkbQpihnW93SWDU3uXt92nu85HkYI=\ncloud.google.com/go/cloudtasks v1.7.0/go.mod h1:ImsfdYWwlWNJbdgPIIGJWC+gemEGTBK/SunNQQNCAb4=\ncloud.google.com/go/cloudtasks v1.8.0/go.mod h1:gQXUIwCSOI4yPVK7DgTVFiiP0ZW/eQkydWzwVMdHxrI=\ncloud.google.com/go/cloudtasks v1.9.0/go.mod h1:w+EyLsVkLWHcOaqNEyvcKAsWp9p29dL6uL9Nst1cI7Y=\ncloud.google.com/go/cloudtasks v1.10.0/go.mod h1:NDSoTLkZ3+vExFEWu2UJV1arUyzVDAiZtdWcsUyNwBs=\ncloud.google.com/go/cloudtasks v1.12.6/go.mod h1:b7c7fe4+TJsFZfDyzO51F7cjq7HLUlRi/KZQLQjDsaY=\ncloud.google.com/go/compute v0.1.0/go.mod h1:GAesmwr110a34z04OlxYkATPBEfVhkymfTBXtfbBFow=\ncloud.google.com/go/compute v1.3.0/go.mod h1:cCZiE1NHEtai4wiufUhW8I8S1JKkAnhnQJWM7YD99wM=\ncloud.google.com/go/compute v1.5.0/go.mod h1:9SMHyhJlzhlkJqrPAc839t2BZFTSk6Jdj6mkzQJeu0M=\ncloud.google.com/go/compute v1.6.0/go.mod h1:T29tfhtVbq1wvAPo0E3+7vhgmkOYeXjhFvz/FMzPu0s=\ncloud.google.com/go/compute v1.6.1/go.mod h1:g85FgpzFvNULZ+S8AYq87axRKuf2Kh7deLqV/jJ3thU=\ncloud.google.com/go/compute v1.7.0/go.mod h1:435lt8av5oL9P3fv1OEzSbSUe+ybHXGMPQHHZWZxy9U=\ncloud.google.com/go/compute v1.10.0/go.mod h1:ER5CLbMxl90o2jtNbGSbtfOpQKR0t15FOtRsugnLrlU=\ncloud.google.com/go/compute v1.12.0/go.mod h1:e8yNOBcBONZU1vJKCvCoDw/4JQsA0dpM4x/6PIIOocU=\ncloud.google.com/go/compute v1.12.1/go.mod h1:e8yNOBcBONZU1vJKCvCoDw/4JQsA0dpM4x/6PIIOocU=\ncloud.google.com/go/compute v1.13.0/go.mod h1:5aPTS0cUNMIc1CE546K+Th6weJUNQErARyZtRXDJ8GE=\ncloud.google.com/go/compute v1.14.0/go.mod h1:YfLtxrj9sU4Yxv+sXzZkyPjEyPBZfXHUvjxega5vAdo=\ncloud.google.com/go/compute v1.15.1/go.mod h1:bjjoF/NtFUrkD/urWfdHaKuOPDR5nWIs63rR+SXhcpA=\ncloud.google.com/go/compute v1.18.0/go.mod h1:1X7yHxec2Ga+Ss6jPyjxRxpu2uu7PLgsOVXvgU0yacs=\ncloud.google.com/go/compute v1.19.0/go.mod h1:rikpw2y+UMidAe9tISo04EHNOIf42RLYF/q8Bs93scU=\ncloud.google.com/go/compute v1.19.1/go.mod h1:6ylj3a05WF8leseCdIf77NK0g1ey+nj5IKd5/kvShxE=\ncloud.google.com/go/compute v1.25.1/go.mod h1:oopOIR53ly6viBYxaDhBfJwzUAxf1zE//uf3IB011ls=\ncloud.google.com/go/compute/metadata v0.1.0/go.mod h1:Z1VN+bulIf6bt4P/C37K4DyZYZEXYonfTBHHFPO/4UU=\ncloud.google.com/go/compute/metadata v0.2.0/go.mod h1:zFmK7XCadkQkj6TtorcaGlCW1hT1fIilQDwofLpJ20k=\ncloud.google.com/go/compute/metadata v0.2.1/go.mod h1:jgHgmJd2RKBGzXqF5LR2EZMGxBkeanZ9wwa75XHJgOM=\ncloud.google.com/go/compute/metadata v0.2.3/go.mod h1:VAV5nSsACxMJvgaAuX6Pk2AawlZn8kiOGuCv6gTkwuA=\ncloud.google.com/go/compute/metadata v0.7.0/go.mod h1:j5MvL9PprKL39t166CoB1uVHfQMs4tFQZZcKwksXUjo=\ncloud.google.com/go/contactcenterinsights v1.3.0/go.mod h1:Eu2oemoePuEFc/xKFPjbTuPSj0fYJcPls9TFlPNnHHY=\ncloud.google.com/go/contactcenterinsights v1.4.0/go.mod h1:L2YzkGbPsv+vMQMCADxJoT9YiTTnSEd6fEvCeHTYVck=\ncloud.google.com/go/contactcenterinsights v1.6.0/go.mod h1:IIDlT6CLcDoyv79kDv8iWxMSTZhLxSCofVV5W6YFM/w=\ncloud.google.com/go/contactcenterinsights v1.13.0/go.mod h1:ieq5d5EtHsu8vhe2y3amtZ+BE+AQwX5qAy7cpo0POsI=\ncloud.google.com/go/container v1.6.0/go.mod h1:Xazp7GjJSeUYo688S+6J5V+n/t+G5sKBTFkKNudGRxg=\ncloud.google.com/go/container v1.7.0/go.mod h1:Dp5AHtmothHGX3DwwIHPgq45Y8KmNsgN3amoYfxVkLo=\ncloud.google.com/go/container v1.13.1/go.mod h1:6wgbMPeQRw9rSnKBCAJXnds3Pzj03C4JHamr8asWKy4=\ncloud.google.com/go/container v1.14.0/go.mod h1:3AoJMPhHfLDxLvrlVWaK57IXzaPnLaZq63WX59aQBfM=\ncloud.google.com/go/container v1.31.0/go.mod h1:7yABn5s3Iv3lmw7oMmyGbeV6tQj86njcTijkkGuvdZA=\ncloud.google.com/go/containeranalysis v0.5.1/go.mod h1:1D92jd8gRR/c0fGMlymRgxWD3Qw9C1ff6/T7mLgVL8I=\ncloud.google.com/go/containeranalysis v0.6.0/go.mod h1:HEJoiEIu+lEXM+k7+qLCci0h33lX3ZqoYFdmPcoO7s4=\ncloud.google.com/go/containeranalysis v0.7.0/go.mod h1:9aUL+/vZ55P2CXfuZjS4UjQ9AgXoSw8Ts6lemfmxBxI=\ncloud.google.com/go/containeranalysis v0.9.0/go.mod h1:orbOANbwk5Ejoom+s+DUCTTJ7IBdBQJDcSylAx/on9s=\ncloud.google.com/go/containeranalysis v0.11.4/go.mod h1:cVZT7rXYBS9NG1rhQbWL9pWbXCKHWJPYraE8/FTSYPE=\ncloud.google.com/go/datacatalog v1.3.0/go.mod h1:g9svFY6tuR+j+hrTw3J2dNcmI0dzmSiyOzm8kpLq0a0=\ncloud.google.com/go/datacatalog v1.5.0/go.mod h1:M7GPLNQeLfWqeIm3iuiruhPzkt65+Bx8dAKvScX8jvs=\ncloud.google.com/go/datacatalog v1.6.0/go.mod h1:+aEyF8JKg+uXcIdAmmaMUmZ3q1b/lKLtXCmXdnc0lbc=\ncloud.google.com/go/datacatalog v1.7.0/go.mod h1:9mEl4AuDYWw81UGc41HonIHH7/sn52H0/tc8f8ZbZIE=\ncloud.google.com/go/datacatalog v1.8.0/go.mod h1:KYuoVOv9BM8EYz/4eMFxrr4DUKhGIOXxZoKYF5wdISM=\ncloud.google.com/go/datacatalog v1.8.1/go.mod h1:RJ58z4rMp3gvETA465Vg+ag8BGgBdnRPEMMSTr5Uv+M=\ncloud.google.com/go/datacatalog v1.12.0/go.mod h1:CWae8rFkfp6LzLumKOnmVh4+Zle4A3NXLzVJ1d1mRm0=\ncloud.google.com/go/datacatalog v1.13.0/go.mod h1:E4Rj9a5ZtAxcQJlEBTLgMTphfP11/lNaAshpoBgemX8=\ncloud.google.com/go/datacatalog v1.19.3/go.mod h1:ra8V3UAsciBpJKQ+z9Whkxzxv7jmQg1hfODr3N3YPJ4=\ncloud.google.com/go/dataflow v0.6.0/go.mod h1:9QwV89cGoxjjSR9/r7eFDqqjtvbKxAK2BaYU6PVk9UM=\ncloud.google.com/go/dataflow v0.7.0/go.mod h1:PX526vb4ijFMesO1o202EaUmouZKBpjHsTlCtB4parQ=\ncloud.google.com/go/dataflow v0.8.0/go.mod h1:Rcf5YgTKPtQyYz8bLYhFoIV/vP39eL7fWNcSOyFfLJE=\ncloud.google.com/go/dataflow v0.9.5/go.mod h1:udl6oi8pfUHnL0z6UN9Lf9chGqzDMVqcYTcZ1aPnCZQ=\ncloud.google.com/go/dataform v0.3.0/go.mod h1:cj8uNliRlHpa6L3yVhDOBrUXH+BPAO1+KFMQQNSThKo=\ncloud.google.com/go/dataform v0.4.0/go.mod h1:fwV6Y4Ty2yIFL89huYlEkwUPtS7YZinZbzzj5S9FzCE=\ncloud.google.com/go/dataform v0.5.0/go.mod h1:GFUYRe8IBa2hcomWplodVmUx/iTL0FrsauObOM3Ipr0=\ncloud.google.com/go/dataform v0.6.0/go.mod h1:QPflImQy33e29VuapFdf19oPbE4aYTJxr31OAPV+ulA=\ncloud.google.com/go/dataform v0.7.0/go.mod h1:7NulqnVozfHvWUBpMDfKMUESr+85aJsC/2O0o3jWPDE=\ncloud.google.com/go/dataform v0.9.2/go.mod h1:S8cQUwPNWXo7m/g3DhWHsLBoufRNn9EgFrMgne2j7cI=\ncloud.google.com/go/datafusion v1.4.0/go.mod h1:1Zb6VN+W6ALo85cXnM1IKiPw+yQMKMhB9TsTSRDo/38=\ncloud.google.com/go/datafusion v1.5.0/go.mod h1:Kz+l1FGHB0J+4XF2fud96WMmRiq/wj8N9u007vyXZ2w=\ncloud.google.com/go/datafusion v1.6.0/go.mod h1:WBsMF8F1RhSXvVM8rCV3AeyWVxcC2xY6vith3iw3S+8=\ncloud.google.com/go/datafusion v1.7.5/go.mod h1:bYH53Oa5UiqahfbNK9YuYKteeD4RbQSNMx7JF7peGHc=\ncloud.google.com/go/datalabeling v0.5.0/go.mod h1:TGcJ0G2NzcsXSE/97yWjIZO0bXj0KbVlINXMG9ud42I=\ncloud.google.com/go/datalabeling v0.6.0/go.mod h1:WqdISuk/+WIGeMkpw/1q7bK/tFEZxsrFJOJdY2bXvTQ=\ncloud.google.com/go/datalabeling v0.7.0/go.mod h1:WPQb1y08RJbmpM3ww0CSUAGweL0SxByuW2E+FU+wXcM=\ncloud.google.com/go/datalabeling v0.8.5/go.mod h1:IABB2lxQnkdUbMnQaOl2prCOfms20mcPxDBm36lps+s=\ncloud.google.com/go/dataplex v1.3.0/go.mod h1:hQuRtDg+fCiFgC8j0zV222HvzFQdRd+SVX8gdmFcZzA=\ncloud.google.com/go/dataplex v1.4.0/go.mod h1:X51GfLXEMVJ6UN47ESVqvlsRplbLhcsAt0kZCCKsU0A=\ncloud.google.com/go/dataplex v1.5.2/go.mod h1:cVMgQHsmfRoI5KFYq4JtIBEUbYwc3c7tXmIDhRmNNVQ=\ncloud.google.com/go/dataplex v1.6.0/go.mod h1:bMsomC/aEJOSpHXdFKFGQ1b0TDPIeL28nJObeO1ppRs=\ncloud.google.com/go/dataplex v1.14.2/go.mod h1:0oGOSFlEKef1cQeAHXy4GZPB/Ife0fz/PxBf+ZymA2U=\ncloud.google.com/go/dataproc v1.7.0/go.mod h1:CKAlMjII9H90RXaMpSxQ8EU6dQx6iAYNPcYPOkSbi8s=\ncloud.google.com/go/dataproc v1.8.0/go.mod h1:5OW+zNAH0pMpw14JVrPONsxMQYMBqJuzORhIBfBn9uI=\ncloud.google.com/go/dataproc v1.12.0/go.mod h1:zrF3aX0uV3ikkMz6z4uBbIKyhRITnxvr4i3IjKsKrw4=\ncloud.google.com/go/dataproc/v2 v2.4.0/go.mod h1:3B1Ht2aRB8VZIteGxQS/iNSJGzt9+CA0WGnDVMEm7Z4=\ncloud.google.com/go/dataqna v0.5.0/go.mod h1:90Hyk596ft3zUQ8NkFfvICSIfHFh1Bc7C4cK3vbhkeo=\ncloud.google.com/go/dataqna v0.6.0/go.mod h1:1lqNpM7rqNLVgWBJyk5NF6Uen2PHym0jtVJonplVsDA=\ncloud.google.com/go/dataqna v0.7.0/go.mod h1:Lx9OcIIeqCrw1a6KdO3/5KMP1wAmTc0slZWwP12Qq3c=\ncloud.google.com/go/dataqna v0.8.5/go.mod h1:vgihg1mz6n7pb5q2YJF7KlXve6tCglInd6XO0JGOlWM=\ncloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE=\ncloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk=\ncloud.google.com/go/datastore v1.10.0/go.mod h1:PC5UzAmDEkAmkfaknstTYbNpgE49HAgW2J1gcgUfmdM=\ncloud.google.com/go/datastore v1.15.0/go.mod h1:GAeStMBIt9bPS7jMJA85kgkpsMkvseWWXiaHya9Jes8=\ncloud.google.com/go/datastream v1.2.0/go.mod h1:i/uTP8/fZwgATHS/XFu0TcNUhuA0twZxxQ3EyCUQMwo=\ncloud.google.com/go/datastream v1.3.0/go.mod h1:cqlOX8xlyYF/uxhiKn6Hbv6WjwPPuI9W2M9SAXwaLLQ=\ncloud.google.com/go/datastream v1.4.0/go.mod h1:h9dpzScPhDTs5noEMQVWP8Wx8AFBRyS0s8KWPx/9r0g=\ncloud.google.com/go/datastream v1.5.0/go.mod h1:6TZMMNPwjUqZHBKPQ1wwXpb0d5VDVPl2/XoS5yi88q4=\ncloud.google.com/go/datastream v1.6.0/go.mod h1:6LQSuswqLa7S4rPAOZFVjHIG3wJIjZcZrw8JDEDJuIs=\ncloud.google.com/go/datastream v1.7.0/go.mod h1:uxVRMm2elUSPuh65IbZpzJNMbuzkcvu5CjMqVIUHrww=\ncloud.google.com/go/datastream v1.10.4/go.mod h1:7kRxPdxZxhPg3MFeCSulmAJnil8NJGGvSNdn4p1sRZo=\ncloud.google.com/go/deploy v1.4.0/go.mod h1:5Xghikd4VrmMLNaF6FiRFDlHb59VM59YoDQnOUdsH/c=\ncloud.google.com/go/deploy v1.5.0/go.mod h1:ffgdD0B89tToyW/U/D2eL0jN2+IEV/3EMuXHA0l4r+s=\ncloud.google.com/go/deploy v1.6.0/go.mod h1:f9PTHehG/DjCom3QH0cntOVRm93uGBDt2vKzAPwpXQI=\ncloud.google.com/go/deploy v1.8.0/go.mod h1:z3myEJnA/2wnB4sgjqdMfgxCA0EqC3RBTNcVPs93mtQ=\ncloud.google.com/go/deploy v1.17.1/go.mod h1:SXQyfsXrk0fBmgBHRzBjQbZhMfKZ3hMQBw5ym7MN/50=\ncloud.google.com/go/dialogflow v1.15.0/go.mod h1:HbHDWs33WOGJgn6rfzBW1Kv807BE3O1+xGbn59zZWI4=\ncloud.google.com/go/dialogflow v1.16.1/go.mod h1:po6LlzGfK+smoSmTBnbkIZY2w8ffjz/RcGSS+sh1el0=\ncloud.google.com/go/dialogflow v1.17.0/go.mod h1:YNP09C/kXA1aZdBgC/VtXX74G/TKn7XVCcVumTflA+8=\ncloud.google.com/go/dialogflow v1.18.0/go.mod h1:trO7Zu5YdyEuR+BhSNOqJezyFQ3aUzz0njv7sMx/iek=\ncloud.google.com/go/dialogflow v1.19.0/go.mod h1:JVmlG1TwykZDtxtTXujec4tQ+D8SBFMoosgy+6Gn0s0=\ncloud.google.com/go/dialogflow v1.29.0/go.mod h1:b+2bzMe+k1s9V+F2jbJwpHPzrnIyHihAdRFMtn2WXuM=\ncloud.google.com/go/dialogflow v1.31.0/go.mod h1:cuoUccuL1Z+HADhyIA7dci3N5zUssgpBJmCzI6fNRB4=\ncloud.google.com/go/dialogflow v1.32.0/go.mod h1:jG9TRJl8CKrDhMEcvfcfFkkpp8ZhgPz3sBGmAUYJ2qE=\ncloud.google.com/go/dialogflow v1.49.0/go.mod h1:dhVrXKETtdPlpPhE7+2/k4Z8FRNUp6kMV3EW3oz/fe0=\ncloud.google.com/go/dlp v1.6.0/go.mod h1:9eyB2xIhpU0sVwUixfBubDoRwP+GjeUoxxeueZmqvmM=\ncloud.google.com/go/dlp v1.7.0/go.mod h1:68ak9vCiMBjbasxeVD17hVPxDEck+ExiHavX8kiHG+Q=\ncloud.google.com/go/dlp v1.9.0/go.mod h1:qdgmqgTyReTz5/YNSSuueR8pl7hO0o9bQ39ZhtgkWp4=\ncloud.google.com/go/dlp v1.11.2/go.mod h1:9Czi+8Y/FegpWzgSfkRlyz+jwW6Te9Rv26P3UfU/h/w=\ncloud.google.com/go/documentai v1.7.0/go.mod h1:lJvftZB5NRiFSX4moiye1SMxHx0Bc3x1+p9e/RfXYiU=\ncloud.google.com/go/documentai v1.8.0/go.mod h1:xGHNEB7CtsnySCNrCFdCyyMz44RhFEEX2Q7UD0c5IhU=\ncloud.google.com/go/documentai v1.9.0/go.mod h1:FS5485S8R00U10GhgBC0aNGrJxBP8ZVpEeJ7PQDZd6k=\ncloud.google.com/go/documentai v1.10.0/go.mod h1:vod47hKQIPeCfN2QS/jULIvQTugbmdc0ZvxxfQY1bg4=\ncloud.google.com/go/documentai v1.16.0/go.mod h1:o0o0DLTEZ+YnJZ+J4wNfTxmDVyrkzFvttBXXtYRMHkM=\ncloud.google.com/go/documentai v1.18.0/go.mod h1:F6CK6iUH8J81FehpskRmhLq/3VlwQvb7TvwOceQ2tbs=\ncloud.google.com/go/documentai v1.25.0/go.mod h1:ftLnzw5VcXkLItp6pw1mFic91tMRyfv6hHEY5br4KzY=\ncloud.google.com/go/domains v0.6.0/go.mod h1:T9Rz3GasrpYk6mEGHh4rymIhjlnIuB4ofT1wTxDeT4Y=\ncloud.google.com/go/domains v0.7.0/go.mod h1:PtZeqS1xjnXuRPKE/88Iru/LdfoRyEHYA9nFQf4UKpg=\ncloud.google.com/go/domains v0.8.0/go.mod h1:M9i3MMDzGFXsydri9/vW+EWz9sWb4I6WyHqdlAk0idE=\ncloud.google.com/go/domains v0.9.5/go.mod h1:dBzlxgepazdFhvG7u23XMhmMKBjrkoUNaw0A8AQB55Y=\ncloud.google.com/go/edgecontainer v0.1.0/go.mod h1:WgkZ9tp10bFxqO8BLPqv2LlfmQF1X8lZqwW4r1BTajk=\ncloud.google.com/go/edgecontainer v0.2.0/go.mod h1:RTmLijy+lGpQ7BXuTDa4C4ssxyXT34NIuHIgKuP4s5w=\ncloud.google.com/go/edgecontainer v0.3.0/go.mod h1:FLDpP4nykgwwIfcLt6zInhprzw0lEi2P1fjO6Ie0qbc=\ncloud.google.com/go/edgecontainer v1.0.0/go.mod h1:cttArqZpBB2q58W/upSG++ooo6EsblxDIolxa3jSjbY=\ncloud.google.com/go/edgecontainer v1.1.5/go.mod h1:rgcjrba3DEDEQAidT4yuzaKWTbkTI5zAMu3yy6ZWS0M=\ncloud.google.com/go/errorreporting v0.3.0/go.mod h1:xsP2yaAp+OAW4OIm60An2bbLpqIhKXdWR/tawvl7QzU=\ncloud.google.com/go/essentialcontacts v1.3.0/go.mod h1:r+OnHa5jfj90qIfZDO/VztSFqbQan7HV75p8sA+mdGI=\ncloud.google.com/go/essentialcontacts v1.4.0/go.mod h1:8tRldvHYsmnBCHdFpvU+GL75oWiBKl80BiqlFh9tp+8=\ncloud.google.com/go/essentialcontacts v1.5.0/go.mod h1:ay29Z4zODTuwliK7SnX8E86aUF2CTzdNtvv42niCX0M=\ncloud.google.com/go/essentialcontacts v1.6.6/go.mod h1:XbqHJGaiH0v2UvtuucfOzFXN+rpL/aU5BCZLn4DYl1Q=\ncloud.google.com/go/eventarc v1.7.0/go.mod h1:6ctpF3zTnaQCxUjHUdcfgcA1A2T309+omHZth7gDfmc=\ncloud.google.com/go/eventarc v1.8.0/go.mod h1:imbzxkyAU4ubfsaKYdQg04WS1NvncblHEup4kvF+4gw=\ncloud.google.com/go/eventarc v1.10.0/go.mod h1:u3R35tmZ9HvswGRBnF48IlYgYeBcPUCjkr4BTdem2Kw=\ncloud.google.com/go/eventarc v1.11.0/go.mod h1:PyUjsUKPWoRBCHeOxZd/lbOOjahV41icXyUY5kSTvVY=\ncloud.google.com/go/eventarc v1.13.4/go.mod h1:zV5sFVoAa9orc/52Q+OuYUG9xL2IIZTbbuTHC6JSY8s=\ncloud.google.com/go/filestore v1.3.0/go.mod h1:+qbvHGvXU1HaKX2nD0WEPo92TP/8AQuCVEBXNY9z0+w=\ncloud.google.com/go/filestore v1.4.0/go.mod h1:PaG5oDfo9r224f8OYXURtAsY+Fbyq/bLYoINEK8XQAI=\ncloud.google.com/go/filestore v1.5.0/go.mod h1:FqBXDWBp4YLHqRnVGveOkHDf8svj9r5+mUDLupOWEDs=\ncloud.google.com/go/filestore v1.6.0/go.mod h1:di5unNuss/qfZTw2U9nhFqo8/ZDSc466dre85Kydllg=\ncloud.google.com/go/filestore v1.8.1/go.mod h1:MbN9KcaM47DRTIuLfQhJEsjaocVebNtNQhSLhKCF5GM=\ncloud.google.com/go/firestore v1.9.0/go.mod h1:HMkjKHNTtRyZNiMzu7YAsLr9K3X2udY2AMwDaMEQiiE=\ncloud.google.com/go/firestore v1.14.0/go.mod h1:96MVaHLsEhbvkBEdZgfN+AS/GIkco1LRpH9Xp9YZfzQ=\ncloud.google.com/go/functions v1.6.0/go.mod h1:3H1UA3qiIPRWD7PeZKLvHZ9SaQhR26XIJcC0A5GbvAk=\ncloud.google.com/go/functions v1.7.0/go.mod h1:+d+QBcWM+RsrgZfV9xo6KfA1GlzJfxcfZcRPEhDDfzg=\ncloud.google.com/go/functions v1.8.0/go.mod h1:RTZ4/HsQjIqIYP9a9YPbU+QFoQsAlYgrwOXJWHn1POY=\ncloud.google.com/go/functions v1.9.0/go.mod h1:Y+Dz8yGguzO3PpIjhLTbnqV1CWmgQ5UwtlpzoyquQ08=\ncloud.google.com/go/functions v1.10.0/go.mod h1:0D3hEOe3DbEvCXtYOZHQZmD+SzYsi1YbI7dGvHfldXw=\ncloud.google.com/go/functions v1.12.0/go.mod h1:AXWGrF3e2C/5ehvwYo/GH6O5s09tOPksiKhz+hH8WkA=\ncloud.google.com/go/functions v1.16.0/go.mod h1:nbNpfAG7SG7Duw/o1iZ6ohvL7mc6MapWQVpqtM29n8k=\ncloud.google.com/go/gaming v1.5.0/go.mod h1:ol7rGcxP/qHTRQE/RO4bxkXq+Fix0j6D4LFPzYTIrDM=\ncloud.google.com/go/gaming v1.6.0/go.mod h1:YMU1GEvA39Qt3zWGyAVA9bpYz/yAhTvaQ1t2sK4KPUA=\ncloud.google.com/go/gaming v1.7.0/go.mod h1:LrB8U7MHdGgFG851iHAfqUdLcKBdQ55hzXy9xBJz0+w=\ncloud.google.com/go/gaming v1.8.0/go.mod h1:xAqjS8b7jAVW0KFYeRUxngo9My3f33kFmua++Pi+ggM=\ncloud.google.com/go/gaming v1.9.0/go.mod h1:Fc7kEmCObylSWLO334NcO+O9QMDyz+TKC4v1D7X+Bc0=\ncloud.google.com/go/gaming v1.10.1/go.mod h1:XQQvtfP8Rb9Rxnxm5wFVpAp9zCQkJi2bLIb7iHGwB3s=\ncloud.google.com/go/gkebackup v0.2.0/go.mod h1:XKvv/4LfG829/B8B7xRkk8zRrOEbKtEam6yNfuQNH60=\ncloud.google.com/go/gkebackup v0.3.0/go.mod h1:n/E671i1aOQvUxT541aTkCwExO/bTer2HDlj4TsBRAo=\ncloud.google.com/go/gkebackup v0.4.0/go.mod h1:byAyBGUwYGEEww7xsbnUTBHIYcOPy/PgUWUtOeRm9Vg=\ncloud.google.com/go/gkebackup v1.3.5/go.mod h1:KJ77KkNN7Wm1LdMopOelV6OodM01pMuK2/5Zt1t4Tvc=\ncloud.google.com/go/gkeconnect v0.5.0/go.mod h1:c5lsNAg5EwAy7fkqX/+goqFsU1Da/jQFqArp+wGNr/o=\ncloud.google.com/go/gkeconnect v0.6.0/go.mod h1:Mln67KyU/sHJEBY8kFZ0xTeyPtzbq9StAVvEULYK16A=\ncloud.google.com/go/gkeconnect v0.7.0/go.mod h1:SNfmVqPkaEi3bF/B3CNZOAYPYdg7sU+obZ+QTky2Myw=\ncloud.google.com/go/gkeconnect v0.8.5/go.mod h1:LC/rS7+CuJ5fgIbXv8tCD/mdfnlAadTaUufgOkmijuk=\ncloud.google.com/go/gkehub v0.9.0/go.mod h1:WYHN6WG8w9bXU0hqNxt8rm5uxnk8IH+lPY9J2TV7BK0=\ncloud.google.com/go/gkehub v0.10.0/go.mod h1:UIPwxI0DsrpsVoWpLB0stwKCP+WFVG9+y977wO+hBH0=\ncloud.google.com/go/gkehub v0.11.0/go.mod h1:JOWHlmN+GHyIbuWQPl47/C2RFhnFKH38jH9Ascu3n0E=\ncloud.google.com/go/gkehub v0.12.0/go.mod h1:djiIwwzTTBrF5NaXCGv3mf7klpEMcST17VBTVVDcuaw=\ncloud.google.com/go/gkehub v0.14.5/go.mod h1:6bzqxM+a+vEH/h8W8ec4OJl4r36laxTs3A/fMNHJ0wA=\ncloud.google.com/go/gkemulticloud v0.3.0/go.mod h1:7orzy7O0S+5kq95e4Hpn7RysVA7dPs8W/GgfUtsPbrA=\ncloud.google.com/go/gkemulticloud v0.4.0/go.mod h1:E9gxVBnseLWCk24ch+P9+B2CoDFJZTyIgLKSalC7tuI=\ncloud.google.com/go/gkemulticloud v0.5.0/go.mod h1:W0JDkiyi3Tqh0TJr//y19wyb1yf8llHVto2Htf2Ja3Y=\ncloud.google.com/go/gkemulticloud v1.1.1/go.mod h1:C+a4vcHlWeEIf45IB5FFR5XGjTeYhF83+AYIpTy4i2Q=\ncloud.google.com/go/grafeas v0.2.0/go.mod h1:KhxgtF2hb0P191HlY5besjYm6MqTSTj3LSI+M+ByZHc=\ncloud.google.com/go/grafeas v0.3.4/go.mod h1:A5m316hcG+AulafjAbPKXBO/+I5itU4LOdKO2R/uDIc=\ncloud.google.com/go/gsuiteaddons v1.3.0/go.mod h1:EUNK/J1lZEZO8yPtykKxLXI6JSVN2rg9bN8SXOa0bgM=\ncloud.google.com/go/gsuiteaddons v1.4.0/go.mod h1:rZK5I8hht7u7HxFQcFei0+AtfS9uSushomRlg+3ua1o=\ncloud.google.com/go/gsuiteaddons v1.5.0/go.mod h1:TFCClYLd64Eaa12sFVmUyG62tk4mdIsI7pAnSXRkcFo=\ncloud.google.com/go/gsuiteaddons v1.6.5/go.mod h1:Lo4P2IvO8uZ9W+RaC6s1JVxo42vgy+TX5a6hfBZ0ubs=\ncloud.google.com/go/iam v0.1.0/go.mod h1:vcUNEa0pEm0qRVpmWepWaFMIAI8/hjB9mO8rNCJtF6c=\ncloud.google.com/go/iam v0.3.0/go.mod h1:XzJPvDayI+9zsASAFO68Hk07u3z+f+JrT2xXNdp4bnY=\ncloud.google.com/go/iam v0.5.0/go.mod h1:wPU9Vt0P4UmCux7mqtRu6jcpPAb74cP1fh50J3QpkUc=\ncloud.google.com/go/iam v0.6.0/go.mod h1:+1AH33ueBne5MzYccyMHtEKqLE4/kJOibtffMHDMFMc=\ncloud.google.com/go/iam v0.7.0/go.mod h1:H5Br8wRaDGNc8XP3keLc4unfUUZeyH3Sfl9XpQEYOeg=\ncloud.google.com/go/iam v0.8.0/go.mod h1:lga0/y3iH6CX7sYqypWJ33hf7kkfXJag67naqGESjkE=\ncloud.google.com/go/iam v0.11.0/go.mod h1:9PiLDanza5D+oWFZiH1uG+RnRCfEGKoyl6yo4cgWZGY=\ncloud.google.com/go/iam v0.12.0/go.mod h1:knyHGviacl11zrtZUoDuYpDgLjvr28sLQaG0YB2GYAY=\ncloud.google.com/go/iam v0.13.0/go.mod h1:ljOg+rcNfzZ5d6f1nAUJ8ZIxOaZUVoS14bKCtaLZ/D0=\ncloud.google.com/go/iam v1.1.6/go.mod h1:O0zxdPeGBoFdWW3HWmBxJsk0pfvNM/p/qa82rWOGTwI=\ncloud.google.com/go/iap v1.4.0/go.mod h1:RGFwRJdihTINIe4wZ2iCP0zF/qu18ZwyKxrhMhygBEc=\ncloud.google.com/go/iap v1.5.0/go.mod h1:UH/CGgKd4KyohZL5Pt0jSKE4m3FR51qg6FKQ/z/Ix9A=\ncloud.google.com/go/iap v1.6.0/go.mod h1:NSuvI9C/j7UdjGjIde7t7HBz+QTwBcapPE07+sSRcLk=\ncloud.google.com/go/iap v1.7.0/go.mod h1:beqQx56T9O1G1yNPph+spKpNibDlYIiIixiqsQXxLIo=\ncloud.google.com/go/iap v1.9.4/go.mod h1:vO4mSq0xNf/Pu6E5paORLASBwEmphXEjgCFg7aeNu1w=\ncloud.google.com/go/ids v1.1.0/go.mod h1:WIuwCaYVOzHIj2OhN9HAwvW+DBdmUAdcWlFxRl+KubM=\ncloud.google.com/go/ids v1.2.0/go.mod h1:5WXvp4n25S0rA/mQWAg1YEEBBq6/s+7ml1RDCW1IrcY=\ncloud.google.com/go/ids v1.3.0/go.mod h1:JBdTYwANikFKaDP6LtW5JAi4gubs57SVNQjemdt6xV4=\ncloud.google.com/go/ids v1.4.5/go.mod h1:p0ZnyzjMWxww6d2DvMGnFwCsSxDJM666Iir1bK1UuBo=\ncloud.google.com/go/iot v1.3.0/go.mod h1:r7RGh2B61+B8oz0AGE+J72AhA0G7tdXItODWsaA2oLs=\ncloud.google.com/go/iot v1.4.0/go.mod h1:dIDxPOn0UvNDUMD8Ger7FIaTuvMkj+aGk94RPP0iV+g=\ncloud.google.com/go/iot v1.5.0/go.mod h1:mpz5259PDl3XJthEmh9+ap0affn/MqNSP4My77Qql9o=\ncloud.google.com/go/iot v1.6.0/go.mod h1:IqdAsmE2cTYYNO1Fvjfzo9po179rAtJeVGUvkLN3rLE=\ncloud.google.com/go/iot v1.7.5/go.mod h1:nq3/sqTz3HGaWJi1xNiX7F41ThOzpud67vwk0YsSsqs=\ncloud.google.com/go/kms v1.4.0/go.mod h1:fajBHndQ+6ubNw6Ss2sSd+SWvjL26RNo/dr7uxsnnOA=\ncloud.google.com/go/kms v1.5.0/go.mod h1:QJS2YY0eJGBg3mnDfuaCyLauWwBJiHRboYxJ++1xJNg=\ncloud.google.com/go/kms v1.6.0/go.mod h1:Jjy850yySiasBUDi6KFUwUv2n1+o7QZFyuUJg6OgjA0=\ncloud.google.com/go/kms v1.8.0/go.mod h1:4xFEhYFqvW+4VMELtZyxomGSYtSQKzM178ylFW4jMAg=\ncloud.google.com/go/kms v1.9.0/go.mod h1:qb1tPTgfF9RQP8e1wq4cLFErVuTJv7UsSC915J8dh3w=\ncloud.google.com/go/kms v1.10.0/go.mod h1:ng3KTUtQQU9bPX3+QGLsflZIHlkbn8amFAMY63m8d24=\ncloud.google.com/go/kms v1.15.7/go.mod h1:ub54lbsa6tDkUwnu4W7Yt1aAIFLnspgh0kPGToDukeI=\ncloud.google.com/go/language v1.4.0/go.mod h1:F9dRpNFQmJbkaop6g0JhSBXCNlO90e1KWx5iDdxbWic=\ncloud.google.com/go/language v1.6.0/go.mod h1:6dJ8t3B+lUYfStgls25GusK04NLh3eDLQnWM3mdEbhI=\ncloud.google.com/go/language v1.7.0/go.mod h1:DJ6dYN/W+SQOjF8e1hLQXMF21AkH2w9wiPzPCJa2MIE=\ncloud.google.com/go/language v1.8.0/go.mod h1:qYPVHf7SPoNNiCL2Dr0FfEFNil1qi3pQEyygwpgVKB8=\ncloud.google.com/go/language v1.9.0/go.mod h1:Ns15WooPM5Ad/5no/0n81yUetis74g3zrbeJBE+ptUY=\ncloud.google.com/go/language v1.12.3/go.mod h1:evFX9wECX6mksEva8RbRnr/4wi/vKGYnAJrTRXU8+f8=\ncloud.google.com/go/lifesciences v0.5.0/go.mod h1:3oIKy8ycWGPUyZDR/8RNnTOYevhaMLqh5vLUXs9zvT8=\ncloud.google.com/go/lifesciences v0.6.0/go.mod h1:ddj6tSX/7BOnhxCSd3ZcETvtNr8NZ6t/iPhY2Tyfu08=\ncloud.google.com/go/lifesciences v0.8.0/go.mod h1:lFxiEOMqII6XggGbOnKiyZ7IBwoIqA84ClvoezaA/bo=\ncloud.google.com/go/lifesciences v0.9.5/go.mod h1:OdBm0n7C0Osh5yZB7j9BXyrMnTRGBJIZonUMxo5CzPw=\ncloud.google.com/go/logging v1.6.1/go.mod h1:5ZO0mHHbvm8gEmeEUHrmDlTDSu5imF6MUP9OfilNXBw=\ncloud.google.com/go/logging v1.7.0/go.mod h1:3xjP2CjkM3ZkO73aj4ASA5wRPGGCRrPIAeNqVNkzY8M=\ncloud.google.com/go/logging v1.9.0/go.mod h1:1Io0vnZv4onoUnsVUQY3HZ3Igb1nBchky0A0y7BBBhE=\ncloud.google.com/go/longrunning v0.1.1/go.mod h1:UUFxuDWkv22EuY93jjmDMFT5GPQKeFVJBIF6QlTqdsE=\ncloud.google.com/go/longrunning v0.3.0/go.mod h1:qth9Y41RRSUE69rDcOn6DdK3HfQfsUI0YSmW3iIlLJc=\ncloud.google.com/go/longrunning v0.4.1/go.mod h1:4iWDqhBZ70CvZ6BfETbvam3T8FMvLK+eFj0E6AaRQTo=\ncloud.google.com/go/longrunning v0.5.5/go.mod h1:WV2LAxD8/rg5Z1cNW6FJ/ZpX4E4VnDnoTk0yawPBB7s=\ncloud.google.com/go/managedidentities v1.3.0/go.mod h1:UzlW3cBOiPrzucO5qWkNkh0w33KFtBJU281hacNvsdE=\ncloud.google.com/go/managedidentities v1.4.0/go.mod h1:NWSBYbEMgqmbZsLIyKvxrYbtqOsxY1ZrGM+9RgDqInM=\ncloud.google.com/go/managedidentities v1.5.0/go.mod h1:+dWcZ0JlUmpuxpIDfyP5pP5y0bLdRwOS4Lp7gMni/LA=\ncloud.google.com/go/managedidentities v1.6.5/go.mod h1:fkFI2PwwyRQbjLxlm5bQ8SjtObFMW3ChBGNqaMcgZjI=\ncloud.google.com/go/maps v0.1.0/go.mod h1:BQM97WGyfw9FWEmQMpZ5T6cpovXXSd1cGmFma94eubI=\ncloud.google.com/go/maps v0.6.0/go.mod h1:o6DAMMfb+aINHz/p/jbcY+mYeXBoZoxTfdSQ8VAJaCw=\ncloud.google.com/go/maps v0.7.0/go.mod h1:3GnvVl3cqeSvgMcpRlQidXsPYuDGQ8naBis7MVzpXsY=\ncloud.google.com/go/maps v1.6.4/go.mod h1:rhjqRy8NWmDJ53saCfsXQ0LKwBHfi6OSh5wkq6BaMhI=\ncloud.google.com/go/mediatranslation v0.5.0/go.mod h1:jGPUhGTybqsPQn91pNXw0xVHfuJ3leR1wj37oU3y1f4=\ncloud.google.com/go/mediatranslation v0.6.0/go.mod h1:hHdBCTYNigsBxshbznuIMFNe5QXEowAuNmmC7h8pu5w=\ncloud.google.com/go/mediatranslation v0.7.0/go.mod h1:LCnB/gZr90ONOIQLgSXagp8XUW1ODs2UmUMvcgMfI2I=\ncloud.google.com/go/mediatranslation v0.8.5/go.mod h1:y7kTHYIPCIfgyLbKncgqouXJtLsU+26hZhHEEy80fSs=\ncloud.google.com/go/memcache v1.4.0/go.mod h1:rTOfiGZtJX1AaFUrOgsMHX5kAzaTQ8azHiuDoTPzNsE=\ncloud.google.com/go/memcache v1.5.0/go.mod h1:dk3fCK7dVo0cUU2c36jKb4VqKPS22BTkf81Xq617aWM=\ncloud.google.com/go/memcache v1.6.0/go.mod h1:XS5xB0eQZdHtTuTF9Hf8eJkKtR3pVRCcvJwtm68T3rA=\ncloud.google.com/go/memcache v1.7.0/go.mod h1:ywMKfjWhNtkQTxrWxCkCFkoPjLHPW6A7WOTVI8xy3LY=\ncloud.google.com/go/memcache v1.9.0/go.mod h1:8oEyzXCu+zo9RzlEaEjHl4KkgjlNDaXbCQeQWlzNFJM=\ncloud.google.com/go/memcache v1.10.5/go.mod h1:/FcblbNd0FdMsx4natdj+2GWzTq+cjZvMa1I+9QsuMA=\ncloud.google.com/go/metastore v1.5.0/go.mod h1:2ZNrDcQwghfdtCwJ33nM0+GrBGlVuh8rakL3vdPY3XY=\ncloud.google.com/go/metastore v1.6.0/go.mod h1:6cyQTls8CWXzk45G55x57DVQ9gWg7RiH65+YgPsNh9s=\ncloud.google.com/go/metastore v1.7.0/go.mod h1:s45D0B4IlsINu87/AsWiEVYbLaIMeUSoxlKKDqBGFS8=\ncloud.google.com/go/metastore v1.8.0/go.mod h1:zHiMc4ZUpBiM7twCIFQmJ9JMEkDSyZS9U12uf7wHqSI=\ncloud.google.com/go/metastore v1.10.0/go.mod h1:fPEnH3g4JJAk+gMRnrAnoqyv2lpUCqJPWOodSaf45Eo=\ncloud.google.com/go/metastore v1.13.4/go.mod h1:FMv9bvPInEfX9Ac1cVcRXp8EBBQnBcqH6gz3KvJ9BAE=\ncloud.google.com/go/monitoring v1.7.0/go.mod h1:HpYse6kkGo//7p6sT0wsIC6IBDET0RhIsnmlA53dvEk=\ncloud.google.com/go/monitoring v1.8.0/go.mod h1:E7PtoMJ1kQXWxPjB6mv2fhC5/15jInuulFdYYtlcvT4=\ncloud.google.com/go/monitoring v1.12.0/go.mod h1:yx8Jj2fZNEkL/GYZyTLS4ZtZEZN8WtDEiEqG4kLK50w=\ncloud.google.com/go/monitoring v1.13.0/go.mod h1:k2yMBAB1H9JT/QETjNkgdCGD9bPF712XiLTVr+cBrpw=\ncloud.google.com/go/monitoring v1.18.0/go.mod h1:c92vVBCeq/OB4Ioyo+NbN2U7tlg5ZH41PZcdvfc+Lcg=\ncloud.google.com/go/networkconnectivity v1.4.0/go.mod h1:nOl7YL8odKyAOtzNX73/M5/mGZgqqMeryi6UPZTk/rA=\ncloud.google.com/go/networkconnectivity v1.5.0/go.mod h1:3GzqJx7uhtlM3kln0+x5wyFvuVH1pIBJjhCpjzSt75o=\ncloud.google.com/go/networkconnectivity v1.6.0/go.mod h1:OJOoEXW+0LAxHh89nXd64uGG+FbQoeH8DtxCHVOMlaM=\ncloud.google.com/go/networkconnectivity v1.7.0/go.mod h1:RMuSbkdbPwNMQjB5HBWD5MpTBnNm39iAVpC3TmsExt8=\ncloud.google.com/go/networkconnectivity v1.10.0/go.mod h1:UP4O4sWXJG13AqrTdQCD9TnLGEbtNRqjuaaA7bNjF5E=\ncloud.google.com/go/networkconnectivity v1.11.0/go.mod h1:iWmDD4QF16VCDLXUqvyspJjIEtBR/4zq5hwnY2X3scM=\ncloud.google.com/go/networkconnectivity v1.14.4/go.mod h1:PU12q++/IMnDJAB+3r+tJtuCXCfwfN+C6Niyj6ji1Po=\ncloud.google.com/go/networkmanagement v1.4.0/go.mod h1:Q9mdLLRn60AsOrPc8rs8iNV6OHXaGcDdsIQe1ohekq8=\ncloud.google.com/go/networkmanagement v1.5.0/go.mod h1:ZnOeZ/evzUdUsnvRt792H0uYEnHQEMaz+REhhzJRcf4=\ncloud.google.com/go/networkmanagement v1.6.0/go.mod h1:5pKPqyXjB/sgtvB5xqOemumoQNB7y95Q7S+4rjSOPYY=\ncloud.google.com/go/networkmanagement v1.9.4/go.mod h1:daWJAl0KTFytFL7ar33I6R/oNBH8eEOX/rBNHrC/8TA=\ncloud.google.com/go/networksecurity v0.5.0/go.mod h1:xS6fOCoqpVC5zx15Z/MqkfDwH4+m/61A3ODiDV1xmiQ=\ncloud.google.com/go/networksecurity v0.6.0/go.mod h1:Q5fjhTr9WMI5mbpRYEbiexTzROf7ZbDzvzCrNl14nyU=\ncloud.google.com/go/networksecurity v0.7.0/go.mod h1:mAnzoxx/8TBSyXEeESMy9OOYwo1v+gZ5eMRnsT5bC8k=\ncloud.google.com/go/networksecurity v0.8.0/go.mod h1:B78DkqsxFG5zRSVuwYFRZ9Xz8IcQ5iECsNrPn74hKHU=\ncloud.google.com/go/networksecurity v0.9.5/go.mod h1:KNkjH/RsylSGyyZ8wXpue8xpCEK+bTtvof8SBfIhMG8=\ncloud.google.com/go/notebooks v1.2.0/go.mod h1:9+wtppMfVPUeJ8fIWPOq1UnATHISkGXGqTkxeieQ6UY=\ncloud.google.com/go/notebooks v1.3.0/go.mod h1:bFR5lj07DtCPC7YAAJ//vHskFBxA5JzYlH68kXVdk34=\ncloud.google.com/go/notebooks v1.4.0/go.mod h1:4QPMngcwmgb6uw7Po99B2xv5ufVoIQ7nOGDyL4P8AgA=\ncloud.google.com/go/notebooks v1.5.0/go.mod h1:q8mwhnP9aR8Hpfnrc5iN5IBhrXUy8S2vuYs+kBJ/gu0=\ncloud.google.com/go/notebooks v1.7.0/go.mod h1:PVlaDGfJgj1fl1S3dUwhFMXFgfYGhYQt2164xOMONmE=\ncloud.google.com/go/notebooks v1.8.0/go.mod h1:Lq6dYKOYOWUCTvw5t2q1gp1lAp0zxAxRycayS0iJcqQ=\ncloud.google.com/go/notebooks v1.11.3/go.mod h1:0wQyI2dQC3AZyQqWnRsp+yA+kY4gC7ZIVP4Qg3AQcgo=\ncloud.google.com/go/optimization v1.1.0/go.mod h1:5po+wfvX5AQlPznyVEZjGJTMr4+CAkJf2XSTQOOl9l4=\ncloud.google.com/go/optimization v1.2.0/go.mod h1:Lr7SOHdRDENsh+WXVmQhQTrzdu9ybg0NecjHidBq6xs=\ncloud.google.com/go/optimization v1.3.1/go.mod h1:IvUSefKiwd1a5p0RgHDbWCIbDFgKuEdB+fPPuP0IDLI=\ncloud.google.com/go/optimization v1.6.3/go.mod h1:8ve3svp3W6NFcAEFr4SfJxrldzhUl4VMUJmhrqVKtYA=\ncloud.google.com/go/orchestration v1.3.0/go.mod h1:Sj5tq/JpWiB//X/q3Ngwdl5K7B7Y0KZ7bfv0wL6fqVA=\ncloud.google.com/go/orchestration v1.4.0/go.mod h1:6W5NLFWs2TlniBphAViZEVhrXRSMgUGDfW7vrWKvsBk=\ncloud.google.com/go/orchestration v1.6.0/go.mod h1:M62Bevp7pkxStDfFfTuCOaXgaaqRAga1yKyoMtEoWPQ=\ncloud.google.com/go/orchestration v1.8.5/go.mod h1:C1J7HesE96Ba8/hZ71ISTV2UAat0bwN+pi85ky38Yq8=\ncloud.google.com/go/orgpolicy v1.4.0/go.mod h1:xrSLIV4RePWmP9P3tBl8S93lTmlAxjm06NSm2UTmKvE=\ncloud.google.com/go/orgpolicy v1.5.0/go.mod h1:hZEc5q3wzwXJaKrsx5+Ewg0u1LxJ51nNFlext7Tanwc=\ncloud.google.com/go/orgpolicy v1.10.0/go.mod h1:w1fo8b7rRqlXlIJbVhOMPrwVljyuW5mqssvBtU18ONc=\ncloud.google.com/go/orgpolicy v1.12.1/go.mod h1:aibX78RDl5pcK3jA8ysDQCFkVxLj3aOQqrbBaUL2V5I=\ncloud.google.com/go/osconfig v1.7.0/go.mod h1:oVHeCeZELfJP7XLxcBGTMBvRO+1nQ5tFG9VQTmYS2Fs=\ncloud.google.com/go/osconfig v1.8.0/go.mod h1:EQqZLu5w5XA7eKizepumcvWx+m8mJUhEwiPqWiZeEdg=\ncloud.google.com/go/osconfig v1.9.0/go.mod h1:Yx+IeIZJ3bdWmzbQU4fxNl8xsZ4amB+dygAwFPlvnNo=\ncloud.google.com/go/osconfig v1.10.0/go.mod h1:uMhCzqC5I8zfD9zDEAfvgVhDS8oIjySWh+l4WK6GnWw=\ncloud.google.com/go/osconfig v1.11.0/go.mod h1:aDICxrur2ogRd9zY5ytBLV89KEgT2MKB2L/n6x1ooPw=\ncloud.google.com/go/osconfig v1.12.5/go.mod h1:D9QFdxzfjgw3h/+ZaAb5NypM8bhOMqBzgmbhzWViiW8=\ncloud.google.com/go/oslogin v1.4.0/go.mod h1:YdgMXWRaElXz/lDk1Na6Fh5orF7gvmJ0FGLIs9LId4E=\ncloud.google.com/go/oslogin v1.5.0/go.mod h1:D260Qj11W2qx/HVF29zBg+0fd6YCSjSqLUkY/qEenQU=\ncloud.google.com/go/oslogin v1.6.0/go.mod h1:zOJ1O3+dTU8WPlGEkFSh7qeHPPSoxrcMbbK1Nm2iX70=\ncloud.google.com/go/oslogin v1.7.0/go.mod h1:e04SN0xO1UNJ1M5GP0vzVBFicIe4O53FOfcixIqTyXo=\ncloud.google.com/go/oslogin v1.9.0/go.mod h1:HNavntnH8nzrn8JCTT5fj18FuJLFJc4NaZJtBnQtKFs=\ncloud.google.com/go/oslogin v1.13.1/go.mod h1:vS8Sr/jR7QvPWpCjNqy6LYZr5Zs1e8ZGW/KPn9gmhws=\ncloud.google.com/go/phishingprotection v0.5.0/go.mod h1:Y3HZknsK9bc9dMi+oE8Bim0lczMU6hrX0UpADuMefr0=\ncloud.google.com/go/phishingprotection v0.6.0/go.mod h1:9Y3LBLgy0kDTcYET8ZH3bq/7qni15yVUoAxiFxnlSUA=\ncloud.google.com/go/phishingprotection v0.7.0/go.mod h1:8qJI4QKHoda/sb/7/YmMQ2omRLSLYSu9bU0EKCNI+Lk=\ncloud.google.com/go/phishingprotection v0.8.5/go.mod h1:g1smd68F7mF1hgQPuYn3z8HDbNre8L6Z0b7XMYFmX7I=\ncloud.google.com/go/policytroubleshooter v1.3.0/go.mod h1:qy0+VwANja+kKrjlQuOzmlvscn4RNsAc0e15GGqfMxg=\ncloud.google.com/go/policytroubleshooter v1.4.0/go.mod h1:DZT4BcRw3QoO8ota9xw/LKtPa8lKeCByYeKTIf/vxdE=\ncloud.google.com/go/policytroubleshooter v1.5.0/go.mod h1:Rz1WfV+1oIpPdN2VvvuboLVRsB1Hclg3CKQ53j9l8vw=\ncloud.google.com/go/policytroubleshooter v1.6.0/go.mod h1:zYqaPTsmfvpjm5ULxAyD/lINQxJ0DDsnWOP/GZ7xzBc=\ncloud.google.com/go/policytroubleshooter v1.10.3/go.mod h1:+ZqG3agHT7WPb4EBIRqUv4OyIwRTZvsVDHZ8GlZaoxk=\ncloud.google.com/go/privatecatalog v0.5.0/go.mod h1:XgosMUvvPyxDjAVNDYxJ7wBW8//hLDDYmnsNcMGq1K0=\ncloud.google.com/go/privatecatalog v0.6.0/go.mod h1:i/fbkZR0hLN29eEWiiwue8Pb+GforiEIBnV9yrRUOKI=\ncloud.google.com/go/privatecatalog v0.7.0/go.mod h1:2s5ssIFO69F5csTXcwBP7NPFTZvps26xGzvQ2PQaBYg=\ncloud.google.com/go/privatecatalog v0.8.0/go.mod h1:nQ6pfaegeDAq/Q5lrfCQzQLhubPiZhSaNhIgfJlnIXs=\ncloud.google.com/go/privatecatalog v0.9.5/go.mod h1:fVWeBOVe7uj2n3kWRGlUQqR/pOd450J9yZoOECcQqJk=\ncloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I=\ncloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw=\ncloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA=\ncloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU=\ncloud.google.com/go/pubsub v1.26.0/go.mod h1:QgBH3U/jdJy/ftjPhTkyXNj543Tin1pRYcdcPRnFIRI=\ncloud.google.com/go/pubsub v1.27.1/go.mod h1:hQN39ymbV9geqBnfQq6Xf63yNhUAhv9CZhzp5O6qsW0=\ncloud.google.com/go/pubsub v1.28.0/go.mod h1:vuXFpwaVoIPQMGXqRyUQigu/AX1S3IWugR9xznmcXX8=\ncloud.google.com/go/pubsub v1.30.0/go.mod h1:qWi1OPS0B+b5L+Sg6Gmc9zD1Y+HaM0MdUr7LsupY1P4=\ncloud.google.com/go/pubsub v1.36.1/go.mod h1:iYjCa9EzWOoBiTdd4ps7QoMtMln5NwaZQpK1hbRfBDE=\ncloud.google.com/go/pubsublite v1.5.0/go.mod h1:xapqNQ1CuLfGi23Yda/9l4bBCKz/wC3KIJ5gKcxveZg=\ncloud.google.com/go/pubsublite v1.6.0/go.mod h1:1eFCS0U11xlOuMFV/0iBqw3zP12kddMeCbj/F3FSj9k=\ncloud.google.com/go/pubsublite v1.7.0/go.mod h1:8hVMwRXfDfvGm3fahVbtDbiLePT3gpoiJYJY+vxWxVM=\ncloud.google.com/go/pubsublite v1.8.1/go.mod h1:fOLdU4f5xldK4RGJrBMm+J7zMWNj/k4PxwEZXy39QS0=\ncloud.google.com/go/recaptchaenterprise v1.3.1/go.mod h1:OdD+q+y4XGeAlxRaMn1Y7/GveP6zmq76byL6tjPE7d4=\ncloud.google.com/go/recaptchaenterprise/v2 v2.1.0/go.mod h1:w9yVqajwroDNTfGuhmOjPDN//rZGySaf6PtFVcSCa7o=\ncloud.google.com/go/recaptchaenterprise/v2 v2.2.0/go.mod h1:/Zu5jisWGeERrd5HnlS3EUGb/D335f9k51B/FVil0jk=\ncloud.google.com/go/recaptchaenterprise/v2 v2.3.0/go.mod h1:O9LwGCjrhGHBQET5CA7dd5NwwNQUErSgEDit1DLNTdo=\ncloud.google.com/go/recaptchaenterprise/v2 v2.4.0/go.mod h1:Am3LHfOuBstrLrNCBrlI5sbwx9LBg3te2N6hGvHn2mE=\ncloud.google.com/go/recaptchaenterprise/v2 v2.5.0/go.mod h1:O8LzcHXN3rz0j+LBC91jrwI3R+1ZSZEWrfL7XHgNo9U=\ncloud.google.com/go/recaptchaenterprise/v2 v2.6.0/go.mod h1:RPauz9jeLtB3JVzg6nCbe12qNoaa8pXc4d/YukAmcnA=\ncloud.google.com/go/recaptchaenterprise/v2 v2.7.0/go.mod h1:19wVj/fs5RtYtynAPJdDTb69oW0vNHYDBTbB4NvMD9c=\ncloud.google.com/go/recaptchaenterprise/v2 v2.9.2/go.mod h1:trwwGkfhCmp05Ll5MSJPXY7yvnO0p4v3orGANAFHAuU=\ncloud.google.com/go/recommendationengine v0.5.0/go.mod h1:E5756pJcVFeVgaQv3WNpImkFP8a+RptV6dDLGPILjvg=\ncloud.google.com/go/recommendationengine v0.6.0/go.mod h1:08mq2umu9oIqc7tDy8sx+MNJdLG0fUi3vaSVbztHgJ4=\ncloud.google.com/go/recommendationengine v0.7.0/go.mod h1:1reUcE3GIu6MeBz/h5xZJqNLuuVjNg1lmWMPyjatzac=\ncloud.google.com/go/recommendationengine v0.8.5/go.mod h1:A38rIXHGFvoPvmy6pZLozr0g59NRNREz4cx7F58HAsQ=\ncloud.google.com/go/recommender v1.5.0/go.mod h1:jdoeiBIVrJe9gQjwd759ecLJbxCDED4A6p+mqoqDvTg=\ncloud.google.com/go/recommender v1.6.0/go.mod h1:+yETpm25mcoiECKh9DEScGzIRyDKpZ0cEhWGo+8bo+c=\ncloud.google.com/go/recommender v1.7.0/go.mod h1:XLHs/W+T8olwlGOgfQenXBTbIseGclClff6lhFVe9Bs=\ncloud.google.com/go/recommender v1.8.0/go.mod h1:PkjXrTT05BFKwxaUxQmtIlrtj0kph108r02ZZQ5FE70=\ncloud.google.com/go/recommender v1.9.0/go.mod h1:PnSsnZY7q+VL1uax2JWkt/UegHssxjUVVCrX52CuEmQ=\ncloud.google.com/go/recommender v1.12.1/go.mod h1:gf95SInWNND5aPas3yjwl0I572dtudMhMIG4ni8nr+0=\ncloud.google.com/go/redis v1.7.0/go.mod h1:V3x5Jq1jzUcg+UNsRvdmsfuFnit1cfe3Z/PGyq/lm4Y=\ncloud.google.com/go/redis v1.8.0/go.mod h1:Fm2szCDavWzBk2cDKxrkmWBqoCiL1+Ctwq7EyqBCA/A=\ncloud.google.com/go/redis v1.9.0/go.mod h1:HMYQuajvb2D0LvMgZmLDZW8V5aOC/WxstZHiy4g8OiA=\ncloud.google.com/go/redis v1.10.0/go.mod h1:ThJf3mMBQtW18JzGgh41/Wld6vnDDc/F/F35UolRZPM=\ncloud.google.com/go/redis v1.11.0/go.mod h1:/X6eicana+BWcUda5PpwZC48o37SiFVTFSs0fWAJ7uQ=\ncloud.google.com/go/redis v1.14.2/go.mod h1:g0Lu7RRRz46ENdFKQ2EcQZBAJ2PtJHJLuiiRuEXwyQw=\ncloud.google.com/go/resourcemanager v1.3.0/go.mod h1:bAtrTjZQFJkiWTPDb1WBjzvc6/kifjj4QBYuKCCoqKA=\ncloud.google.com/go/resourcemanager v1.4.0/go.mod h1:MwxuzkumyTX7/a3n37gmsT3py7LIXwrShilPh3P1tR0=\ncloud.google.com/go/resourcemanager v1.5.0/go.mod h1:eQoXNAiAvCf5PXxWxXjhKQoTMaUSNrEfg+6qdf/wots=\ncloud.google.com/go/resourcemanager v1.6.0/go.mod h1:YcpXGRs8fDzcUl1Xw8uOVmI8JEadvhRIkoXXUNVYcVo=\ncloud.google.com/go/resourcemanager v1.9.5/go.mod h1:hep6KjelHA+ToEjOfO3garMKi/CLYwTqeAw7YiEI9x8=\ncloud.google.com/go/resourcesettings v1.3.0/go.mod h1:lzew8VfESA5DQ8gdlHwMrqZs1S9V87v3oCnKCWoOuQU=\ncloud.google.com/go/resourcesettings v1.4.0/go.mod h1:ldiH9IJpcrlC3VSuCGvjR5of/ezRrOxFtpJoJo5SmXg=\ncloud.google.com/go/resourcesettings v1.5.0/go.mod h1:+xJF7QSG6undsQDfsCJyqWXyBwUoJLhetkRMDRnIoXA=\ncloud.google.com/go/resourcesettings v1.6.5/go.mod h1:WBOIWZraXZOGAgoR4ukNj0o0HiSMO62H9RpFi9WjP9I=\ncloud.google.com/go/retail v1.8.0/go.mod h1:QblKS8waDmNUhghY2TI9O3JLlFk8jybHeV4BF19FrE4=\ncloud.google.com/go/retail v1.9.0/go.mod h1:g6jb6mKuCS1QKnH/dpu7isX253absFl6iE92nHwlBUY=\ncloud.google.com/go/retail v1.10.0/go.mod h1:2gDk9HsL4HMS4oZwz6daui2/jmKvqShXKQuB2RZ+cCc=\ncloud.google.com/go/retail v1.11.0/go.mod h1:MBLk1NaWPmh6iVFSz9MeKG/Psyd7TAgm6y/9L2B4x9Y=\ncloud.google.com/go/retail v1.12.0/go.mod h1:UMkelN/0Z8XvKymXFbD4EhFJlYKRx1FGhQkVPU5kF14=\ncloud.google.com/go/retail v1.16.0/go.mod h1:LW7tllVveZo4ReWt68VnldZFWJRzsh9np+01J9dYWzE=\ncloud.google.com/go/run v0.2.0/go.mod h1:CNtKsTA1sDcnqqIFR3Pb5Tq0usWxJJvsWOCPldRU3Do=\ncloud.google.com/go/run v0.3.0/go.mod h1:TuyY1+taHxTjrD0ZFk2iAR+xyOXEA0ztb7U3UNA0zBo=\ncloud.google.com/go/run v0.8.0/go.mod h1:VniEnuBwqjigv0A7ONfQUaEItaiCRVujlMqerPPiktM=\ncloud.google.com/go/run v0.9.0/go.mod h1:Wwu+/vvg8Y+JUApMwEDfVfhetv30hCG4ZwDR/IXl2Qg=\ncloud.google.com/go/run v1.3.4/go.mod h1:FGieuZvQ3tj1e9GnzXqrMABSuir38AJg5xhiYq+SF3o=\ncloud.google.com/go/scheduler v1.4.0/go.mod h1:drcJBmxF3aqZJRhmkHQ9b3uSSpQoltBPGPxGAWROx6s=\ncloud.google.com/go/scheduler v1.5.0/go.mod h1:ri073ym49NW3AfT6DZi21vLZrG07GXr5p3H1KxN5QlI=\ncloud.google.com/go/scheduler v1.6.0/go.mod h1:SgeKVM7MIwPn3BqtcBntpLyrIJftQISRrYB5ZtT+KOk=\ncloud.google.com/go/scheduler v1.7.0/go.mod h1:jyCiBqWW956uBjjPMMuX09n3x37mtyPJegEWKxRsn44=\ncloud.google.com/go/scheduler v1.8.0/go.mod h1:TCET+Y5Gp1YgHT8py4nlg2Sew8nUHMqcpousDgXJVQc=\ncloud.google.com/go/scheduler v1.9.0/go.mod h1:yexg5t+KSmqu+njTIh3b7oYPheFtBWGcbVUYF1GGMIc=\ncloud.google.com/go/scheduler v1.10.6/go.mod h1:pe2pNCtJ+R01E06XCDOJs1XvAMbv28ZsQEbqknxGOuE=\ncloud.google.com/go/secretmanager v1.6.0/go.mod h1:awVa/OXF6IiyaU1wQ34inzQNc4ISIDIrId8qE5QGgKA=\ncloud.google.com/go/secretmanager v1.8.0/go.mod h1:hnVgi/bN5MYHd3Gt0SPuTPPp5ENina1/LxM+2W9U9J4=\ncloud.google.com/go/secretmanager v1.9.0/go.mod h1:b71qH2l1yHmWQHt9LC80akm86mX8AL6X1MA01dW8ht4=\ncloud.google.com/go/secretmanager v1.10.0/go.mod h1:MfnrdvKMPNra9aZtQFvBcvRU54hbPD8/HayQdlUgJpU=\ncloud.google.com/go/secretmanager v1.11.5/go.mod h1:eAGv+DaCHkeVyQi0BeXgAHOU0RdrMeZIASKc+S7VqH4=\ncloud.google.com/go/security v1.5.0/go.mod h1:lgxGdyOKKjHL4YG3/YwIL2zLqMFCKs0UbQwgyZmfJl4=\ncloud.google.com/go/security v1.7.0/go.mod h1:mZklORHl6Bg7CNnnjLH//0UlAlaXqiG7Lb9PsPXLfD0=\ncloud.google.com/go/security v1.8.0/go.mod h1:hAQOwgmaHhztFhiQ41CjDODdWP0+AE1B3sX4OFlq+GU=\ncloud.google.com/go/security v1.9.0/go.mod h1:6Ta1bO8LXI89nZnmnsZGp9lVoVWXqsVbIq/t9dzI+2Q=\ncloud.google.com/go/security v1.10.0/go.mod h1:QtOMZByJVlibUT2h9afNDWRZ1G96gVywH8T5GUSb9IA=\ncloud.google.com/go/security v1.12.0/go.mod h1:rV6EhrpbNHrrxqlvW0BWAIawFWq3X90SduMJdFwtLB8=\ncloud.google.com/go/security v1.13.0/go.mod h1:Q1Nvxl1PAgmeW0y3HTt54JYIvUdtcpYKVfIB8AOMZ+0=\ncloud.google.com/go/security v1.15.5/go.mod h1:KS6X2eG3ynWjqcIX976fuToN5juVkF6Ra6c7MPnldtc=\ncloud.google.com/go/securitycenter v1.13.0/go.mod h1:cv5qNAqjY84FCN6Y9z28WlkKXyWsgLO832YiWwkCWcU=\ncloud.google.com/go/securitycenter v1.14.0/go.mod h1:gZLAhtyKv85n52XYWt6RmeBdydyxfPeTrpToDPw4Auc=\ncloud.google.com/go/securitycenter v1.15.0/go.mod h1:PeKJ0t8MoFmmXLXWm41JidyzI3PJjd8sXWaVqg43WWk=\ncloud.google.com/go/securitycenter v1.16.0/go.mod h1:Q9GMaLQFUD+5ZTabrbujNWLtSLZIZF7SAR0wWECrjdk=\ncloud.google.com/go/securitycenter v1.18.1/go.mod h1:0/25gAzCM/9OL9vVx4ChPeM/+DlfGQJDwBy/UC8AKK0=\ncloud.google.com/go/securitycenter v1.19.0/go.mod h1:LVLmSg8ZkkyaNy4u7HCIshAngSQ8EcIRREP3xBnyfag=\ncloud.google.com/go/securitycenter v1.24.4/go.mod h1:PSccin+o1EMYKcFQzz9HMMnZ2r9+7jbc+LvPjXhpwcU=\ncloud.google.com/go/servicecontrol v1.4.0/go.mod h1:o0hUSJ1TXJAmi/7fLJAedOovnujSEvjKCAFNXPQ1RaU=\ncloud.google.com/go/servicecontrol v1.5.0/go.mod h1:qM0CnXHhyqKVuiZnGKrIurvVImCs8gmqWsDoqe9sU1s=\ncloud.google.com/go/servicecontrol v1.10.0/go.mod h1:pQvyvSRh7YzUF2efw7H87V92mxU8FnFDawMClGCNuAA=\ncloud.google.com/go/servicecontrol v1.11.0/go.mod h1:kFmTzYzTUIuZs0ycVqRHNaNhgR+UMUpw9n02l/pY+mc=\ncloud.google.com/go/servicecontrol v1.11.1/go.mod h1:aSnNNlwEFBY+PWGQ2DoM0JJ/QUXqV5/ZD9DOLB7SnUk=\ncloud.google.com/go/servicedirectory v1.4.0/go.mod h1:gH1MUaZCgtP7qQiI+F+A+OpeKF/HQWgtAddhTbhL2bs=\ncloud.google.com/go/servicedirectory v1.5.0/go.mod h1:QMKFL0NUySbpZJ1UZs3oFAmdvVxhhxB6eJ/Vlp73dfg=\ncloud.google.com/go/servicedirectory v1.6.0/go.mod h1:pUlbnWsLH9c13yGkxCmfumWEPjsRs1RlmJ4pqiNjVL4=\ncloud.google.com/go/servicedirectory v1.7.0/go.mod h1:5p/U5oyvgYGYejufvxhgwjL8UVXjkuw7q5XcG10wx1U=\ncloud.google.com/go/servicedirectory v1.8.0/go.mod h1:srXodfhY1GFIPvltunswqXpVxFPpZjf8nkKQT7XcXaY=\ncloud.google.com/go/servicedirectory v1.9.0/go.mod h1:29je5JjiygNYlmsGz8k6o+OZ8vd4f//bQLtvzkPPT/s=\ncloud.google.com/go/servicedirectory v1.11.4/go.mod h1:Bz2T9t+/Ehg6x+Y7Ycq5xiShYLD96NfEsWNHyitj1qM=\ncloud.google.com/go/servicemanagement v1.4.0/go.mod h1:d8t8MDbezI7Z2R1O/wu8oTggo3BI2GKYbdG4y/SJTco=\ncloud.google.com/go/servicemanagement v1.5.0/go.mod h1:XGaCRe57kfqu4+lRxaFEAuqmjzF0r+gWHjWqKqBvKFo=\ncloud.google.com/go/servicemanagement v1.6.0/go.mod h1:aWns7EeeCOtGEX4OvZUWCCJONRZeFKiptqKf1D0l/Jc=\ncloud.google.com/go/servicemanagement v1.8.0/go.mod h1:MSS2TDlIEQD/fzsSGfCdJItQveu9NXnUniTrq/L8LK4=\ncloud.google.com/go/serviceusage v1.3.0/go.mod h1:Hya1cozXM4SeSKTAgGXgj97GlqUvF5JaoXacR1JTP/E=\ncloud.google.com/go/serviceusage v1.4.0/go.mod h1:SB4yxXSaYVuUBYUml6qklyONXNLt83U0Rb+CXyhjEeU=\ncloud.google.com/go/serviceusage v1.5.0/go.mod h1:w8U1JvqUqwJNPEOTQjrMHkw3IaIFLoLsPLvsE3xueec=\ncloud.google.com/go/serviceusage v1.6.0/go.mod h1:R5wwQcbOWsyuOfbP9tGdAnCAc6B9DRwPG1xtWMDeuPA=\ncloud.google.com/go/shell v1.3.0/go.mod h1:VZ9HmRjZBsjLGXusm7K5Q5lzzByZmJHf1d0IWHEN5X4=\ncloud.google.com/go/shell v1.4.0/go.mod h1:HDxPzZf3GkDdhExzD/gs8Grqk+dmYcEjGShZgYa9URw=\ncloud.google.com/go/shell v1.6.0/go.mod h1:oHO8QACS90luWgxP3N9iZVuEiSF84zNyLytb+qE2f9A=\ncloud.google.com/go/shell v1.7.5/go.mod h1:hL2++7F47/IfpfTO53KYf1EC+F56k3ThfNEXd4zcuiE=\ncloud.google.com/go/spanner v1.41.0/go.mod h1:MLYDBJR/dY4Wt7ZaMIQ7rXOTLjYrmxLE/5ve9vFfWos=\ncloud.google.com/go/spanner v1.44.0/go.mod h1:G8XIgYdOK+Fbcpbs7p2fiprDw4CaZX63whnSMLVBxjk=\ncloud.google.com/go/spanner v1.56.0/go.mod h1:DndqtUKQAt3VLuV2Le+9Y3WTnq5cNKrnLb/Piqcj+h0=\ncloud.google.com/go/speech v1.6.0/go.mod h1:79tcr4FHCimOp56lwC01xnt/WPJZc4v3gzyT7FoBkCM=\ncloud.google.com/go/speech v1.7.0/go.mod h1:KptqL+BAQIhMsj1kOP2la5DSEEerPDuOP/2mmkhHhZQ=\ncloud.google.com/go/speech v1.8.0/go.mod h1:9bYIl1/tjsAnMgKGHKmBZzXKEkGgtU+MpdDPTE9f7y0=\ncloud.google.com/go/speech v1.9.0/go.mod h1:xQ0jTcmnRFFM2RfX/U+rk6FQNUF6DQlydUSyoooSpco=\ncloud.google.com/go/speech v1.14.1/go.mod h1:gEosVRPJ9waG7zqqnsHpYTOoAS4KouMRLDFMekpJ0J0=\ncloud.google.com/go/speech v1.15.0/go.mod h1:y6oH7GhqCaZANH7+Oe0BhgIogsNInLlz542tg3VqeYI=\ncloud.google.com/go/speech v1.21.1/go.mod h1:E5GHZXYQlkqWQwY5xRSLHw2ci5NMQNG52FfMU1aZrIA=\ncloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw=\ncloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos=\ncloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk=\ncloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs=\ncloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0=\ncloud.google.com/go/storage v1.14.0/go.mod h1:GrKmX003DSIwi9o29oFT7YDnHYwZoctc3fOKtUw0Xmo=\ncloud.google.com/go/storage v1.22.1/go.mod h1:S8N1cAStu7BOeFfE8KAQzmyyLkK8p/vmRq6kuBTW58Y=\ncloud.google.com/go/storage v1.23.0/go.mod h1:vOEEDNFnciUMhBeT6hsJIn3ieU5cFRmzeLgDvXzfIXc=\ncloud.google.com/go/storage v1.27.0/go.mod h1:x9DOL8TK/ygDUMieqwfhdpQryTeEkhGKMi80i/iqR2s=\ncloud.google.com/go/storage v1.28.1/go.mod h1:Qnisd4CqDdo6BGs2AD5LLnEsmSQ80wQ5ogcBBKhU86Y=\ncloud.google.com/go/storage v1.29.0/go.mod h1:4puEjyTKnku6gfKoTfNOU/W+a9JyuVNxjpS5GBrB8h4=\ncloud.google.com/go/storage v1.38.0/go.mod h1:tlUADB0mAb9BgYls9lq+8MGkfzOXuLrnHXlpHmvFJoY=\ncloud.google.com/go/storagetransfer v1.5.0/go.mod h1:dxNzUopWy7RQevYFHewchb29POFv3/AaBgnhqzqiK0w=\ncloud.google.com/go/storagetransfer v1.6.0/go.mod h1:y77xm4CQV/ZhFZH75PLEXY0ROiS7Gh6pSKrM8dJyg6I=\ncloud.google.com/go/storagetransfer v1.7.0/go.mod h1:8Giuj1QNb1kfLAiWM1bN6dHzfdlDAVC9rv9abHot2W4=\ncloud.google.com/go/storagetransfer v1.8.0/go.mod h1:JpegsHHU1eXg7lMHkvf+KE5XDJ7EQu0GwNJbbVGanEw=\ncloud.google.com/go/storagetransfer v1.10.4/go.mod h1:vef30rZKu5HSEf/x1tK3WfWrL0XVoUQN/EPDRGPzjZs=\ncloud.google.com/go/talent v1.1.0/go.mod h1:Vl4pt9jiHKvOgF9KoZo6Kob9oV4lwd/ZD5Cto54zDRw=\ncloud.google.com/go/talent v1.2.0/go.mod h1:MoNF9bhFQbiJ6eFD3uSsg0uBALw4n4gaCaEjBw9zo8g=\ncloud.google.com/go/talent v1.3.0/go.mod h1:CmcxwJ/PKfRgd1pBjQgU6W3YBwiewmUzQYH5HHmSCmM=\ncloud.google.com/go/talent v1.4.0/go.mod h1:ezFtAgVuRf8jRsvyE6EwmbTK5LKciD4KVnHuDEFmOOA=\ncloud.google.com/go/talent v1.5.0/go.mod h1:G+ODMj9bsasAEJkQSzO2uHQWXHHXUomArjWQQYkqK6c=\ncloud.google.com/go/talent v1.6.6/go.mod h1:y/WQDKrhVz12WagoarpAIyKKMeKGKHWPoReZ0g8tseQ=\ncloud.google.com/go/texttospeech v1.4.0/go.mod h1:FX8HQHA6sEpJ7rCMSfXuzBcysDAuWusNNNvN9FELDd8=\ncloud.google.com/go/texttospeech v1.5.0/go.mod h1:oKPLhR4n4ZdQqWKURdwxMy0uiTS1xU161C8W57Wkea4=\ncloud.google.com/go/texttospeech v1.6.0/go.mod h1:YmwmFT8pj1aBblQOI3TfKmwibnsfvhIBzPXcW4EBovc=\ncloud.google.com/go/texttospeech v1.7.5/go.mod h1:tzpCuNWPwrNJnEa4Pu5taALuZL4QRRLcb+K9pbhXT6M=\ncloud.google.com/go/tpu v1.3.0/go.mod h1:aJIManG0o20tfDQlRIej44FcwGGl/cD0oiRyMKG19IQ=\ncloud.google.com/go/tpu v1.4.0/go.mod h1:mjZaX8p0VBgllCzF6wcU2ovUXN9TONFLd7iz227X2Xg=\ncloud.google.com/go/tpu v1.5.0/go.mod h1:8zVo1rYDFuW2l4yZVY0R0fb/v44xLh3llq7RuV61fPM=\ncloud.google.com/go/tpu v1.6.5/go.mod h1:P9DFOEBIBhuEcZhXi+wPoVy/cji+0ICFi4TtTkMHSSs=\ncloud.google.com/go/trace v1.3.0/go.mod h1:FFUE83d9Ca57C+K8rDl/Ih8LwOzWIV1krKgxg6N0G28=\ncloud.google.com/go/trace v1.4.0/go.mod h1:UG0v8UBqzusp+z63o7FK74SdFE+AXpCLdFb1rshXG+Y=\ncloud.google.com/go/trace v1.8.0/go.mod h1:zH7vcsbAhklH8hWFig58HvxcxyQbaIqMarMg9hn5ECA=\ncloud.google.com/go/trace v1.9.0/go.mod h1:lOQqpE5IaWY0Ixg7/r2SjixMuc6lfTFeO4QGM4dQWOk=\ncloud.google.com/go/trace v1.10.5/go.mod h1:9hjCV1nGBCtXbAE4YK7OqJ8pmPYSxPA0I67JwRd5s3M=\ncloud.google.com/go/translate v1.3.0/go.mod h1:gzMUwRjvOqj5i69y/LYLd8RrNQk+hOmIXTi9+nb3Djs=\ncloud.google.com/go/translate v1.4.0/go.mod h1:06Dn/ppvLD6WvA5Rhdp029IX2Mi3Mn7fpMRLPvXT5Wg=\ncloud.google.com/go/translate v1.5.0/go.mod h1:29YDSYveqqpA1CQFD7NQuP49xymq17RXNaUDdc0mNu0=\ncloud.google.com/go/translate v1.6.0/go.mod h1:lMGRudH1pu7I3n3PETiOB2507gf3HnfLV8qlkHZEyos=\ncloud.google.com/go/translate v1.7.0/go.mod h1:lMGRudH1pu7I3n3PETiOB2507gf3HnfLV8qlkHZEyos=\ncloud.google.com/go/translate v1.10.1/go.mod h1:adGZcQNom/3ogU65N9UXHOnnSvjPwA/jKQUMnsYXOyk=\ncloud.google.com/go/video v1.8.0/go.mod h1:sTzKFc0bUSByE8Yoh8X0mn8bMymItVGPfTuUBUyRgxk=\ncloud.google.com/go/video v1.9.0/go.mod h1:0RhNKFRF5v92f8dQt0yhaHrEuH95m068JYOvLZYnJSw=\ncloud.google.com/go/video v1.12.0/go.mod h1:MLQew95eTuaNDEGriQdcYn0dTwf9oWiA4uYebxM5kdg=\ncloud.google.com/go/video v1.13.0/go.mod h1:ulzkYlYgCp15N2AokzKjy7MQ9ejuynOJdf1tR5lGthk=\ncloud.google.com/go/video v1.14.0/go.mod h1:SkgaXwT+lIIAKqWAJfktHT/RbgjSuY6DobxEp0C5yTQ=\ncloud.google.com/go/video v1.20.4/go.mod h1:LyUVjyW+Bwj7dh3UJnUGZfyqjEto9DnrvTe1f/+QrW0=\ncloud.google.com/go/videointelligence v1.6.0/go.mod h1:w0DIDlVRKtwPCn/C4iwZIJdvC69yInhW0cfi+p546uU=\ncloud.google.com/go/videointelligence v1.7.0/go.mod h1:k8pI/1wAhjznARtVT9U1llUaFNPh7muw8QyOUpavru4=\ncloud.google.com/go/videointelligence v1.8.0/go.mod h1:dIcCn4gVDdS7yte/w+koiXn5dWVplOZkE+xwG9FgK+M=\ncloud.google.com/go/videointelligence v1.9.0/go.mod h1:29lVRMPDYHikk3v8EdPSaL8Ku+eMzDljjuvRs105XoU=\ncloud.google.com/go/videointelligence v1.10.0/go.mod h1:LHZngX1liVtUhZvi2uNS0VQuOzNi2TkY1OakiuoUOjU=\ncloud.google.com/go/videointelligence v1.11.5/go.mod h1:/PkeQjpRponmOerPeJxNPuxvi12HlW7Em0lJO14FC3I=\ncloud.google.com/go/vision v1.2.0/go.mod h1:SmNwgObm5DpFBme2xpyOyasvBc1aPdjvMk2bBk0tKD0=\ncloud.google.com/go/vision/v2 v2.2.0/go.mod h1:uCdV4PpN1S0jyCyq8sIM42v2Y6zOLkZs+4R9LrGYwFo=\ncloud.google.com/go/vision/v2 v2.3.0/go.mod h1:UO61abBx9QRMFkNBbf1D8B1LXdS2cGiiCRx0vSpZoUo=\ncloud.google.com/go/vision/v2 v2.4.0/go.mod h1:VtI579ll9RpVTrdKdkMzckdnwMyX2JILb+MhPqRbPsY=\ncloud.google.com/go/vision/v2 v2.5.0/go.mod h1:MmaezXOOE+IWa+cS7OhRRLK2cNv1ZL98zhqFFZaaH2E=\ncloud.google.com/go/vision/v2 v2.6.0/go.mod h1:158Hes0MvOS9Z/bDMSFpjwsUrZ5fPrdwuyyvKSGAGMY=\ncloud.google.com/go/vision/v2 v2.7.0/go.mod h1:H89VysHy21avemp6xcf9b9JvZHVehWbET0uT/bcuY/0=\ncloud.google.com/go/vision/v2 v2.8.0/go.mod h1:ocqDiA2j97pvgogdyhoxiQp2ZkDCyr0HWpicywGGRhU=\ncloud.google.com/go/vmmigration v1.2.0/go.mod h1:IRf0o7myyWFSmVR1ItrBSFLFD/rJkfDCUTO4vLlJvsE=\ncloud.google.com/go/vmmigration v1.3.0/go.mod h1:oGJ6ZgGPQOFdjHuocGcLqX4lc98YQ7Ygq8YQwHh9A7g=\ncloud.google.com/go/vmmigration v1.5.0/go.mod h1:E4YQ8q7/4W9gobHjQg4JJSgXXSgY21nA5r8swQV+Xxc=\ncloud.google.com/go/vmmigration v1.6.0/go.mod h1:bopQ/g4z+8qXzichC7GW1w2MjbErL54rk3/C843CjfY=\ncloud.google.com/go/vmmigration v1.7.5/go.mod h1:pkvO6huVnVWzkFioxSghZxIGcsstDvYiVCxQ9ZH3eYI=\ncloud.google.com/go/vmwareengine v0.1.0/go.mod h1:RsdNEf/8UDvKllXhMz5J40XxDrNJNN4sagiox+OI208=\ncloud.google.com/go/vmwareengine v0.2.2/go.mod h1:sKdctNJxb3KLZkE/6Oui94iw/xs9PRNC2wnNLXsHvH8=\ncloud.google.com/go/vmwareengine v0.3.0/go.mod h1:wvoyMvNWdIzxMYSpH/R7y2h5h3WFkx6d+1TIsP39WGY=\ncloud.google.com/go/vmwareengine v1.1.1/go.mod h1:nMpdsIVkUrSaX8UvmnBhzVzG7PPvNYc5BszcvIVudYs=\ncloud.google.com/go/vpcaccess v1.4.0/go.mod h1:aQHVbTWDYUR1EbTApSVvMq1EnT57ppDmQzZ3imqIk4w=\ncloud.google.com/go/vpcaccess v1.5.0/go.mod h1:drmg4HLk9NkZpGfCmZ3Tz0Bwnm2+DKqViEpeEpOq0m8=\ncloud.google.com/go/vpcaccess v1.6.0/go.mod h1:wX2ILaNhe7TlVa4vC5xce1bCnqE3AeH27RV31lnmZes=\ncloud.google.com/go/vpcaccess v1.7.5/go.mod h1:slc5ZRvvjP78c2dnL7m4l4R9GwL3wDLcpIWz6P/ziig=\ncloud.google.com/go/webrisk v1.4.0/go.mod h1:Hn8X6Zr+ziE2aNd8SliSDWpEnSS1u4R9+xXZmFiHmGE=\ncloud.google.com/go/webrisk v1.5.0/go.mod h1:iPG6fr52Tv7sGk0H6qUFzmL3HHZev1htXuWDEEsqMTg=\ncloud.google.com/go/webrisk v1.6.0/go.mod h1:65sW9V9rOosnc9ZY7A7jsy1zoHS5W9IAXv6dGqhMQMc=\ncloud.google.com/go/webrisk v1.7.0/go.mod h1:mVMHgEYH0r337nmt1JyLthzMr6YxwN1aAIEc2fTcq7A=\ncloud.google.com/go/webrisk v1.8.0/go.mod h1:oJPDuamzHXgUc+b8SiHRcVInZQuybnvEW72PqTc7sSg=\ncloud.google.com/go/webrisk v1.9.5/go.mod h1:aako0Fzep1Q714cPEM5E+mtYX8/jsfegAuS8aivxy3U=\ncloud.google.com/go/websecurityscanner v1.3.0/go.mod h1:uImdKm2wyeXQevQJXeh8Uun/Ym1VqworNDlBXQevGMo=\ncloud.google.com/go/websecurityscanner v1.4.0/go.mod h1:ebit/Fp0a+FWu5j4JOmJEV8S8CzdTkAS77oDsiSqYWQ=\ncloud.google.com/go/websecurityscanner v1.5.0/go.mod h1:Y6xdCPy81yi0SQnDY1xdNTNpfY1oAgXUlcfN3B3eSng=\ncloud.google.com/go/websecurityscanner v1.6.5/go.mod h1:QR+DWaxAz2pWooylsBF854/Ijvuoa3FCyS1zBa1rAVQ=\ncloud.google.com/go/workflows v1.6.0/go.mod h1:6t9F5h/unJz41YqfBmqSASJSXccBLtD1Vwf+KmJENM0=\ncloud.google.com/go/workflows v1.7.0/go.mod h1:JhSrZuVZWuiDfKEFxU0/F1PQjmpnpcoISEXH2bcHC3M=\ncloud.google.com/go/workflows v1.8.0/go.mod h1:ysGhmEajwZxGn1OhGOGKsTXc5PyxOc0vfKf5Af+to4M=\ncloud.google.com/go/workflows v1.9.0/go.mod h1:ZGkj1aFIOd9c8Gerkjjq7OW7I5+l6cSvT3ujaO/WwSA=\ncloud.google.com/go/workflows v1.10.0/go.mod h1:fZ8LmRmZQWacon9UCX1r/g/DfAXx5VcPALq2CxzdePw=\ncloud.google.com/go/workflows v1.12.4/go.mod h1:yQ7HUqOkdJK4duVtMeBCAOPiN1ZF1E9pAMX51vpwB/w=\nconnectrpc.com/connect v1.18.1 h1:PAg7CjSAGvscaf6YZKUefjoih5Z/qYkyaTrBW8xvYPw=\nconnectrpc.com/connect v1.18.1/go.mod h1:0292hj1rnx8oFrStN7cB4jjVBeqs+Yx5yDIC2prWDO8=\nconnectrpc.com/otelconnect v0.7.2 h1:WlnwFzaW64dN06JXU+hREPUGeEzpz3Acz2ACOmN8cMI=\nconnectrpc.com/otelconnect v0.7.2/go.mod h1:JS7XUKfuJs2adhCnXhNHPHLz6oAaZniCJdSF00OZSew=\ndmitri.shuralyov.com/app/changes v0.0.0-20180602232624-0a106ad413e3/go.mod h1:Yl+fi1br7+Rr3LqpNJf1/uxUdtRUV+Tnj0o93V2B9MU=\ndmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=\ndmitri.shuralyov.com/html/belt v0.0.0-20180602232347-f7d459c86be0/go.mod h1:JLBrvjyP0v+ecvNYvCpyZgu5/xkfAUhi6wJj28eUfSU=\ndmitri.shuralyov.com/service/change v0.0.0-20181023043359-a85b471d5412/go.mod h1:a1inKt/atXimZ4Mv927x+r7UpyzRUf4emIoiiSC2TN4=\ndmitri.shuralyov.com/state v0.0.0-20180228185332-28bcc343414c/go.mod h1:0PRwlb0D6DFvNNtx+9ybjezNCa8XF0xaYcETyp6rHWU=\ngioui.org v0.0.0-20210308172011-57750fc8a0a6/go.mod h1:RSH6KIUZ0p2xy5zHDxgAM4zumjgTw83q2ge/PI+yyw8=\ngit.apache.org/thrift.git v0.0.0-20180902110319-2566ecd5d999/go.mod h1:fPE2ZNJGynbRyZ4dJvy6G277gSllfV2HJqblrnkyeyg=\ngit.sr.ht/~sbinet/gg v0.3.1/go.mod h1:KGYtlADtqsqANL9ueOFkWymvzUvLMQllU5Ixo+8v3pc=\ngithub.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E=\ngithub.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E=\ngithub.com/Azure/go-ansiterm v0.0.0-20250102033503-faa5f7b0171c h1:udKWzYgxTojEKWjV8V+WSxDXJ4NFATAsZjh8iIbsQIg=\ngithub.com/Azure/go-ansiterm v0.0.0-20250102033503-faa5f7b0171c/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E=\ngithub.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=\ngithub.com/BurntSushi/toml v1.2.1/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=\ngithub.com/BurntSushi/toml v1.4.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho=\ngithub.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=\ngithub.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.26.0/go.mod h1:2bIszWvQRlJVmJLiuLhukLImRjKPcYdzzsx6darK02A=\ngithub.com/JohnCGriffin/overflow v0.0.0-20211019200055-46fa312c352c/go.mod h1:X0CRv0ky0k6m906ixxpzmDRLvX58TFUKS2eePweuyxk=\ngithub.com/Microsoft/go-winio v0.6.1/go.mod h1:LRdKpFKfdobln8UmuiYcKPot9D2v6svN5+sAH+4kjUM=\ngithub.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY=\ngithub.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU=\ngithub.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=\ngithub.com/ajstarks/deck v0.0.0-20200831202436-30c9fc6549a9/go.mod h1:JynElWSGnm/4RlzPXRlREEwqTHAN3T56Bv2ITsFT3gY=\ngithub.com/ajstarks/deck/generate v0.0.0-20210309230005-c3f852c02e19/go.mod h1:T13YZdzov6OU0A1+RfKZiZN9ca6VeKdBdyDV+BY97Tk=\ngithub.com/ajstarks/svgo v0.0.0-20180226025133-644b8db467af/go.mod h1:K08gAheRH3/J6wwsYMMT4xOr94bZjxIelGM0+d/wbFw=\ngithub.com/ajstarks/svgo v0.0.0-20211024235047-1546f124cd8b/go.mod h1:1KcenG0jGWcpt8ov532z81sp/kMMUG485J2InIOyADM=\ngithub.com/alecthomas/assert/v2 v2.3.0/go.mod h1:pXcQ2Asjp247dahGEmsZ6ru0UVwnkhktn7S0bBDLxvQ=\ngithub.com/alecthomas/kingpin/v2 v2.4.0/go.mod h1:0gyi0zQnjuFk8xrkNKamJoyUo382HRL7ATRpFZCw6tE=\ngithub.com/alecthomas/participle/v2 v2.1.0/go.mod h1:Y1+hAs8DHPmc3YUFzqllV+eSQ9ljPTk0ZkPMtEdAx2c=\ngithub.com/alecthomas/repr v0.2.0/go.mod h1:Fr0507jx4eOXV7AlPV6AVZLYrLIuIeSOWtW57eE/O/4=\ngithub.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=\ngithub.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137/go.mod h1:OMCwj8VM1Kc9e19TLln2VL61YJF0x1XFtfdL4JdbSyE=\ngithub.com/andybalholm/brotli v1.0.4/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig=\ngithub.com/andybalholm/brotli v1.0.5/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig=\ngithub.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c=\ngithub.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY=\ngithub.com/antlr4-go/antlr/v4 v4.13.1 h1:SqQKkuVZ+zWkMMNkjy5FZe5mr5WURWnlpmOuzYWrPrQ=\ngithub.com/antlr4-go/antlr/v4 v4.13.1/go.mod h1:GKmUxMtwp6ZgGwZSva4eWPC5mS6vUAmOABFgjdkM7Nw=\ngithub.com/apache/arrow/go/v10 v10.0.1/go.mod h1:YvhnlEePVnBS4+0z3fhPfUy7W1Ikj0Ih0vcRo/gZ1M0=\ngithub.com/apache/arrow/go/v11 v11.0.0/go.mod h1:Eg5OsL5H+e299f7u5ssuXsuHQVEGC4xei5aX110hRiI=\ngithub.com/apache/arrow/go/v12 v12.0.1/go.mod h1:weuTY7JvTG/HDPtMQxEUp7pU73vkLWMLpY67QwZ/WWw=\ngithub.com/apache/arrow/go/v14 v14.0.2/go.mod h1:u3fgh3EdgN/YQ8cVQRguVW3R+seMybFg8QBQ5LU+eBY=\ngithub.com/apache/thrift v0.16.0/go.mod h1:PHK3hniurgQaNMZYaCLEqXKsYK8upmhPbmdP2FXSqgU=\ngithub.com/apache/thrift v0.17.0/go.mod h1:OLxhMRJxomX+1I/KUw03qoV3mMz16BwaKI+d4fPBx7Q=\ngithub.com/bazelbuild/rules_go v0.49.0/go.mod h1:Dhcz716Kqg1RHNWos+N6MlXNkjNP2EwZQ0LukRKJfMs=\ngithub.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA=\ngithub.com/benbjohnson/clock v1.3.5/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA=\ngithub.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=\ngithub.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=\ngithub.com/boombuler/barcode v1.0.0/go.mod h1:paBWMcWSl3LHKBqUq+rly7CNSldXjb2rDl3JlRe0mD8=\ngithub.com/boombuler/barcode v1.0.1/go.mod h1:paBWMcWSl3LHKBqUq+rly7CNSldXjb2rDl3JlRe0mD8=\ngithub.com/bradfitz/go-smtpd v0.0.0-20170404230938-deb6d6237625/go.mod h1:HYsPBTaaSFSlLx/70C2HPIMNZpVV8+vt/A+FMnYP11g=\ngithub.com/bufbuild/buf v1.26.1 h1:+GdU4z2paCmDclnjLv7MqnVi3AGviImlIKhG0MHH9FA=\ngithub.com/bufbuild/buf v1.26.1/go.mod h1:UMPncXMWgrmIM+0QpwTEwjNr2SA0z2YIVZZsmNflvB4=\ngithub.com/bufbuild/buf v1.55.1 h1:yaRXO9YmtgyEhiqT/gwuJWhHN9xBBbqlQvXVnPauvCk=\ngithub.com/bufbuild/buf v1.55.1/go.mod h1:bvDF6WkvObC+ca9gmP++/oCAWeVVX7MspMcTFznqF7k=\ngithub.com/bufbuild/connect-go v1.8.0/go.mod h1:GmMJYR6orFqD0Y6ZgX8pwQ8j9baizDrIQMm1/a6LnHk=\ngithub.com/bufbuild/connect-go v1.9.0 h1:JIgAeNuFpo+SUPfU19Yt5TcWlznsN5Bv10/gI/6Pjoc=\ngithub.com/bufbuild/connect-go v1.9.0/go.mod h1:CAIePUgkDR5pAFaylSMtNK45ANQjp9JvpluG20rhpV8=\ngithub.com/bufbuild/connect-opentelemetry-go v0.4.0 h1:6JAn10SNqlQ/URhvRNGrIlczKw1wEXknBUUtmWqOiak=\ngithub.com/bufbuild/connect-opentelemetry-go v0.4.0/go.mod h1:nwPXYoDOoc2DGyKE/6pT1Q9MPSi2Et2e6BieMD0l6WU=\ngithub.com/bufbuild/protocompile v0.4.0/go.mod h1:3v93+mbWn/v3xzN+31nwkJfrEpAUwp+BagBSZWx+TP8=\ngithub.com/bufbuild/protocompile v0.6.0 h1:Uu7WiSQ6Yj9DbkdnOe7U4mNKp58y9WDMKDn28/ZlunY=\ngithub.com/bufbuild/protocompile v0.6.0/go.mod h1:YNP35qEYoYGme7QMtz5SBCoN4kL4g12jTtjuzRNdjpE=\ngithub.com/bufbuild/protocompile v0.14.1 h1:iA73zAf/fyljNjQKwYzUHD6AD4R8KMasmwa/FBatYVw=\ngithub.com/bufbuild/protocompile v0.14.1/go.mod h1:ppVdAIhbr2H8asPk6k4pY7t9zB1OU5DoEw9xY/FUi1c=\ngithub.com/bufbuild/protoplugin v0.0.0-20250218205857-750e09ce93e1 h1:V1xulAoqLqVg44rY97xOR+mQpD2N+GzhMHVwJ030WEU=\ngithub.com/bufbuild/protoplugin v0.0.0-20250218205857-750e09ce93e1/go.mod h1:c5D8gWRIZ2HLWO3gXYTtUfw/hbJyD8xikv2ooPxnklQ=\ngithub.com/buger/jsonparser v0.0.0-20181115193947-bf1c66bbce23/go.mod h1:bbYlZJ7hK1yFx9hf58LP0zeX7UjIGs20ufpu3evjr+s=\ngithub.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE=\ngithub.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=\ngithub.com/census-instrumentation/opencensus-proto v0.3.0/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=\ngithub.com/census-instrumentation/opencensus-proto v0.4.1/go.mod h1:4T9NM4+4Vw91VeyqjLS6ao50K5bOcLKN6Q42XnYaRYw=\ngithub.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=\ngithub.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=\ngithub.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=\ngithub.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=\ngithub.com/chromedp/cdproto v0.0.0-20230802225258-3cf4e6d46a89/go.mod h1:GKljq0VrfU4D5yc+2qA6OVr8pmO/MBbPEWqWQ/oqGEs=\ngithub.com/chromedp/chromedp v0.9.2/go.mod h1:LkSXJKONWTCHAfQasKFUZI+mxqS4tZqhmtGzzhLsnLs=\ngithub.com/chromedp/sysutil v1.0.0/go.mod h1:kgWmDdq8fTzXYcKIBqIYvRRTnYb9aNS9moAV0xufSww=\ngithub.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=\ngithub.com/chzyer/logex v1.2.1/go.mod h1:JLbx6lG2kDbNRFnfkgvh4eRJRPX1QCoOIWomwysCBrQ=\ngithub.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=\ngithub.com/chzyer/readline v1.5.1/go.mod h1:Eh+b79XXUwfKfcPLepksvw2tcLE/Ct21YObkaSkeBlk=\ngithub.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=\ngithub.com/chzyer/test v1.0.0/go.mod h1:2JlltgoNkt4TW/z9V/IzDdFaMTM2JPIi26O1pF38GC8=\ngithub.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=\ngithub.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=\ngithub.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=\ngithub.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=\ngithub.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4/go.mod h1:6pvJx4me5XPnfI9Z40ddWsdw2W/uZgQLFXToKeRcDiI=\ngithub.com/cncf/udpa/go v0.0.0-20220112060539-c52dc94e7fbe/go.mod h1:6pvJx4me5XPnfI9Z40ddWsdw2W/uZgQLFXToKeRcDiI=\ngithub.com/cncf/xds/go v0.0.0-20210312221358-fbca930ec8ed/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=\ngithub.com/cncf/xds/go v0.0.0-20210805033703-aa0b78936158/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=\ngithub.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=\ngithub.com/cncf/xds/go v0.0.0-20211001041855-01bcc9b48dfe/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=\ngithub.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=\ngithub.com/cncf/xds/go v0.0.0-20220314180256-7f1daf1720fc/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=\ngithub.com/cncf/xds/go v0.0.0-20230105202645-06c439db220b/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=\ngithub.com/cncf/xds/go v0.0.0-20250121191232-2f005788dc42/go.mod h1:W+zGtBO5Y1IgJhy4+A9GOqVhqLpfZi+vwmdNXUehLA8=\ngithub.com/containerd/errdefs v1.0.0 h1:tg5yIfIlQIrxYtu9ajqY42W3lpS19XqdxRQeEwYG8PI=\ngithub.com/containerd/errdefs v1.0.0/go.mod h1:+YBYIdtsnF4Iw6nWZhJcqGSg/dwvV7tyJ/kCkyJ2k+M=\ngithub.com/containerd/errdefs/pkg v0.3.0 h1:9IKJ06FvyNlexW690DXuQNx2KA2cUJXx151Xdx3ZPPE=\ngithub.com/containerd/errdefs/pkg v0.3.0/go.mod h1:NJw6s9HwNuRhnjJhM7pylWwMyAkmCQvQ4GpJHEqRLVk=\ngithub.com/containerd/log v0.1.0/go.mod h1:VRRf09a7mHDIRezVKTRCrOq78v577GXq3bSa3EhrzVo=\ngithub.com/containerd/stargz-snapshotter/estargz v0.14.3 h1:OqlDCK3ZVUO6C3B/5FSkDwbkEETK84kQgEeFwDC+62k=\ngithub.com/containerd/stargz-snapshotter/estargz v0.14.3/go.mod h1:KY//uOCIkSuNAHhJogcZtrNHdKrA99/FCCRjE3HD36o=\ngithub.com/containerd/stargz-snapshotter/estargz v0.16.3 h1:7evrXtoh1mSbGj/pfRccTampEyKpjpOnS3CyiV1Ebr8=\ngithub.com/containerd/stargz-snapshotter/estargz v0.16.3/go.mod h1:uyr4BfYfOj3G9WBVE8cOlQmXAbPN9VEQpBBeJIuOipU=\ngithub.com/containerd/typeurl/v2 v2.2.0/go.mod h1:8XOOxnyatxSWuG8OfsZXVnAF4iZfedjS/8UHSPJnX4g=\ngithub.com/coreos/go-systemd v0.0.0-20181012123002-c6f51f82210d/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=\ngithub.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=\ngithub.com/cpuguy83/go-md2man/v2 v2.0.2 h1:p1EgwI/C7NhT0JmVkwCD2ZBK8j4aeHQX2pMHHBfMQ6w=\ngithub.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=\ngithub.com/cpuguy83/go-md2man/v2 v2.0.5/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=\ngithub.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g=\ngithub.com/cpuguy83/go-md2man/v2 v2.0.7 h1:zbFlGlXEAKlwXpmvle3d8Oe3YnkKIK4xSRTd3sHPnBo=\ngithub.com/cpuguy83/go-md2man/v2 v2.0.7/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g=\ngithub.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=\ngithub.com/creack/pty v1.1.18/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4=\ngithub.com/danieljoos/wincred v1.1.2/go.mod h1:GijpziifJoIBfYh+S7BbkdUTU4LfM+QnGqR5Vl2tAx0=\ngithub.com/danieljoos/wincred v1.2.0/go.mod h1:FzQLLMKBFdvu+osBrnFODiv32YGwCfx0SkRa/eYHgec=\ngithub.com/danieljoos/wincred v1.2.2/go.mod h1:w7w4Utbrz8lqeMbDAK0lkNJUv5sAOkFi7nd/ogr0Uh8=\ngithub.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=\ngithub.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=\ngithub.com/distribution/reference v0.6.0 h1:0IXCQ5g4/QMHHkarYzh5l+u8T3t73zM5QvfrDyIgxBk=\ngithub.com/distribution/reference v0.6.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E=\ngithub.com/docker/cli v23.0.5+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8=\ngithub.com/docker/cli v24.0.4+incompatible h1:Y3bYF9ekNTm2VFz5U/0BlMdJy73D+Y1iAAZ8l63Ydzw=\ngithub.com/docker/cli v24.0.4+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8=\ngithub.com/docker/cli v28.2.2+incompatible h1:qzx5BNUDFqlvyq4AHzdNB7gSyVTmU4cgsyN9SdInc1A=\ngithub.com/docker/cli v28.2.2+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8=\ngithub.com/docker/distribution v2.8.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=\ngithub.com/docker/distribution v2.8.2+incompatible h1:T3de5rq0dB1j30rp0sA2rER+m322EBzniBPB6ZIzuh8=\ngithub.com/docker/distribution v2.8.2+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=\ngithub.com/docker/distribution v2.8.3+incompatible h1:AtKxIZ36LoNK51+Z6RpzLpddBirtxJnzDrHLEKxTAYk=\ngithub.com/docker/distribution v2.8.3+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=\ngithub.com/docker/docker v23.0.5+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=\ngithub.com/docker/docker v24.0.4+incompatible h1:s/LVDftw9hjblvqIeTiGYXBCD95nOEEl7qRsRrIOuQI=\ngithub.com/docker/docker v24.0.4+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=\ngithub.com/docker/docker v28.2.2+incompatible h1:CjwRSksz8Yo4+RmQ339Dp/D2tGO5JxwYeqtMOEe0LDw=\ngithub.com/docker/docker v28.2.2+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=\ngithub.com/docker/docker-credential-helpers v0.7.0/go.mod h1:rETQfLdHNT3foU5kuNkFR1R1V12OJRRO5lzt2D1b5X0=\ngithub.com/docker/docker-credential-helpers v0.8.0 h1:YQFtbBQb4VrpoPxhFuzEBPQ9E16qz5SpHLS+uswaCp8=\ngithub.com/docker/docker-credential-helpers v0.8.0/go.mod h1:UGFXcuoQ5TxPiB54nHOZ32AWRqQdECoh/Mg0AlEYb40=\ngithub.com/docker/docker-credential-helpers v0.9.3 h1:gAm/VtF9wgqJMoxzT3Gj5p4AqIjCBS4wrsOh9yRqcz8=\ngithub.com/docker/docker-credential-helpers v0.9.3/go.mod h1:x+4Gbw9aGmChi3qTLZj8Dfn0TD20M/fuWy0E5+WDeCo=\ngithub.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ=\ngithub.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec=\ngithub.com/docker/go-connections v0.5.0 h1:USnMq7hx7gwdVZq1L49hLXaFtUdTADjXGp+uj1Br63c=\ngithub.com/docker/go-connections v0.5.0/go.mod h1:ov60Kzw0kKElRwhNs9UlUHAE/F9Fe6GLaXnqyDdmEXc=\ngithub.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4=\ngithub.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=\ngithub.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3ebgob9U8Nd0kOddGdZWjyMGR8Wziv+TBNwSE=\ngithub.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=\ngithub.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto=\ngithub.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=\ngithub.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=\ngithub.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=\ngithub.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po=\ngithub.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=\ngithub.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=\ngithub.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.mod h1:hliV/p42l8fGbc6Y9bQ70uLwIvmJyVE5k4iMKlh8wCQ=\ngithub.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.mod h1:AFq3mo9L8Lqqiid3OhADV3RfLJnjiw63cSpi+fDTRC0=\ngithub.com/envoyproxy/go-control-plane v0.10.2-0.20220325020618-49ff273808a1/go.mod h1:KJwIaB5Mv44NWtYuAOFCVOjcI94vtpEz2JU/D2v6IjE=\ngithub.com/envoyproxy/go-control-plane v0.10.3/go.mod h1:fJJn/j26vwOu972OllsvAgJJM//w9BV6Fxbg2LuVd34=\ngithub.com/envoyproxy/go-control-plane v0.13.4/go.mod h1:kDfuBlDVsSj2MjrLEtRWtHlsWIFcGyB2RMO44Dc5GZA=\ngithub.com/envoyproxy/go-control-plane/envoy v1.32.4/go.mod h1:Gzjc5k8JcJswLjAx1Zm+wSYE20UrLtt7JZMWiWQXQEw=\ngithub.com/envoyproxy/go-control-plane/ratelimit v0.1.0/go.mod h1:Wk+tMFAFbCXaJPzVVHnPgRKdUdwW/KdbRt94AzgRee4=\ngithub.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=\ngithub.com/envoyproxy/protoc-gen-validate v0.6.7/go.mod h1:dyJXwwfPK2VSqiB9Klm1J6romD608Ba7Hij42vrOBCo=\ngithub.com/envoyproxy/protoc-gen-validate v0.9.1/go.mod h1:OKNgG7TCp5pF4d6XftA0++PMirau2/yoOwVac3AbF2w=\ngithub.com/envoyproxy/protoc-gen-validate v1.2.1/go.mod h1:d/C80l/jxXLdfEIhX1W2TmLfsJ31lvEjwamM4DxlWXU=\ngithub.com/fatih/color v1.15.0/go.mod h1:0h5ZqXfHYED7Bhv2ZJamyIOUej9KtShiJESRwBDUSsw=\ngithub.com/felixge/fgprof v0.9.3 h1:VvyZxILNuCiUCSXtPtYmmtGvb65nqXh2QFWc0Wpf2/g=\ngithub.com/felixge/fgprof v0.9.3/go.mod h1:RdbpDgzqYVh/T9fPELJyV7EYJuHB55UTEULNun8eiPw=\ngithub.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg=\ngithub.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=\ngithub.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc=\ngithub.com/fogleman/gg v1.2.1-0.20190220221249-0403632d5b90/go.mod h1:R/bRT+9gY/C5z7JzPU0zXsXHKM4/ayA+zqcVNZzPa1k=\ngithub.com/fogleman/gg v1.3.0/go.mod h1:R/bRT+9gY/C5z7JzPU0zXsXHKM4/ayA+zqcVNZzPa1k=\ngithub.com/francoispqt/gojay v1.2.13/go.mod h1:ehT5mTG4ua4581f1++1WLG0vPdaA9HaiDsoyrBGkyDY=\ngithub.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=\ngithub.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=\ngithub.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=\ngithub.com/gliderlabs/ssh v0.1.1/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0=\ngithub.com/go-chi/chi/v5 v5.0.10 h1:rLz5avzKpjqxrYwXNfmjkrYYXOyLJd37pz53UFHC6vk=\ngithub.com/go-chi/chi/v5 v5.0.10/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8=\ngithub.com/go-chi/chi/v5 v5.2.1 h1:KOIHODQj58PmL80G2Eak4WdvUzjSJSm0vG72crDCqb8=\ngithub.com/go-chi/chi/v5 v5.2.1/go.mod h1:L2yAIGWB3H+phAw1NxKwWM+7eUH/lU8pOMm5hHcoops=\ngithub.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q=\ngithub.com/go-fonts/dejavu v0.1.0/go.mod h1:4Wt4I4OU2Nq9asgDCteaAaWZOV24E+0/Pwo0gppep4g=\ngithub.com/go-fonts/latin-modern v0.2.0/go.mod h1:rQVLdDMK+mK1xscDwsqM5J8U2jrRa3T0ecnM9pNujks=\ngithub.com/go-fonts/liberation v0.1.1/go.mod h1:K6qoJYypsmfVjWg8KOVDQhLc8UDgIK2HYqyqAO9z7GY=\ngithub.com/go-fonts/liberation v0.2.0/go.mod h1:K6qoJYypsmfVjWg8KOVDQhLc8UDgIK2HYqyqAO9z7GY=\ngithub.com/go-fonts/stix v0.1.0/go.mod h1:w/c1f0ldAUlJmLBvlbkvVXLAD+tAMqobIIQpmnUIzUY=\ngithub.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=\ngithub.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=\ngithub.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=\ngithub.com/go-jose/go-jose/v4 v4.0.4/go.mod h1:NKb5HO1EZccyMpiZNbdUw/14tiXNyUJh188dfnMCAfc=\ngithub.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=\ngithub.com/go-kit/log v0.2.1/go.mod h1:NwTd00d/i8cPZ3xOwwiv2PO5MOcx78fFErGNcVmBjv0=\ngithub.com/go-latex/latex v0.0.0-20210118124228-b3d85cf34e07/go.mod h1:CO1AlKB2CSIqUrmQPqA0gdRIlnLEY0gK5JGjh37zN5U=\ngithub.com/go-latex/latex v0.0.0-20210823091927-c0d11ff05a81/go.mod h1:SX0U8uGpxhq9o2S/CELCSUxEWWAuoCUcVCQWv7G2OCk=\ngithub.com/go-logfmt/logfmt v0.5.1/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs=\ngithub.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=\ngithub.com/go-logr/logr v1.2.4 h1:g01GSCwiDw2xSZfjJ2/T9M+S6pFdcNtFYsp+Y43HYDQ=\ngithub.com/go-logr/logr v1.2.4/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=\ngithub.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI=\ngithub.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=\ngithub.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=\ngithub.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=\ngithub.com/go-pdf/fpdf v0.5.0/go.mod h1:HzcnA+A23uwogo0tp9yU+l3V+KXhiESpt1PMayhOh5M=\ngithub.com/go-pdf/fpdf v0.6.0/go.mod h1:HzcnA+A23uwogo0tp9yU+l3V+KXhiESpt1PMayhOh5M=\ngithub.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=\ngithub.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8=\ngithub.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA=\ngithub.com/go-playground/validator/v10 v10.4.1/go.mod h1:nlOn6nFhuKACm19sB/8EGNn9GlaMV7XkbRSipzJ0Ii4=\ngithub.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=\ngithub.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE=\ngithub.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI=\ngithub.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls=\ngithub.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI=\ngithub.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8=\ngithub.com/gobwas/httphead v0.1.0/go.mod h1:O/RXo79gxV8G+RqlR/otEwx4Q36zl9rqC5u12GKvMCM=\ngithub.com/gobwas/pool v0.2.1/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw=\ngithub.com/gobwas/ws v1.2.1/go.mod h1:hRKAFb8wOxFROYNsT1bqfWnhX+b5MFeJM9r2ZSwg/KY=\ngithub.com/goccy/go-json v0.9.11/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=\ngithub.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=\ngithub.com/goccy/go-yaml v1.11.0/go.mod h1:H+mJrWtjPTJAHvRbV09MCK9xYwODM+wRTVFFTWckfng=\ngithub.com/gofrs/flock v0.8.1/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14jxHU=\ngithub.com/gofrs/flock v0.12.1 h1:MTLVXXHf8ekldpJk3AKicLij9MdwOWkZ+a/jHHZby9E=\ngithub.com/gofrs/flock v0.12.1/go.mod h1:9zxTsyu5xtJ9DK+1tFZyibEV7y3uwDxPPfbxeeHCoD0=\ngithub.com/gofrs/uuid/v5 v5.0.0 h1:p544++a97kEL+svbcFbCQVM9KFu0Yo25UoISXGNNH9M=\ngithub.com/gofrs/uuid/v5 v5.0.0/go.mod h1:CDOjlDMVAtN56jqyRUZh58JT31Tiw7/oQyEXZV+9bD8=\ngithub.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=\ngithub.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=\ngithub.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=\ngithub.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGwJL78qG/PmXZO1EjYhfJinVAhrmmHX6Z8B9k=\ngithub.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=\ngithub.com/golang/glog v1.0.0/go.mod h1:EWib/APOK0SL3dFbYqvxE3UYd8E6s1ouQ7iEp/0LWV4=\ngithub.com/golang/glog v1.2.4/go.mod h1:6AhwSGph0fcJtXVM/PEHPqZlFeoLxhs7/t5UDAwmO+w=\ngithub.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=\ngithub.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=\ngithub.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=\ngithub.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=\ngithub.com/golang/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:tluoj9z5200jBnyusfRPU2LqT6J+DAorxEvtC7LHB+E=\ngithub.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=\ngithub.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=\ngithub.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y=\ngithub.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=\ngithub.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=\ngithub.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=\ngithub.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4=\ngithub.com/golang/mock v1.5.0/go.mod h1:CWnOUgYIOo4TcNZ0wHX3YZCqsaM1I1Jvs6v3mP3KVu8=\ngithub.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs=\ngithub.com/golang/mock v1.7.0-rc.1/go.mod h1:s42URUywIqd+OcERslBJvOjepvNymP31m3q8d/GkuRs=\ngithub.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=\ngithub.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=\ngithub.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=\ngithub.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=\ngithub.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=\ngithub.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk=\ngithub.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=\ngithub.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=\ngithub.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs=\ngithub.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w=\ngithub.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=\ngithub.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8=\ngithub.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=\ngithub.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=\ngithub.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=\ngithub.com/golang/protobuf v1.5.1/go.mod h1:DopwsBzvsk0Fs44TXzsVbJyPhcCPeIwnvohx4u74HPM=\ngithub.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=\ngithub.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=\ngithub.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps=\ngithub.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=\ngithub.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=\ngithub.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=\ngithub.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=\ngithub.com/google/cel-go v0.25.0 h1:jsFw9Fhn+3y2kBbltZR4VEz5xKkcIFRPDnuEzAGv5GY=\ngithub.com/google/cel-go v0.25.0/go.mod h1:hjEb6r5SuOSlhCHmFoLzu8HGCERvIsDAbxDAyNU/MmI=\ngithub.com/google/flatbuffers v2.0.8+incompatible/go.mod h1:1AeVuKshWv4vARoZatz6mlQ0JxURH0Kv5+zNeJKJCa8=\ngithub.com/google/flatbuffers v23.5.26+incompatible/go.mod h1:1AeVuKshWv4vARoZatz6mlQ0JxURH0Kv5+zNeJKJCa8=\ngithub.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=\ngithub.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=\ngithub.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=\ngithub.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=\ngithub.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=\ngithub.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=\ngithub.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=\ngithub.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=\ngithub.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=\ngithub.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=\ngithub.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=\ngithub.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=\ngithub.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE=\ngithub.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=\ngithub.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=\ngithub.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=\ngithub.com/google/go-containerregistry v0.15.2 h1:MMkSh+tjSdnmJZO7ljvEqV1DjfekB6VUEAZgy3a+TQE=\ngithub.com/google/go-containerregistry v0.15.2/go.mod h1:wWK+LnOv4jXMM23IT/F1wdYftGWGr47Is8CG+pmHK1Q=\ngithub.com/google/go-containerregistry v0.20.6 h1:cvWX87UxxLgaH76b4hIvya6Dzz9qHB31qAwjAohdSTU=\ngithub.com/google/go-containerregistry v0.20.6/go.mod h1:T0x8MuoAoKX/873bkeSfLD2FAkwCDf9/HZgsFJ02E2Y=\ngithub.com/google/go-github v17.0.0+incompatible/go.mod h1:zLgOLi98H3fifZn+44m+umXrS52loVEgC2AApnigrVQ=\ngithub.com/google/go-pkcs11 v0.2.1-0.20230907215043-c6f79328ddf9/go.mod h1:6eQoGcuNJpa7jnd5pMGdkSaQpNDYvPlXWMcjXXThLlY=\ngithub.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck=\ngithub.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=\ngithub.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=\ngithub.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=\ngithub.com/google/martian/v3 v3.1.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=\ngithub.com/google/martian/v3 v3.2.1/go.mod h1:oBOf6HBosgwRXnUGWUB05QECsc6uvmMiJ3+6W4l/CUk=\ngithub.com/google/martian/v3 v3.3.2/go.mod h1:oBOf6HBosgwRXnUGWUB05QECsc6uvmMiJ3+6W4l/CUk=\ngithub.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=\ngithub.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=\ngithub.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=\ngithub.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=\ngithub.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=\ngithub.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=\ngithub.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=\ngithub.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=\ngithub.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=\ngithub.com/google/pprof v0.0.0-20201218002935-b9804c9f04c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=\ngithub.com/google/pprof v0.0.0-20210122040257-d980be63207e/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=\ngithub.com/google/pprof v0.0.0-20210226084205-cbba55b83ad5/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=\ngithub.com/google/pprof v0.0.0-20210601050228-01bbb1931b22/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=\ngithub.com/google/pprof v0.0.0-20210609004039-a478d1d731e9/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=\ngithub.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=\ngithub.com/google/pprof v0.0.0-20211214055906-6f57359322fd/go.mod h1:KgnwoLYCZ8IQu3XUZ8Nc/bM9CCZFOyjUNOSygVozoDg=\ngithub.com/google/pprof v0.0.0-20230705174524-200ffdc848b8 h1:n6vlPhxsA+BW/XsS5+uqi7GyzaLa5MH7qlSLBZtRdiA=\ngithub.com/google/pprof v0.0.0-20230705174524-200ffdc848b8/go.mod h1:Jh3hGz2jkYak8qXPD19ryItVnUgpgeqzdkY/D0EaeuA=\ngithub.com/google/pprof v0.0.0-20250607225305-033d6d78b36a h1://KbezygeMJZCSHH+HgUZiTeSoiuFspbMg1ge+eFj18=\ngithub.com/google/pprof v0.0.0-20250607225305-033d6d78b36a/go.mod h1:5hDyRhoBCxViHszMt12TnOpEI4VVi+U8Gm9iphldiMA=\ngithub.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=\ngithub.com/google/s2a-go v0.1.7/go.mod h1:50CgR4k1jNlWBu4UfS4AcfhVe1r6pdZPygJ3R8F0Qdw=\ngithub.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=\ngithub.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=\ngithub.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=\ngithub.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=\ngithub.com/googleapis/enterprise-certificate-proxy v0.0.0-20220520183353-fd19c99a87aa/go.mod h1:17drOmN3MwGY7t0e+Ei9b45FFGA3fBs3x36SsCg1hq8=\ngithub.com/googleapis/enterprise-certificate-proxy v0.1.0/go.mod h1:17drOmN3MwGY7t0e+Ei9b45FFGA3fBs3x36SsCg1hq8=\ngithub.com/googleapis/enterprise-certificate-proxy v0.2.0/go.mod h1:8C0jb7/mgJe/9KK8Lm7X9ctZC2t60YyIpYEI16jx0Qg=\ngithub.com/googleapis/enterprise-certificate-proxy v0.2.1/go.mod h1:AwSRAtLfXpU5Nm3pW+v7rGDHp09LsPtGY9MduiEsR9k=\ngithub.com/googleapis/enterprise-certificate-proxy v0.2.3/go.mod h1:AwSRAtLfXpU5Nm3pW+v7rGDHp09LsPtGY9MduiEsR9k=\ngithub.com/googleapis/enterprise-certificate-proxy v0.3.2/go.mod h1:VLSiSSBs/ksPL8kq3OBOQ6WRI2QnaFynd1DCjZ62+V0=\ngithub.com/googleapis/gax-go v2.0.0+incompatible/go.mod h1:SFVmujtThgffbyetf+mdk2eWhX2bMyUtNHzFKcPA9HY=\ngithub.com/googleapis/gax-go/v2 v2.0.3/go.mod h1:LLvjysVCY1JZeum8Z6l8qUty8fiNwE08qbEPm1M08qg=\ngithub.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=\ngithub.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=\ngithub.com/googleapis/gax-go/v2 v2.1.0/go.mod h1:Q3nei7sK6ybPYH7twZdmQpAd1MKb7pfu6SK+H1/DsU0=\ngithub.com/googleapis/gax-go/v2 v2.1.1/go.mod h1:hddJymUZASv3XPyGkUpKj8pPO47Rmb0eJc8R6ouapiM=\ngithub.com/googleapis/gax-go/v2 v2.2.0/go.mod h1:as02EH8zWkzwUoLbBaFeQ+arQaj/OthfcblKl4IGNaM=\ngithub.com/googleapis/gax-go/v2 v2.3.0/go.mod h1:b8LNqSzNabLiUpXKkY7HAR5jr6bIT99EXz9pXxye9YM=\ngithub.com/googleapis/gax-go/v2 v2.4.0/go.mod h1:XOTVJ59hdnfJLIP/dh8n5CGryZR2LxK9wbMD5+iXC6c=\ngithub.com/googleapis/gax-go/v2 v2.5.1/go.mod h1:h6B0KMMFNtI2ddbGJn3T3ZbwkeT6yqEF02fYlzkUCyo=\ngithub.com/googleapis/gax-go/v2 v2.6.0/go.mod h1:1mjbznJAPHFpesgE5ucqfYEscaz5kMdcIDwU/6+DDoY=\ngithub.com/googleapis/gax-go/v2 v2.7.0/go.mod h1:TEop28CZZQ2y+c0VxMUmu1lV+fQx57QpBWsYpwqHJx8=\ngithub.com/googleapis/gax-go/v2 v2.7.1/go.mod h1:4orTrqY6hXxxaUL4LHIPl6lGo8vAE38/qKbhSAKP6QI=\ngithub.com/googleapis/gax-go/v2 v2.12.2/go.mod h1:61M8vcyyXR2kqKFxKrfA22jaA8JGF7Dc8App1U3H6jc=\ngithub.com/googleapis/go-type-adapters v1.0.0/go.mod h1:zHW75FOG2aur7gAO2B+MLby+cLsWGBF62rFAi7WjWO4=\ngithub.com/googleapis/google-cloud-go-testing v0.0.0-20200911160855-bcd43fbb19e8/go.mod h1:dvDLG8qkwmyD9a/MJJN3XJcT3xFxOKAvTZGvuZmac9g=\ngithub.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=\ngithub.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA=\ngithub.com/grpc-ecosystem/grpc-gateway v1.5.0/go.mod h1:RSKVYQBd5MCa4OVpNdGskqpgL2+G+NZTnrVHpWWfpdw=\ngithub.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw=\ngithub.com/grpc-ecosystem/grpc-gateway/v2 v2.7.0/go.mod h1:hgWBS7lorOAVIJEQMi4ZsPv9hVvWI6+ch50m39Pf2Ks=\ngithub.com/grpc-ecosystem/grpc-gateway/v2 v2.11.3/go.mod h1:o//XUCC/F+yRGJoPO/VU0GSB0f8Nhgmxx0VIRUvaC0w=\ngithub.com/grpc-ecosystem/grpc-gateway/v2 v2.26.3/go.mod h1:ndYquD05frm2vACXE1nsccT4oJzjhw2arTS2cpUD1PI=\ngithub.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=\ngithub.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=\ngithub.com/hexops/gotextdiff v1.0.3/go.mod h1:pSWU5MAI3yDq+fZBTazCSJysOMbxWL1BSow5/V2vxeg=\ngithub.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=\ngithub.com/iancoleman/strcase v0.2.0/go.mod h1:iwCmte+B7n89clKwxIoIXy/HfoL7AsD47ZCWhYzw7ho=\ngithub.com/iancoleman/strcase v0.3.0/go.mod h1:iwCmte+B7n89clKwxIoIXy/HfoL7AsD47ZCWhYzw7ho=\ngithub.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=\ngithub.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=\ngithub.com/ianlancetaylor/demangle v0.0.0-20210905161508-09a460cdf81d/go.mod h1:aYm2/VgdVmcIU8iMfdMvDMsRAQjcfZSKFby6HOFvi/w=\ngithub.com/ianlancetaylor/demangle v0.0.0-20230524184225-eabc099b10ab/go.mod h1:gx7rwoVhcfuVKG5uya9Hs3Sxj7EIvldVofAWIUtGouw=\ngithub.com/ianlancetaylor/demangle v0.0.0-20250417193237-f615e6bd150b/go.mod h1:gx7rwoVhcfuVKG5uya9Hs3Sxj7EIvldVofAWIUtGouw=\ngithub.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=\ngithub.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=\ngithub.com/jdx/go-netrc v1.0.0 h1:QbLMLyCZGj0NA8glAhxUpf1zDg6cxnWgMBbjq40W0gQ=\ngithub.com/jdx/go-netrc v1.0.0/go.mod h1:Gh9eFQJnoTNIRHXl2j5bJXA1u84hQWJWgGh569zF3v8=\ngithub.com/jdxcode/netrc v0.0.0-20221124155335-4616370d1a84 h1:2uT3aivO7NVpUPGcQX7RbHijHMyWix/yCnIrCWc+5co=\ngithub.com/jdxcode/netrc v0.0.0-20221124155335-4616370d1a84/go.mod h1:Zi/ZFkEqFHTm7qkjyNJjaWH4LQA9LQhGJyF0lTYGpxw=\ngithub.com/jellevandenhooff/dkim v0.0.0-20150330215556-f50fe3d243e1/go.mod h1:E0B/fFc00Y+Rasa88328GlI/XbtyysCtTHZS8h7IrBU=\ngithub.com/jhump/gopoet v0.0.0-20190322174617-17282ff210b3/go.mod h1:me9yfT6IJSlOL3FCfrg+L6yzUEZ+5jW6WHt4Sk+UPUI=\ngithub.com/jhump/gopoet v0.1.0/go.mod h1:me9yfT6IJSlOL3FCfrg+L6yzUEZ+5jW6WHt4Sk+UPUI=\ngithub.com/jhump/goprotoc v0.5.0/go.mod h1:VrbvcYrQOrTi3i0Vf+m+oqQWk9l72mjkJCYo7UvLHRQ=\ngithub.com/jhump/protoreflect v1.11.0/go.mod h1:U7aMIjN0NWq9swDP7xDdoMfRHb35uiuTd3Z9nFXJf5E=\ngithub.com/jhump/protoreflect v1.15.1/go.mod h1:jD/2GMKKE6OqX8qTjhADU1e6DShO+gavG9e0Q693nKo=\ngithub.com/jhump/protoreflect v1.17.1-0.20240913204751-8f5fd1dcb3c5/go.mod h1:uUKhM0KLkqvoYeM5BSlLxkJ3Dja3r0N08ru0cacT99E=\ngithub.com/jhump/protoreflect/v2 v2.0.0-beta.2/go.mod h1:4tnOYkB/mq7QTyS3YKtVtNrJv4Psqout8HA1U+hZtgM=\ngithub.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y=\ngithub.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4=\ngithub.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=\ngithub.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=\ngithub.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=\ngithub.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk=\ngithub.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM=\ngithub.com/jung-kurt/gofpdf v1.0.0/go.mod h1:7Id9E/uU8ce6rXgefFLlgrJj/GYY22cpxn+r32jIOes=\ngithub.com/jung-kurt/gofpdf v1.0.3-0.20190309125859-24315acbbda5/go.mod h1:7Id9E/uU8ce6rXgefFLlgrJj/GYY22cpxn+r32jIOes=\ngithub.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51/go.mod h1:CzGEWj7cYgsdH8dAjBGEr58BoE7ScuLd+fwFZ44+/x8=\ngithub.com/keybase/dbus v0.0.0-20220506165403-5aa21ea2c23a/go.mod h1:YPNKjjE7Ubp9dTbnWvsP3HT+hYnY6TfXzubYTBeUxc8=\ngithub.com/keybase/go-keychain v0.0.1/go.mod h1:PdEILRW3i9D8JcdM+FmY6RwkHGnhHxXwkPPMeUgOK1k=\ngithub.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=\ngithub.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=\ngithub.com/klauspost/asmfmt v1.3.2/go.mod h1:AG8TuvYojzulgDAMCnYn50l/5QV3Bs/tp6j0HLHbNSE=\ngithub.com/klauspost/compress v1.15.9/go.mod h1:PhcZ0MbTNciWF3rruxRgKxI5NkcHHrHUDtV4Yw2GlzU=\ngithub.com/klauspost/compress v1.16.0/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE=\ngithub.com/klauspost/compress v1.16.5/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE=\ngithub.com/klauspost/compress v1.16.7 h1:2mk3MPGNzKyxErAw8YaohYh69+pa4sIQSC0fPGCFR9I=\ngithub.com/klauspost/compress v1.16.7/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE=\ngithub.com/klauspost/compress v1.18.0 h1:c/Cqfb0r+Yi+JtIEq73FWXVkRonBlf0CRNYc8Zttxdo=\ngithub.com/klauspost/compress v1.18.0/go.mod h1:2Pp+KzxcywXVXMr50+X0Q/Lsb43OQHYWRCY2AiWywWQ=\ngithub.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=\ngithub.com/klauspost/cpuid/v2 v2.2.5/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws=\ngithub.com/klauspost/pgzip v1.2.6 h1:8RXeL5crjEUFnR2/Sn6GJNWtSQ3Dk8pq4CL3jvdDyjU=\ngithub.com/klauspost/pgzip v1.2.6/go.mod h1:Ch1tH69qFZu15pkjo5kYi6mth2Zzwzt50oCQKQE9RUs=\ngithub.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=\ngithub.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg=\ngithub.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=\ngithub.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=\ngithub.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=\ngithub.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk=\ngithub.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=\ngithub.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=\ngithub.com/kr/pty v1.1.3/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=\ngithub.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=\ngithub.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=\ngithub.com/ledongthuc/pdf v0.0.0-20220302134840-0c2507a12d80/go.mod h1:imJHygn/1yfhB7XSJJKlFZKl/J+dCPAknuiaGOshXAs=\ngithub.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII=\ngithub.com/lunixbochs/vtclean v1.0.0/go.mod h1:pHhQNgMf3btfWnGBVipUOjRYhoOsdGqdm/+2c2E2WMI=\ngithub.com/lyft/protoc-gen-star v0.6.0/go.mod h1:TGAoBVkt8w7MPG72TrKIu85MIdXwDuzJYeZuUPFPNwA=\ngithub.com/lyft/protoc-gen-star v0.6.1/go.mod h1:TGAoBVkt8w7MPG72TrKIu85MIdXwDuzJYeZuUPFPNwA=\ngithub.com/lyft/protoc-gen-star/v2 v2.0.4-0.20230330145011-496ad1ac90a4/go.mod h1:amey7yeodaJhXSbf/TlLvWiqQfLOSpEk//mLlc+axEk=\ngithub.com/magefile/mage v1.14.0/go.mod h1:z5UZb/iS3GoOSn0JgWuiw7dxlurVYTu+/jHXqQg881A=\ngithub.com/mailru/easyjson v0.0.0-20190312143242-1de009706dbe/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=\ngithub.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=\ngithub.com/mattn/go-colorable v0.1.14 h1:9A9LHSqF/7dyVVX6g0U9cwm9pG3kP9gSzcuIPHPsaIE=\ngithub.com/mattn/go-colorable v0.1.14/go.mod h1:6LmQG8QLFO4G5z1gPvYEzlUgJ2wF+stgPZH1UqBm1s8=\ngithub.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=\ngithub.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=\ngithub.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=\ngithub.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=\ngithub.com/mattn/go-sqlite3 v1.14.14/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU=\ngithub.com/mattn/go-sqlite3 v1.14.16/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg=\ngithub.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=\ngithub.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4=\ngithub.com/matttproud/golang_protobuf_extensions/v2 v2.0.0/go.mod h1:QUyp042oQthUoa9bqDv0ER0wrtXnBruoNd7aNjkbP+k=\ngithub.com/microcosm-cc/bluemonday v1.0.1/go.mod h1:hsXNsILzKxV+sX77C5b8FSuKF00vh2OMYv+xgHpAMF4=\ngithub.com/minio/asm2plan9s v0.0.0-20200509001527-cdd76441f9d8/go.mod h1:mC1jAcsrzbxHt8iiaC+zU4b1ylILSosueou12R++wfY=\ngithub.com/minio/c2goasm v0.0.0-20190812172519-36a3d3bbc4f3/go.mod h1:RagcQ7I8IeTMnF8JTXieKnO4Z6JCsikNEzj0DwauVzE=\ngithub.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y=\ngithub.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=\ngithub.com/moby/docker-image-spec v1.3.1 h1:jMKff3w6PgbfSa69GfNg+zN/XLhfXJGnEx3Nl2EsFP0=\ngithub.com/moby/docker-image-spec v1.3.1/go.mod h1:eKmb5VW8vQEh/BAr2yvVNvuiJuY6UIocYsFu/DxxRpo=\ngithub.com/moby/sys/atomicwriter v0.1.0/go.mod h1:Ul8oqv2ZMNHOceF643P6FKPXeCmYtlQMvpizfsSoaWs=\ngithub.com/moby/sys/sequential v0.6.0/go.mod h1:uyv8EUTrca5PnDsdMGXhZe6CCe8U/UiTWd+lL+7b/Ko=\ngithub.com/moby/term v0.0.0-20221205130635-1aeaba878587/go.mod h1:8FzsFHVUBGZdbDsJw/ot+X+d5HLUbvklYLJ9uGfcI3Y=\ngithub.com/moby/term v0.5.0 h1:xt8Q1nalod/v7BqbG21f8mQPqH+xAaC9C3N3wfWbVP0=\ngithub.com/moby/term v0.5.0/go.mod h1:8FzsFHVUBGZdbDsJw/ot+X+d5HLUbvklYLJ9uGfcI3Y=\ngithub.com/moby/term v0.5.2 h1:6qk3FJAFDs6i/q3W/pQ97SX192qKfZgGjCQqfCJkgzQ=\ngithub.com/moby/term v0.5.2/go.mod h1:d3djjFCrjnB+fl8NJux+EJzu0msscUP+f8it8hPkFLc=\ngithub.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=\ngithub.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=\ngithub.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=\ngithub.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=\ngithub.com/morikuni/aec v1.0.0 h1:nP9CBfwrvYnBRgY6qfDQkygYDmYwOilePFkwzv4dU8A=\ngithub.com/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc=\ngithub.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=\ngithub.com/neelance/astrewrite v0.0.0-20160511093645-99348263ae86/go.mod h1:kHJEU3ofeGjhHklVoIGuVj85JJwZ6kWPaJwCIxgnFmo=\ngithub.com/neelance/sourcemap v0.0.0-20151028013722-8c68805598ab/go.mod h1:Qr6/a/Q4r9LP1IltGz7tA7iOK1WonHEYhu1HRBA7ZiM=\ngithub.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=\ngithub.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A=\ngithub.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU=\ngithub.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=\ngithub.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk=\ngithub.com/onsi/ginkgo v1.16.4 h1:29JGrr5oVBm5ulCWet69zQkzWipVXIol6ygQUe/EzNc=\ngithub.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0=\ngithub.com/onsi/ginkgo/v2 v2.23.4 h1:ktYTpKJAVZnDT4VjxSbiBenUjmlL/5QkBEocaWXiQus=\ngithub.com/onsi/ginkgo/v2 v2.23.4/go.mod h1:Bt66ApGPBFzHyR+JO10Zbt0Gsp4uWxu5mIOTusL46e8=\ngithub.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=\ngithub.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=\ngithub.com/onsi/gomega v1.36.3/go.mod h1:8D9+Txp43QWKhM24yyOBEdpkzN8FvJyAwecBgsU4KU0=\ngithub.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U=\ngithub.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM=\ngithub.com/opencontainers/image-spec v1.1.0-rc3/go.mod h1:X4pATf0uXsnn3g5aiGIsVnJBR4mxhKzfwmvK/B2NTm8=\ngithub.com/opencontainers/image-spec v1.1.0-rc4 h1:oOxKUJWnFC4YGHCCMNql1x4YaDfYBTS5Y4x/Cgeo1E0=\ngithub.com/opencontainers/image-spec v1.1.0-rc4/go.mod h1:X4pATf0uXsnn3g5aiGIsVnJBR4mxhKzfwmvK/B2NTm8=\ngithub.com/opencontainers/image-spec v1.1.1 h1:y0fUlFfIZhPF1W537XOLg0/fcx6zcHCJwooC2xJA040=\ngithub.com/opencontainers/image-spec v1.1.1/go.mod h1:qpqAh3Dmcf36wStyyWU+kCeDgrGnAve2nCC8+7h8Q0M=\ngithub.com/openzipkin/zipkin-go v0.1.1/go.mod h1:NtoC/o8u3JlF1lSlyPNswIbeQH9bJTmOf0Erfk+hxe8=\ngithub.com/orisano/pixelmatch v0.0.0-20220722002657-fb0b55479cde/go.mod h1:nZgzbfBr3hhjoZnS66nKrHmduYNpc34ny7RK4z5/HM0=\ngithub.com/phpdave11/gofpdf v1.4.2/go.mod h1:zpO6xFn9yxo3YLyMvW8HcKWVdbNqgIfOOp2dXMnm1mY=\ngithub.com/phpdave11/gofpdi v1.0.12/go.mod h1:vBmVV0Do6hSBHC8uKUQ71JGW+ZGQq74llk/7bXwjDoI=\ngithub.com/phpdave11/gofpdi v1.0.13/go.mod h1:vBmVV0Do6hSBHC8uKUQ71JGW+ZGQq74llk/7bXwjDoI=\ngithub.com/pierrec/lz4/v4 v4.1.15/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4=\ngithub.com/pierrec/lz4/v4 v4.1.18/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4=\ngithub.com/pkg/browser v0.0.0-20210911075715-681adbf594b8 h1:KoWmjvw+nsYOo29YJK9vDA65RGE3NrOnUtO7a+RF9HU=\ngithub.com/pkg/browser v0.0.0-20210911075715-681adbf594b8/go.mod h1:HKlIX3XHQyzLZPlr7++PzdhaXEj94dEiJgZDTsxEqUI=\ngithub.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c h1:+mdjkGKdHQG3305AYmdv1U2eRNDiU2ErMBj1gwrq8eQ=\ngithub.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c/go.mod h1:7rwL4CYBLnjLxUqIJNnCWiEdr3bn6IUYi15bNlnbCCU=\ngithub.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA=\ngithub.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=\ngithub.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=\ngithub.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=\ngithub.com/pkg/profile v1.7.0 h1:hnbDkaNWPCLMO9wGLdBFTIZvzDrDfBM2072E1S9gJkA=\ngithub.com/pkg/profile v1.7.0/go.mod h1:8Uer0jas47ZQMJ7VD+OHknK4YDY07LPUC6dEvqDjvNo=\ngithub.com/pkg/sftp v1.10.1/go.mod h1:lYOWFsE0bwd1+KfKJaKeuokY15vzFx25BLbzYYoAxZI=\ngithub.com/pkg/sftp v1.13.1/go.mod h1:3HaPG6Dq1ILlpPZRO0HVMrsydcdLt6HRDccSgb87qRg=\ngithub.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10/go.mod h1:t/avpk3KcrXxUnYOhZhMXJlSEyie6gQbtLq5NM3loB8=\ngithub.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=\ngithub.com/prashantv/gostub v1.1.0/go.mod h1:A5zLQHz7ieHGG7is6LLXLz7I8+3LZzsrV0P1IAHhP5U=\ngithub.com/prometheus/client_golang v0.8.0/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=\ngithub.com/prometheus/client_golang v1.19.1/go.mod h1:mP78NwGzrVks5S2H6ab8+ZZGJLZUq1hoULYBAYBw1Ho=\ngithub.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=\ngithub.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=\ngithub.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=\ngithub.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY=\ngithub.com/prometheus/common v0.0.0-20180801064454-c7de2306084e/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro=\ngithub.com/prometheus/common v0.48.0/go.mod h1:0/KsvlIEfPQCQ5I2iNSAWKPZziNCvRs5EC6ILDTlAPc=\ngithub.com/prometheus/procfs v0.0.0-20180725123919-05ee40e3a273/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=\ngithub.com/prometheus/procfs v0.12.0/go.mod h1:pcuDEFsWDnvcgNzo4EEweacyhjeA9Zk3cnaOZAZEfOo=\ngithub.com/quic-go/qpack v0.5.1 h1:giqksBPnT/HDtZ6VhtFKgoLOWmlyo9Ei6u9PqzIMbhI=\ngithub.com/quic-go/qpack v0.5.1/go.mod h1:+PC4XFrEskIVkcLzpEkbLqq1uCoxPhQuvK5rH1ZgaEg=\ngithub.com/quic-go/quic-go v0.52.0 h1:/SlHrCRElyaU6MaEPKqKr9z83sBg2v4FLLvWM+Z47pA=\ngithub.com/quic-go/quic-go v0.52.0/go.mod h1:MFlGGpcpJqRAfmYi6NC2cptDPSxRWTOGNuP4wqrWmzQ=\ngithub.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo=\ngithub.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo=\ngithub.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ=\ngithub.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=\ngithub.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc=\ngithub.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs=\ngithub.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o=\ngithub.com/rs/cors v1.9.0 h1:l9HGsTsHJcvW14Nk7J9KFz8bzeAWXn3CG6bgt7LsrAE=\ngithub.com/rs/cors v1.9.0/go.mod h1:XyqrcTp5zjWr1wsJ8PIRZssZ8b/WMcMf71DJnit4EMU=\ngithub.com/rs/cors v1.11.1 h1:eU3gRzXLRK57F5rKMGMZURNdIG4EoAmX8k94r9wXWHA=\ngithub.com/rs/cors v1.11.1/go.mod h1:XyqrcTp5zjWr1wsJ8PIRZssZ8b/WMcMf71DJnit4EMU=\ngithub.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g=\ngithub.com/russross/blackfriday v1.6.0 h1:KqfZb0pUVN2lYqZUYRddxF4OR8ZMURnJIG5Y3VRLtww=\ngithub.com/russross/blackfriday v1.6.0/go.mod h1:ti0ldHuxg49ri4ksnFxlkCfN+hvslNlmVHqNRXXJNAY=\ngithub.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=\ngithub.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk=\ngithub.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=\ngithub.com/ruudk/golang-pdf417 v0.0.0-20181029194003-1af4ab5afa58/go.mod h1:6lfFZQK844Gfx8o5WFuvpxWRwnSoipWe/p622j1v06w=\ngithub.com/ruudk/golang-pdf417 v0.0.0-20201230142125-a7e3863a1245/go.mod h1:pQAZKsJ8yyVxGRWYNEm9oFB8ieLgKFnamEyDmSA0BRk=\ngithub.com/santhosh-tekuri/jsonschema/v5 v5.3.1/go.mod h1:uToXkOrWAZ6/Oc07xWQrPOhJotwFIyu2bBVN41fcDUY=\ngithub.com/segmentio/asm v1.2.0 h1:9BQrFxC+YOHJlTlHGkTrFWf59nbL3XnCoFLTwDCI7ys=\ngithub.com/segmentio/asm v1.2.0/go.mod h1:BqMnlJP91P8d+4ibuonYZw9mfnzI9HfxselHZr5aAcs=\ngithub.com/segmentio/encoding v0.5.1 h1:LhmgXA5/alniiqfc4cYYrxF6DbUQ3m8MVz4/LQIU1mg=\ngithub.com/segmentio/encoding v0.5.1/go.mod h1:HS1ZKa3kSN32ZHVZ7ZLPLXWvOVIiZtyJnO1gPH1sKt0=\ngithub.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo=\ngithub.com/shurcooL/component v0.0.0-20170202220835-f88ec8f54cc4/go.mod h1:XhFIlyj5a1fBNx5aJTbKoIq0mNaPvOagO+HjB3EtxrY=\ngithub.com/shurcooL/events v0.0.0-20181021180414-410e4ca65f48/go.mod h1:5u70Mqkb5O5cxEA8nxTsgrgLehJeAw6Oc4Ab1c/P1HM=\ngithub.com/shurcooL/github_flavored_markdown v0.0.0-20181002035957-2122de532470/go.mod h1:2dOwnU2uBioM+SGy2aZoq1f/Sd1l9OkAeAUvjSyvgU0=\ngithub.com/shurcooL/go v0.0.0-20180423040247-9e1955d9fb6e/go.mod h1:TDJrrUr11Vxrven61rcy3hJMUqaf/CLWYhHNPmT14Lk=\ngithub.com/shurcooL/go-goon v0.0.0-20170922171312-37c2f522c041/go.mod h1:N5mDOmsrJOB+vfqUK+7DmDyjhSLIIBnXo9lvZJj3MWQ=\ngithub.com/shurcooL/gofontwoff v0.0.0-20180329035133-29b52fc0a18d/go.mod h1:05UtEgK5zq39gLST6uB0cf3NEHjETfB4Fgr3Gx5R9Vw=\ngithub.com/shurcooL/gopherjslib v0.0.0-20160914041154-feb6d3990c2c/go.mod h1:8d3azKNyqcHP1GaQE/c6dDgjkgSx2BZ4IoEi4F1reUI=\ngithub.com/shurcooL/highlight_diff v0.0.0-20170515013008-09bb4053de1b/go.mod h1:ZpfEhSmds4ytuByIcDnOLkTHGUI6KNqRNPDLHDk+mUU=\ngithub.com/shurcooL/highlight_go v0.0.0-20181028180052-98c3abbbae20/go.mod h1:UDKB5a1T23gOMUJrI+uSuH0VRDStOiUVSjBTRDVBVag=\ngithub.com/shurcooL/home v0.0.0-20181020052607-80b7ffcb30f9/go.mod h1:+rgNQw2P9ARFAs37qieuu7ohDNQ3gds9msbT2yn85sg=\ngithub.com/shurcooL/htmlg v0.0.0-20170918183704-d01228ac9e50/go.mod h1:zPn1wHpTIePGnXSHpsVPWEktKXHr6+SS6x/IKRb7cpw=\ngithub.com/shurcooL/httperror v0.0.0-20170206035902-86b7830d14cc/go.mod h1:aYMfkZ6DWSJPJ6c4Wwz3QtW22G7mf/PEgaB9k/ik5+Y=\ngithub.com/shurcooL/httpfs v0.0.0-20171119174359-809beceb2371/go.mod h1:ZY1cvUeJuFPAdZ/B6v7RHavJWZn2YPVFQ1OSXhCGOkg=\ngithub.com/shurcooL/httpgzip v0.0.0-20180522190206-b1c53ac65af9/go.mod h1:919LwcH0M7/W4fcZ0/jy0qGght1GIhqyS/EgWGH2j5Q=\ngithub.com/shurcooL/issues v0.0.0-20181008053335-6292fdc1e191/go.mod h1:e2qWDig5bLteJ4fwvDAc2NHzqFEthkqn7aOZAOpj+PQ=\ngithub.com/shurcooL/issuesapp v0.0.0-20180602232740-048589ce2241/go.mod h1:NPpHK2TI7iSaM0buivtFUc9offApnI0Alt/K8hcHy0I=\ngithub.com/shurcooL/notifications v0.0.0-20181007000457-627ab5aea122/go.mod h1:b5uSkrEVM1jQUspwbixRBhaIjIzL2xazXp6kntxYle0=\ngithub.com/shurcooL/octicon v0.0.0-20181028054416-fa4f57f9efb2/go.mod h1:eWdoE5JD4R5UVWDucdOPg1g2fqQRq78IQa9zlOV1vpQ=\ngithub.com/shurcooL/reactions v0.0.0-20181006231557-f2e0b4ca5b82/go.mod h1:TCR1lToEk4d2s07G3XGfz2QrgHXg4RJBvjrOozvoWfk=\ngithub.com/shurcooL/sanitized_anchor_name v0.0.0-20170918181015-86672fcb3f95/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=\ngithub.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=\ngithub.com/shurcooL/users v0.0.0-20180125191416-49c67e49c537/go.mod h1:QJTqeLYEDaXHZDBsXlPCDqdhQuJkuw4NOtaxYe3xii4=\ngithub.com/shurcooL/webdavfs v0.0.0-20170829043945-18c3829fa133/go.mod h1:hKmq5kWdCj2z2KEozexVbfEZIWiTjhE0+UjmZgPqehw=\ngithub.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=\ngithub.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=\ngithub.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=\ngithub.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=\ngithub.com/sourcegraph/annotate v0.0.0-20160123013949-f4cad6c6324d/go.mod h1:UdhH50NIW0fCiwBSr0co2m7BnFLdv4fQTgdqdJTHFeE=\ngithub.com/sourcegraph/syntaxhighlight v0.0.0-20170531221838-bd320f5d308e/go.mod h1:HuIsMU8RRBOtsCgI77wP899iHVBQpCmg4ErYMZB+2IA=\ngithub.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=\ngithub.com/spf13/afero v1.3.3/go.mod h1:5KUK8ByomD5Ti5Artl0RtHeI5pTF7MIDuXL3yY520V4=\ngithub.com/spf13/afero v1.6.0/go.mod h1:Ai8FlHk4v/PARR026UzYexafAt9roJ7LcLMAmO6Z93I=\ngithub.com/spf13/afero v1.9.2/go.mod h1:iUV7ddyEEZPO5gA3zD4fJt6iStLlL+Lg4m2cihcDf8Y=\ngithub.com/spf13/afero v1.10.0/go.mod h1:UBogFpq8E9Hx+xc5CNTTEpTnuHVmXDwZcZcE1eb/UhQ=\ngithub.com/spf13/cobra v1.7.0 h1:hyqWnYt1ZQShIddO5kBpj3vu05/++x6tJ6dg8EC572I=\ngithub.com/spf13/cobra v1.7.0/go.mod h1:uLxZILRyS/50WlhOIKD7W6V5bgeIt+4sICxh6uRMrb0=\ngithub.com/spf13/cobra v1.9.1 h1:CXSaggrXdbHK9CF+8ywj8Amf7PBRmPCOJugH954Nnlo=\ngithub.com/spf13/cobra v1.9.1/go.mod h1:nDyEzZ8ogv936Cinf6g1RU9MRY64Ir93oCnqb9wxYW0=\ngithub.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=\ngithub.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=\ngithub.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=\ngithub.com/spf13/pflag v1.0.6 h1:jFzHGLGAlb3ruxLB8MhbI6A8+AQX/2eW4qeyNZXNp2o=\ngithub.com/spf13/pflag v1.0.6/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=\ngithub.com/spiffe/go-spiffe/v2 v2.5.0/go.mod h1:P+NxobPc6wXhVtINNtFjNWGBTreew1GBUCwT2wPmb7g=\ngithub.com/stoewer/go-strcase v1.3.0 h1:g0eASXYtp+yvN9fK8sH94oCIk0fau9uV1/ZdJ0AVEzs=\ngithub.com/stoewer/go-strcase v1.3.0/go.mod h1:fAH5hQ5pehh+j3nZfvwdk2RgEgQjAoM8wodgtPmh1xo=\ngithub.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=\ngithub.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=\ngithub.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=\ngithub.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA=\ngithub.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=\ngithub.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=\ngithub.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=\ngithub.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=\ngithub.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=\ngithub.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=\ngithub.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=\ngithub.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=\ngithub.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=\ngithub.com/stretchr/testify v1.8.3/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=\ngithub.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=\ngithub.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=\ngithub.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=\ngithub.com/substrait-io/substrait-go v0.4.2/go.mod h1:qhpnLmrcvAnlZsUyPXZRqldiHapPTXC3t7xFgDi3aQg=\ngithub.com/tarm/serial v0.0.0-20180830185346-98f6abe2eb07/go.mod h1:kDXzergiv9cbyO7IOYJZWg1U88JhDg3PB6klq9Hg2pA=\ngithub.com/tetratelabs/wazero v1.3.1 h1:rnb9FgOEQRLLR8tgoD1mfjNjMhFeWRUk+a4b4j/GpUM=\ngithub.com/tetratelabs/wazero v1.3.1/go.mod h1:wYx2gNRg8/WihJfSDxA1TIL8H+GkfLYm+bIfbblu9VQ=\ngithub.com/tetratelabs/wazero v1.9.0 h1:IcZ56OuxrtaEz8UYNRHBrUa9bYeX9oVY93KspZZBf/I=\ngithub.com/tetratelabs/wazero v1.9.0/go.mod h1:TSbcXCfFP0L2FGkRPxHphadXPjo1T6W+CseNNY7EkjM=\ngithub.com/urfave/cli v1.22.4/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=\ngithub.com/urfave/cli v1.22.12/go.mod h1:sSBEIC79qR6OvcmsD4U3KABeOTxDqQtdDnaFuUN30b8=\ngithub.com/urfave/cli v1.22.16/go.mod h1:EeJR6BKodywf4zciqrdw6hpCPk68JO9z5LazXZMn5Po=\ngithub.com/vbatts/tar-split v0.11.2/go.mod h1:vV3ZuO2yWSVsz+pfFzDG/upWH1JhjOiEaWq6kXyQ3VI=\ngithub.com/vbatts/tar-split v0.11.3 h1:hLFqsOLQ1SsppQNTMpkpPXClLDfC2A3Zgy9OUU+RVck=\ngithub.com/vbatts/tar-split v0.11.3/go.mod h1:9QlHN18E+fEH7RdG+QAJJcuya3rqT7eXSTY7wGrAokY=\ngithub.com/vbatts/tar-split v0.12.1 h1:CqKoORW7BUWBe7UL/iqTVvkTBOF8UvOMKOIZykxnnbo=\ngithub.com/vbatts/tar-split v0.12.1/go.mod h1:eF6B6i6ftWQcDqEn3/iGFRFRo8cBIMSJVOpnNdfTMFA=\ngithub.com/viant/assertly v0.4.8/go.mod h1:aGifi++jvCrUaklKEKT0BU95igDNaqkvz+49uaYMPRU=\ngithub.com/viant/toolbox v0.24.0/go.mod h1:OxMCG57V0PXuIP2HNQrtJf2CjqdmbrOx5EkMILuUhzM=\ngithub.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU=\ngithub.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ=\ngithub.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y=\ngithub.com/xhit/go-str2duration v1.2.0/go.mod h1:3cPSlfZlUHVlneIVfePFWcJZsuwf+P1v2SRTV4cUmp4=\ngithub.com/xhit/go-str2duration/v2 v2.1.0/go.mod h1:ohY8p+0f07DiV6Em5LKB0s2YpLtXVyJfNt1+BlmyAsU=\ngithub.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=\ngithub.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=\ngithub.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=\ngithub.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=\ngithub.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=\ngithub.com/yuin/goldmark v1.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=\ngithub.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=\ngithub.com/zeebo/assert v1.3.0/go.mod h1:Pq9JiuJQpG8JLJdtkwrJESF0Foym2/D9XMU5ciN/wJ0=\ngithub.com/zeebo/errs v1.4.0/go.mod h1:sgbWHsvVuTPHcqJJGQ1WhI5KbWlHYz+2+2C/LSEtCw4=\ngithub.com/zeebo/xxh3 v1.0.2/go.mod h1:5NWz9Sef7zIDm2JHfFlcQvNekmcEl9ekUZQQKCYaDcA=\ngo.einride.tech/aip v0.66.0/go.mod h1:qAhMsfT7plxBX+Oy7Huol6YUvZ0ZzdUz26yZsQwfl1M=\ngo.lsp.dev/jsonrpc2 v0.10.0 h1:Pr/YcXJoEOTMc/b6OTmcR1DPJ3mSWl/SWiU1Cct6VmI=\ngo.lsp.dev/jsonrpc2 v0.10.0/go.mod h1:fmEzIdXPi/rf6d4uFcayi8HpFP1nBF99ERP1htC72Ac=\ngo.lsp.dev/pkg v0.0.0-20210717090340-384b27a52fb2 h1:hCzQgh6UcwbKgNSRurYWSqh8MufqRRPODRBblutn4TE=\ngo.lsp.dev/pkg v0.0.0-20210717090340-384b27a52fb2/go.mod h1:gtSHRuYfbCT0qnbLnovpie/WEmqyJ7T4n6VXiFMBtcw=\ngo.lsp.dev/protocol v0.12.0 h1:tNprUI9klQW5FAFVM4Sa+AbPFuVQByWhP1ttNUAjIWg=\ngo.lsp.dev/protocol v0.12.0/go.mod h1:Qb11/HgZQ72qQbeyPfJbu3hZBH23s1sr4st8czGeDMQ=\ngo.lsp.dev/uri v0.3.0 h1:KcZJmh6nFIBeJzTugn5JTU6OOyG0lDOo3R9KwTxTYbo=\ngo.lsp.dev/uri v0.3.0/go.mod h1:P5sbO1IQR+qySTWOCnhnK7phBx+W3zbLqSMDJNTw88I=\ngo.opencensus.io v0.18.0/go.mod h1:vKdFvxhtzZ9onBp9VKHK8z/sRpBMnKAsufL7wlDrCOA=\ngo.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=\ngo.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8=\ngo.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=\ngo.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=\ngo.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=\ngo.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk=\ngo.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E=\ngo.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo=\ngo.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA=\ngo.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A=\ngo.opentelemetry.io/contrib/detectors/gcp v1.34.0/go.mod h1:cV4BMFcscUR/ckqLkbfQmF0PRsq8w/lMGzdbCSveBHo=\ngo.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.49.0/go.mod h1:Mjt1i1INqiaoZOMGR1RIUJN+i3ChKoFRqzrRQhlkbs0=\ngo.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0 h1:F7Jx+6hwnZ41NSFTO5q4LYDtJRXBf2PD0rNBkeB/lus=\ngo.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0/go.mod h1:UHB22Z8QsdRDrnAtX4PntOl36ajSxcdUMt1sF7Y6E7Q=\ngo.opentelemetry.io/otel v1.16.0 h1:Z7GVAX/UkAXPKsy94IU+i6thsQS4nb7LviLpnaNeW8s=\ngo.opentelemetry.io/otel v1.16.0/go.mod h1:vl0h9NUa1D5s1nv3A5vZOYWn8av4K8Ml6JDeHrT/bx4=\ngo.opentelemetry.io/otel v1.36.0 h1:UumtzIklRBY6cI/lllNZlALOF5nNIzJVb16APdvgTXg=\ngo.opentelemetry.io/otel v1.36.0/go.mod h1:/TcFMXYjyRNh8khOAO9ybYkqaDBb/70aVwkNML4pP8E=\ngo.opentelemetry.io/otel/exporters/otlp/otlptrace v1.36.0/go.mod h1:90PoxvaEB5n6AOdZvi+yWJQoE95U8Dhhw2bSyRqnTD0=\ngo.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.33.0/go.mod h1:wAy0T/dUbs468uOlkT31xjvqQgEVXv58BRFWEgn5v/0=\ngo.opentelemetry.io/otel/metric v1.16.0 h1:RbrpwVG1Hfv85LgnZ7+txXioPDoh6EdbZHo26Q3hqOo=\ngo.opentelemetry.io/otel/metric v1.16.0/go.mod h1:QE47cpOmkwipPiefDwo2wDzwJrlfxxNYodqc4xnGCo4=\ngo.opentelemetry.io/otel/metric v1.36.0 h1:MoWPKVhQvJ+eeXWHFBOPoBOi20jh6Iq2CcCREuTYufE=\ngo.opentelemetry.io/otel/metric v1.36.0/go.mod h1:zC7Ks+yeyJt4xig9DEw9kuUFe5C3zLbVjV2PzT6qzbs=\ngo.opentelemetry.io/otel/sdk v1.16.0 h1:Z1Ok1YsijYL0CSJpHt4cS3wDDh7p572grzNrBMiMWgE=\ngo.opentelemetry.io/otel/sdk v1.16.0/go.mod h1:tMsIuKXuuIWPBAOrH+eHtvhTL+SntFtXF9QD68aP6p4=\ngo.opentelemetry.io/otel/sdk v1.36.0/go.mod h1:+lC+mTgD+MUWfjJubi2vvXWcVxyr9rmlshZni72pXeY=\ngo.opentelemetry.io/otel/sdk/metric v0.39.0/go.mod h1:piDIRgjcK7u0HCL5pCA4e74qpK/jk3NiUoAHATVAmiI=\ngo.opentelemetry.io/otel/sdk/metric v1.36.0/go.mod h1:qTNOhFDfKRwX0yXOqJYegL5WRaW376QbB7P4Pb0qva4=\ngo.opentelemetry.io/otel/trace v1.16.0 h1:8JRpaObFoW0pxuVPapkgH8UhHQj+bJW8jJsCZEu5MQs=\ngo.opentelemetry.io/otel/trace v1.16.0/go.mod h1:Yt9vYq1SdNz3xdjZZK7wcXv1qv2pwLkqr2QVwea0ef0=\ngo.opentelemetry.io/otel/trace v1.36.0 h1:ahxWNuqZjpdiFAyrIoQ4GIiAIhxAunQR6MUoKrsNd4w=\ngo.opentelemetry.io/otel/trace v1.36.0/go.mod h1:gQ+OnDZzrybY4k4seLzPAWNwVBBVlF2szhehOBB/tGA=\ngo.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI=\ngo.opentelemetry.io/proto/otlp v0.15.0/go.mod h1:H7XAot3MsfNsj7EXtrA2q5xSNQ10UqI405h3+duxN4U=\ngo.opentelemetry.io/proto/otlp v1.7.0/go.mod h1:fSKjH6YJ7HDlwzltzyMj036AJ3ejJLCgCSHGj4efDDo=\ngo.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=\ngo.uber.org/atomic v1.9.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=\ngo.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE=\ngo.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0=\ngo.uber.org/automaxprocs v1.6.0 h1:O3y2/QNTOdbF+e/dpXNNW7Rx2hZ4sTIPyybbxyNqTUs=\ngo.uber.org/automaxprocs v1.6.0/go.mod h1:ifeIMSnPZuznNm6jmdzmU3/bfk01Fe2fotchwEFJ8r8=\ngo.uber.org/goleak v1.1.11/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ=\ngo.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=\ngo.uber.org/mock v0.5.2 h1:LbtPTcP8A5k9WPXj54PPPbjcI4Y6lhyOZXn+VS7wNko=\ngo.uber.org/mock v0.5.2/go.mod h1:wLlUxC2vVTPTaE3UD51E0BGOAElKrILxhVSDYQLld5o=\ngo.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU=\ngo.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0=\ngo.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=\ngo.uber.org/zap v1.24.0 h1:FiJd5l1UOLj0wCgbSE0rwwXHzEdAZS6hiiSnxJN/D60=\ngo.uber.org/zap v1.24.0/go.mod h1:2kMP+WWQ8aoFoedH3T2sq6iJ2yDWpHbP0f6MQbS9Gkg=\ngo.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8=\ngo.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E=\ngo4.org v0.0.0-20180809161055-417644f6feb5/go.mod h1:MkTOUMDaeVYJUOUsaDXIhWPZYa1yOyC1qaOBpL57BhE=\ngolang.org/x/build v0.0.0-20190111050920-041ab4dc3f9d/go.mod h1:OWs+y06UdEOHN4y+MfF/py+xQ/tYqIWW03b70/CG9Rw=\ngolang.org/x/crypto v0.0.0-20181030102418-4d3f4d9ffa16/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=\ngolang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=\ngolang.org/x/crypto v0.0.0-20190313024323-a1f597ede03a/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=\ngolang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=\ngolang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=\ngolang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=\ngolang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=\ngolang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=\ngolang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=\ngolang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=\ngolang.org/x/crypto v0.0.0-20211108221036-ceb1ce70b4fa/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=\ngolang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=\ngolang.org/x/crypto v0.1.0/go.mod h1:RecgLatLF4+eUMCP1PoPZQb+cVrJcOPbHkTkbkB9sbw=\ngolang.org/x/crypto v0.11.0 h1:6Ewdq3tDic1mg5xRO4milcWCfMVQhI4NkqWWvqejpuA=\ngolang.org/x/crypto v0.11.0/go.mod h1:xgJhtzW8F9jGdVFWZESrid1U1bjeNy4zgy5cRr/CIio=\ngolang.org/x/crypto v0.39.0 h1:SHs+kF4LP+f+p14esP5jAoDpHU8Gu/v9lFRK6IT5imM=\ngolang.org/x/crypto v0.39.0/go.mod h1:L+Xg3Wf6HoL4Bn4238Z6ft6KfEpN0tJGo53AAPC632U=\ngolang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=\ngolang.org/x/exp v0.0.0-20180807140117-3d87b88a115f/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=\ngolang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=\ngolang.org/x/exp v0.0.0-20190125153040-c74c464bbbf2/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=\ngolang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=\ngolang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=\ngolang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek=\ngolang.org/x/exp v0.0.0-20191002040644-a1355ae1e2c3/go.mod h1:NOZ3BPKG0ec/BKJQgnvsSFpcKLM5xXVWnvZS97DWHgE=\ngolang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY=\ngolang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=\ngolang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=\ngolang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=\ngolang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM=\ngolang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU=\ngolang.org/x/exp v0.0.0-20220827204233-334a2380cb91/go.mod h1:cyybsKvd6eL0RnXn6p/Grxp8F5bW7iYuBgsNCOHpMYE=\ngolang.org/x/exp v0.0.0-20230713183714-613f0c0eb8a1/go.mod h1:FXUEEKJgO7OQYeo8N01OfiKP8RXMtf6e8aTskBGqWdc=\ngolang.org/x/exp v0.0.0-20250606033433-dcc06ee1d476 h1:bsqhLWFR6G6xiQcb+JoGqdKdRU6WzPWmK8E0jxTjzo4=\ngolang.org/x/exp v0.0.0-20250606033433-dcc06ee1d476/go.mod h1:3//PLf8L/X+8b4vuAfHzxeRUl04Adcb341+IGKfnqS8=\ngolang.org/x/image v0.0.0-20180708004352-c73c2afc3b81/go.mod h1:ux5Hcp/YLpHSI86hEcLt0YII63i6oz57MZXIpbrjZUs=\ngolang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=\ngolang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=\ngolang.org/x/image v0.0.0-20190910094157-69e4b8554b2a/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=\ngolang.org/x/image v0.0.0-20200119044424-58c23975cae1/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=\ngolang.org/x/image v0.0.0-20200430140353-33d19683fad8/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=\ngolang.org/x/image v0.0.0-20200618115811-c13761719519/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=\ngolang.org/x/image v0.0.0-20201208152932-35266b937fa6/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=\ngolang.org/x/image v0.0.0-20210216034530-4410531fe030/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=\ngolang.org/x/image v0.0.0-20210607152325-775e3b0c77b9/go.mod h1:023OzeP/+EPmXeapQh35lcL3II3LrY8Ic+EFFKVhULM=\ngolang.org/x/image v0.0.0-20210628002857-a66eb6448b8d/go.mod h1:023OzeP/+EPmXeapQh35lcL3II3LrY8Ic+EFFKVhULM=\ngolang.org/x/image v0.0.0-20211028202545-6944b10bf410/go.mod h1:023OzeP/+EPmXeapQh35lcL3II3LrY8Ic+EFFKVhULM=\ngolang.org/x/image v0.0.0-20220302094943-723b81ca9867/go.mod h1:023OzeP/+EPmXeapQh35lcL3II3LrY8Ic+EFFKVhULM=\ngolang.org/x/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=\ngolang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=\ngolang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=\ngolang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=\ngolang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=\ngolang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=\ngolang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=\ngolang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=\ngolang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs=\ngolang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=\ngolang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=\ngolang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=\ngolang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=\ngolang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE=\ngolang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o=\ngolang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=\ngolang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY=\ngolang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=\ngolang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=\ngolang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=\ngolang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=\ngolang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=\ngolang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=\ngolang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=\ngolang.org/x/mod v0.5.0/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro=\ngolang.org/x/mod v0.5.1/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro=\ngolang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=\ngolang.org/x/mod v0.6.0/go.mod h1:4mET923SAdbXp2ki8ey+zGs1SLqsuM2Y0uvdZR/fUNI=\ngolang.org/x/mod v0.7.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=\ngolang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=\ngolang.org/x/mod v0.10.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=\ngolang.org/x/mod v0.11.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=\ngolang.org/x/mod v0.12.0 h1:rmsUpXtvNzj340zd98LZ4KntptpfRHwpFOHG188oHXc=\ngolang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=\ngolang.org/x/mod v0.25.0 h1:n7a+ZbQKQA/Ysbyb0/6IbB1H/X41mKgbhfv7AfG/44w=\ngolang.org/x/mod v0.25.0/go.mod h1:IXM97Txy2VM4PJ3gI61r1YEk/gAj6zAHN3AdZt6S9Ww=\ngolang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=\ngolang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=\ngolang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=\ngolang.org/x/net v0.0.0-20181029044818-c44066c5c816/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=\ngolang.org/x/net v0.0.0-20181106065722-10aee1819953/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=\ngolang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=\ngolang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=\ngolang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=\ngolang.org/x/net v0.0.0-20190313220215-9f648a60d977/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=\ngolang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=\ngolang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=\ngolang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=\ngolang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=\ngolang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=\ngolang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=\ngolang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=\ngolang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=\ngolang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=\ngolang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=\ngolang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=\ngolang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=\ngolang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=\ngolang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=\ngolang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=\ngolang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=\ngolang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=\ngolang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=\ngolang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=\ngolang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=\ngolang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=\ngolang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=\ngolang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=\ngolang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=\ngolang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=\ngolang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=\ngolang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=\ngolang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=\ngolang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=\ngolang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc=\ngolang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=\ngolang.org/x/net v0.0.0-20210503060351-7fd8e65b6420/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=\ngolang.org/x/net v0.0.0-20210813160813-60bc85c4be6d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=\ngolang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=\ngolang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=\ngolang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=\ngolang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=\ngolang.org/x/net v0.0.0-20220325170049-de3da57026de/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=\ngolang.org/x/net v0.0.0-20220412020605-290c469a71a5/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=\ngolang.org/x/net v0.0.0-20220425223048-2871e0cb64e4/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=\ngolang.org/x/net v0.0.0-20220607020251-c690dde0001d/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=\ngolang.org/x/net v0.0.0-20220617184016-355a448f1bc9/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=\ngolang.org/x/net v0.0.0-20220624214902-1bab6f366d9e/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=\ngolang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=\ngolang.org/x/net v0.0.0-20220909164309-bea034e7d591/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk=\ngolang.org/x/net v0.0.0-20221012135044-0b7e1fb9d458/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk=\ngolang.org/x/net v0.0.0-20221014081412-f15817d10f9b/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk=\ngolang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco=\ngolang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY=\ngolang.org/x/net v0.5.0/go.mod h1:DivGGAXEgPSlEBzxGzZI+ZLohi+xUj054jfeKui00ws=\ngolang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=\ngolang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=\ngolang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc=\ngolang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns=\ngolang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=\ngolang.org/x/net v0.12.0 h1:cfawfvKITfUsFCeJIHJrbSxpeu/E81khclypR0GVT50=\ngolang.org/x/net v0.12.0/go.mod h1:zEVYFnQC7m/vmpQFELhcD1EWkZlX69l4oqgmer6hfKA=\ngolang.org/x/net v0.41.0 h1:vBTly1HeNPEn3wtREYfy4GZ/NECgw2Cnl+nK6Nz3uvw=\ngolang.org/x/net v0.41.0/go.mod h1:B/K4NNqkfmg07DQYrbwvSluqCJOOXwUjeb/5lOisjbA=\ngolang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=\ngolang.org/x/oauth2 v0.0.0-20181017192945-9dcd33a902f4/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=\ngolang.org/x/oauth2 v0.0.0-20181203162652-d668ce993890/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=\ngolang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=\ngolang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=\ngolang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=\ngolang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=\ngolang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=\ngolang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=\ngolang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=\ngolang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=\ngolang.org/x/oauth2 v0.0.0-20210220000619-9bb904979d93/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=\ngolang.org/x/oauth2 v0.0.0-20210313182246-cd4f82c27b84/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=\ngolang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=\ngolang.org/x/oauth2 v0.0.0-20210628180205-a41e5a781914/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=\ngolang.org/x/oauth2 v0.0.0-20210805134026-6f1e6394065a/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=\ngolang.org/x/oauth2 v0.0.0-20210819190943-2bc19b11175f/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=\ngolang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=\ngolang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc=\ngolang.org/x/oauth2 v0.0.0-20220309155454-6242fa91716a/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc=\ngolang.org/x/oauth2 v0.0.0-20220411215720-9780585627b5/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc=\ngolang.org/x/oauth2 v0.0.0-20220608161450-d0670ef3b1eb/go.mod h1:jaDAt6Dkxork7LmZnYtzbRWj0W47D86a3TGe0YHBvmE=\ngolang.org/x/oauth2 v0.0.0-20220622183110-fd043fe589d2/go.mod h1:jaDAt6Dkxork7LmZnYtzbRWj0W47D86a3TGe0YHBvmE=\ngolang.org/x/oauth2 v0.0.0-20220822191816-0ebed06d0094/go.mod h1:h4gKUeWbJ4rQPri7E0u6Gs4e9Ri2zaLxzw5DI5XGrYg=\ngolang.org/x/oauth2 v0.0.0-20220909003341-f21342109be1/go.mod h1:h4gKUeWbJ4rQPri7E0u6Gs4e9Ri2zaLxzw5DI5XGrYg=\ngolang.org/x/oauth2 v0.0.0-20221006150949-b44042a4b9c1/go.mod h1:h4gKUeWbJ4rQPri7E0u6Gs4e9Ri2zaLxzw5DI5XGrYg=\ngolang.org/x/oauth2 v0.0.0-20221014153046-6fdb5e3db783/go.mod h1:h4gKUeWbJ4rQPri7E0u6Gs4e9Ri2zaLxzw5DI5XGrYg=\ngolang.org/x/oauth2 v0.4.0/go.mod h1:RznEsdpjGAINPTOF0UH/t+xJ75L18YO3Ho6Pyn+uRec=\ngolang.org/x/oauth2 v0.5.0/go.mod h1:9/XBHVqLaWO3/BRHs5jbpYCnOZVjj5V0ndyaAM7KB4I=\ngolang.org/x/oauth2 v0.6.0/go.mod h1:ycmewcwgD4Rpr3eZJLSB4Kyyljb3qDh40vJ8STE5HKw=\ngolang.org/x/oauth2 v0.7.0/go.mod h1:hPLQkd9LyjfXTiRohC/41GhcFqxisoUQ99sCUOHO9x4=\ngolang.org/x/oauth2 v0.30.0/go.mod h1:B++QgG3ZKulg6sRPGD/mqlHQs5rB3Ml9erfeDY7xKlU=\ngolang.org/x/perf v0.0.0-20180704124530-6e6d33e29852/go.mod h1:JLpeXjPJfIyPr5TlbXLkXWLhP8nz10XfvxElABhCtcw=\ngolang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sync v0.0.0-20220601150217-0de741cfad7f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sync v0.0.0-20220819030929-7fc1605a5dde/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sync v0.0.0-20220929204114-8fcdb60fdcc0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sync v0.3.0 h1:ftCYgMx6zT/asHUrPw8BLLscYtGznsLAnjq5RH9P66E=\ngolang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y=\ngolang.org/x/sync v0.15.0 h1:KWH3jNZsfyT6xfAfKiz6MRNmd46ByHDYaZ7KSkCtdW8=\ngolang.org/x/sync v0.15.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=\ngolang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=\ngolang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=\ngolang.org/x/sys v0.0.0-20181029174526-d69651ed3497/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=\ngolang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=\ngolang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20190316082340-a2f829d7f35f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20210220050731-9a76102bfb43/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20210225134936-a50acf3fe073/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20210304124612-50617c2ba197/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20210305230114-8fe3ee5dd75b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20210514084401-e8d321eab015/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20210603125802-9665404d3644/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20210616045830-e2b7044e8c71/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20210816183151-1e6c022a8912/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20210819135213-f52c844e1c1c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20210823070655-63515b42dcdf/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20210908233432-aa78b53d3365/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20211007075335-d3039528d8ac/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20211124211545-fe61309f8881/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20211210111614-af8b64212486/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20220128215802-99c3d69c2c27/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20220209214540-3681064d5158/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20220227234510-4e6760a101f9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20220310020820-b874c991c1a5/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20220328115105-d36c6a25d886/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20220502124256-b6088ccd6cba/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20220610221304-9f5ed59c137d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20220615213510-4f61da869c0c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20220624220833-87e55d714810/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20220825204002-c680a09ffe64/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20220829200755-d48e67d00261/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20220906165534-d0df966e6959/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.4.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.10.0 h1:SqMFp9UcQJZa+pmYuAKjd9xq1f0j5rLcDIk0mj4qAsA=\ngolang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.33.0 h1:q3i8TbbEz+JRD9ywIRlyRAQbM0qF7hu24q3teo2hbuw=\ngolang.org/x/sys v0.33.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=\ngolang.org/x/telemetry v0.0.0-20240521205824-bda55230c457/go.mod h1:pRgIJT+bRLFKnoM1ldnzKoxTIn14Yxz928LQRYYgIN0=\ngolang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=\ngolang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=\ngolang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=\ngolang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc=\ngolang.org/x/term v0.4.0/go.mod h1:9P2UbLfCdcvo3p/nzKvsmas4TnlujnuoV9hGgYzW1lQ=\ngolang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=\ngolang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U=\ngolang.org/x/term v0.7.0/go.mod h1:P32HKFT3hSsZrRxla30E9HqToFYAQPCMs/zFMBUFqPY=\ngolang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=\ngolang.org/x/term v0.10.0 h1:3R7pNqamzBraeqj/Tj8qt1aQ2HpmlC+Cx/qL/7hn4/c=\ngolang.org/x/term v0.10.0/go.mod h1:lpqdcUyK/oCiQxvxVrppt5ggO2KCZ5QblwqPnfZ6d5o=\ngolang.org/x/term v0.32.0 h1:DR4lr0TjUs3epypdhTOkMmuF5CDFJ/8pOnbzMZPQ7bg=\ngolang.org/x/term v0.32.0/go.mod h1:uZG1FhGx848Sqfsq4/DlJr3xGGsYMu/L5GW4abiaEPQ=\ngolang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=\ngolang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=\ngolang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=\ngolang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=\ngolang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=\ngolang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=\ngolang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=\ngolang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=\ngolang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=\ngolang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ=\ngolang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=\ngolang.org/x/text v0.5.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=\ngolang.org/x/text v0.6.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=\ngolang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=\ngolang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=\ngolang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=\ngolang.org/x/text v0.11.0 h1:LAntKIrcmeSKERyiOh0XMV39LXS8IE9UL2yP7+f5ij4=\ngolang.org/x/text v0.11.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=\ngolang.org/x/text v0.26.0 h1:P42AVeLghgTYr4+xUnTRKDMqpar+PtX7KWuNQL21L8M=\ngolang.org/x/text v0.26.0/go.mod h1:QK15LZJUUQVJxhz7wXgxSy/CJaTFjd0G+YLonydOVQA=\ngolang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=\ngolang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=\ngolang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=\ngolang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=\ngolang.org/x/time v0.0.0-20210723032227-1f47c861a9ac/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=\ngolang.org/x/time v0.0.0-20220922220347-f3bd1da661af/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=\ngolang.org/x/time v0.1.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=\ngolang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=\ngolang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=\ngolang.org/x/tools v0.0.0-20180525024113-a5b4c53f6e8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=\ngolang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=\ngolang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=\ngolang.org/x/tools v0.0.0-20181030000716-a0a13e073c7b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=\ngolang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=\ngolang.org/x/tools v0.0.0-20190206041539-40960b6deb8e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=\ngolang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=\ngolang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=\ngolang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=\ngolang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=\ngolang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=\ngolang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=\ngolang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=\ngolang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=\ngolang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=\ngolang.org/x/tools v0.0.0-20190624222133-a101b041ded4/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=\ngolang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=\ngolang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=\ngolang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=\ngolang.org/x/tools v0.0.0-20190927191325-030b2cf1153e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=\ngolang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=\ngolang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=\ngolang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=\ngolang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=\ngolang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=\ngolang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=\ngolang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=\ngolang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=\ngolang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=\ngolang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=\ngolang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=\ngolang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=\ngolang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=\ngolang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=\ngolang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=\ngolang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=\ngolang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw=\ngolang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw=\ngolang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8=\ngolang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=\ngolang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=\ngolang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=\ngolang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=\ngolang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=\ngolang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=\ngolang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=\ngolang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=\ngolang.org/x/tools v0.0.0-20200904185747-39188db58858/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE=\ngolang.org/x/tools v0.0.0-20201110124207-079ba7bd75cd/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=\ngolang.org/x/tools v0.0.0-20201124115921-2c860bdd6e78/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=\ngolang.org/x/tools v0.0.0-20201201161351-ac6f37ff4c2a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=\ngolang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=\ngolang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=\ngolang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=\ngolang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=\ngolang.org/x/tools v0.0.0-20210108195828-e2f9c7f1fc8e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=\ngolang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0=\ngolang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=\ngolang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=\ngolang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=\ngolang.org/x/tools v0.1.4/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=\ngolang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=\ngolang.org/x/tools v0.1.8/go.mod h1:nABZi5QlRsZVlzPpHl034qft6wpY4eDcsTt5AaioBiU=\ngolang.org/x/tools v0.1.9/go.mod h1:nABZi5QlRsZVlzPpHl034qft6wpY4eDcsTt5AaioBiU=\ngolang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=\ngolang.org/x/tools v0.2.0/go.mod h1:y4OqIKeOV/fWJetJ8bXPU1sEVniLMIyDAZWeHdV+NTA=\ngolang.org/x/tools v0.3.0/go.mod h1:/rWhSS2+zyEVwoJf8YAX6L2f0ntZ7Kn/mGgAWcipA5k=\ngolang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=\ngolang.org/x/tools v0.8.0/go.mod h1:JxBZ99ISMI5ViVkT1tr6tdNmXeTrcpVSD3vZ1RsRdN4=\ngolang.org/x/tools v0.11.0/go.mod h1:anzJrxPjNtfgiYQYirP2CPGzGLxrH2u2QBhn6Bf3qY8=\ngolang.org/x/tools v0.34.0 h1:qIpSLOxeCYGg9TrcJokLBG4KFA6d795g0xkBkiESGlo=\ngolang.org/x/tools v0.34.0/go.mod h1:pAP9OwEaY1CAW3HOmg3hLZC5Z0CCmzjAF2UQMSqNARg=\ngolang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=\ngolang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=\ngolang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=\ngolang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=\ngolang.org/x/xerrors v0.0.0-20220411194840-2f41105eb62f/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=\ngolang.org/x/xerrors v0.0.0-20220517211312-f3a8303e98df/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8=\ngolang.org/x/xerrors v0.0.0-20220609144429-65e65417b02f/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8=\ngolang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8=\ngolang.org/x/xerrors v0.0.0-20231012003039-104605ab7028/go.mod h1:NDW/Ps6MPRej6fsCIbMTohpP40sJ/P/vI1MoTEGwX90=\ngonum.org/v1/gonum v0.0.0-20180816165407-929014505bf4/go.mod h1:Y+Yx5eoAFn32cQvJDxZx5Dpnq+c3wtXuadVZAcxbbBo=\ngonum.org/v1/gonum v0.8.2/go.mod h1:oe/vMfY3deqTw+1EZJhuvEW2iwGF1bW9wwu7XCu0+v0=\ngonum.org/v1/gonum v0.9.3/go.mod h1:TZumC3NeyVQskjXqmyWt4S3bINhy7B4eYwW69EbyX+0=\ngonum.org/v1/gonum v0.11.0/go.mod h1:fSG4YDCxxUZQJ7rKsQrj0gMOg00Il0Z96/qMA4bVQhA=\ngonum.org/v1/gonum v0.12.0/go.mod h1:73TDxJfAAHeA8Mk9mf8NlIppyhQNo5GLTcYeqgo2lvY=\ngonum.org/v1/netlib v0.0.0-20190313105609-8cb42192e0e0/go.mod h1:wa6Ws7BG/ESfp6dHfk7C6KdzKA7wR7u/rKwOGE66zvw=\ngonum.org/v1/plot v0.0.0-20190515093506-e2840ee46a6b/go.mod h1:Wt8AAjI+ypCyYX3nZBvf6cAIx93T+c/OS2HFAYskSZc=\ngonum.org/v1/plot v0.9.0/go.mod h1:3Pcqqmp6RHvJI72kgb8fThyUnav364FOsdDo2aGW5lY=\ngonum.org/v1/plot v0.10.1/go.mod h1:VZW5OlhkL1mysU9vaqNHnsy86inf6Ot+jB3r+BczCEo=\ngoogle.golang.org/api v0.0.0-20180910000450-7ca32eb868bf/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0=\ngoogle.golang.org/api v0.0.0-20181030000543-1d582fd0359e/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0=\ngoogle.golang.org/api v0.1.0/go.mod h1:UGEZY7KEX120AnNLIHFMKIo4obdJhkp2tPbaPlQx13Y=\ngoogle.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE=\ngoogle.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M=\ngoogle.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=\ngoogle.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=\ngoogle.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=\ngoogle.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=\ngoogle.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=\ngoogle.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=\ngoogle.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=\ngoogle.golang.org/api v0.19.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=\ngoogle.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=\ngoogle.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=\ngoogle.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE=\ngoogle.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE=\ngoogle.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM=\ngoogle.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc=\ngoogle.golang.org/api v0.35.0/go.mod h1:/XrVsuzM0rZmrsbjJutiuftIzeuTQcEeaYcSk/mQ1dg=\ngoogle.golang.org/api v0.36.0/go.mod h1:+z5ficQTmoYpPn8LCUNVpK5I7hwkpjbcgqA7I34qYtE=\ngoogle.golang.org/api v0.40.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjRCQ8=\ngoogle.golang.org/api v0.41.0/go.mod h1:RkxM5lITDfTzmyKFPt+wGrCJbVfniCr2ool8kTBzRTU=\ngoogle.golang.org/api v0.43.0/go.mod h1:nQsDGjRXMo4lvh5hP0TKqF244gqhGcr/YSIykhUk/94=\ngoogle.golang.org/api v0.47.0/go.mod h1:Wbvgpq1HddcWVtzsVLyfLp8lDg6AA241LmgIL59tHXo=\ngoogle.golang.org/api v0.48.0/go.mod h1:71Pr1vy+TAZRPkPs/xlCf5SsU8WjuAWv1Pfjbtukyy4=\ngoogle.golang.org/api v0.50.0/go.mod h1:4bNT5pAuq5ji4SRZm+5QIkjny9JAyVD/3gaSihNefaw=\ngoogle.golang.org/api v0.51.0/go.mod h1:t4HdrdoNgyN5cbEfm7Lum0lcLDLiise1F8qDKX00sOU=\ngoogle.golang.org/api v0.54.0/go.mod h1:7C4bFFOvVDGXjfDTAsgGwDgAxRDeQ4X8NvUedIt6z3k=\ngoogle.golang.org/api v0.55.0/go.mod h1:38yMfeP1kfjsl8isn0tliTjIb1rJXcQi4UXlbqivdVE=\ngoogle.golang.org/api v0.56.0/go.mod h1:38yMfeP1kfjsl8isn0tliTjIb1rJXcQi4UXlbqivdVE=\ngoogle.golang.org/api v0.57.0/go.mod h1:dVPlbZyBo2/OjBpmvNdpn2GRm6rPy75jyU7bmhdrMgI=\ngoogle.golang.org/api v0.61.0/go.mod h1:xQRti5UdCmoCEqFxcz93fTl338AVqDgyaDRuOZ3hg9I=\ngoogle.golang.org/api v0.63.0/go.mod h1:gs4ij2ffTRXwuzzgJl/56BdwJaA194ijkfn++9tDuPo=\ngoogle.golang.org/api v0.67.0/go.mod h1:ShHKP8E60yPsKNw/w8w+VYaj9H6buA5UqDp8dhbQZ6g=\ngoogle.golang.org/api v0.70.0/go.mod h1:Bs4ZM2HGifEvXwd50TtW70ovgJffJYw2oRCOFU/SkfA=\ngoogle.golang.org/api v0.71.0/go.mod h1:4PyU6e6JogV1f9eA4voyrTY2batOLdgZ5qZ5HOCc4j8=\ngoogle.golang.org/api v0.74.0/go.mod h1:ZpfMZOVRMywNyvJFeqL9HRWBgAuRfSjJFpe9QtRRyDs=\ngoogle.golang.org/api v0.75.0/go.mod h1:pU9QmyHLnzlpar1Mjt4IbapUCy8J+6HD6GeELN69ljA=\ngoogle.golang.org/api v0.77.0/go.mod h1:pU9QmyHLnzlpar1Mjt4IbapUCy8J+6HD6GeELN69ljA=\ngoogle.golang.org/api v0.78.0/go.mod h1:1Sg78yoMLOhlQTeF+ARBoytAcH1NNyyl390YMy6rKmw=\ngoogle.golang.org/api v0.80.0/go.mod h1:xY3nI94gbvBrE0J6NHXhxOmW97HG7Khjkku6AFB3Hyg=\ngoogle.golang.org/api v0.84.0/go.mod h1:NTsGnUFJMYROtiquksZHBWtHfeMC7iYthki7Eq3pa8o=\ngoogle.golang.org/api v0.85.0/go.mod h1:AqZf8Ep9uZ2pyTvgL+x0D3Zt0eoT9b5E8fmzfu6FO2g=\ngoogle.golang.org/api v0.90.0/go.mod h1:+Sem1dnrKlrXMR/X0bPnMWyluQe4RsNoYfmNLhOIkzw=\ngoogle.golang.org/api v0.93.0/go.mod h1:+Sem1dnrKlrXMR/X0bPnMWyluQe4RsNoYfmNLhOIkzw=\ngoogle.golang.org/api v0.95.0/go.mod h1:eADj+UBuxkh5zlrSntJghuNeg8HwQ1w5lTKkuqaETEI=\ngoogle.golang.org/api v0.96.0/go.mod h1:w7wJQLTM+wvQpNf5JyEcBoxK0RH7EDrh/L4qfsuJ13s=\ngoogle.golang.org/api v0.97.0/go.mod h1:w7wJQLTM+wvQpNf5JyEcBoxK0RH7EDrh/L4qfsuJ13s=\ngoogle.golang.org/api v0.98.0/go.mod h1:w7wJQLTM+wvQpNf5JyEcBoxK0RH7EDrh/L4qfsuJ13s=\ngoogle.golang.org/api v0.99.0/go.mod h1:1YOf74vkVndF7pG6hIHuINsM7eWwpVTAfNMNiL91A08=\ngoogle.golang.org/api v0.100.0/go.mod h1:ZE3Z2+ZOr87Rx7dqFsdRQkRBk36kDtp/h+QpHbB7a70=\ngoogle.golang.org/api v0.102.0/go.mod h1:3VFl6/fzoA+qNuS1N1/VfXY4LjoXN/wzeIp7TweWwGo=\ngoogle.golang.org/api v0.103.0/go.mod h1:hGtW6nK1AC+d9si/UBhw8Xli+QMOf6xyNAyJw4qU9w0=\ngoogle.golang.org/api v0.106.0/go.mod h1:2Ts0XTHNVWxypznxWOYUeI4g3WdP9Pk2Qk58+a/O9MY=\ngoogle.golang.org/api v0.107.0/go.mod h1:2Ts0XTHNVWxypznxWOYUeI4g3WdP9Pk2Qk58+a/O9MY=\ngoogle.golang.org/api v0.108.0/go.mod h1:2Ts0XTHNVWxypznxWOYUeI4g3WdP9Pk2Qk58+a/O9MY=\ngoogle.golang.org/api v0.110.0/go.mod h1:7FC4Vvx1Mooxh8C5HWjzZHcavuS2f6pmJpZx60ca7iI=\ngoogle.golang.org/api v0.111.0/go.mod h1:qtFHvU9mhgTJegR31csQ+rwxyUTHOKFqCKWp1J0fdw0=\ngoogle.golang.org/api v0.114.0/go.mod h1:ifYI2ZsFK6/uGddGfAD5BMxlnkBqCmqHSDUVi45N5Yg=\ngoogle.golang.org/api v0.169.0/go.mod h1:gpNOiMA2tZ4mf5R9Iwf4rK/Dcz0fbdIgWYWVoxmsyLg=\ngoogle.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=\ngoogle.golang.org/appengine v1.2.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=\ngoogle.golang.org/appengine v1.3.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=\ngoogle.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=\ngoogle.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=\ngoogle.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0=\ngoogle.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=\ngoogle.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=\ngoogle.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=\ngoogle.golang.org/appengine v1.6.8/go.mod h1:1jJ3jBArFh5pcgW8gCtRJnepW8FzD1V44FJffLiz/Ds=\ngoogle.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=\ngoogle.golang.org/genproto v0.0.0-20180831171423-11092d34479b/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=\ngoogle.golang.org/genproto v0.0.0-20181029155118-b69ba1387ce2/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=\ngoogle.golang.org/genproto v0.0.0-20181202183823-bd91e49a0898/go.mod h1:7Ep/1NZk928CDR8SjdVbjWNpdIf6nzjE3BTgJDr2Atg=\ngoogle.golang.org/genproto v0.0.0-20190306203927-b5d61aea6440/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=\ngoogle.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=\ngoogle.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=\ngoogle.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=\ngoogle.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=\ngoogle.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=\ngoogle.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=\ngoogle.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8=\ngoogle.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=\ngoogle.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=\ngoogle.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=\ngoogle.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=\ngoogle.golang.org/genproto v0.0.0-20200115191322-ca5a22157cba/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=\ngoogle.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=\ngoogle.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA=\ngoogle.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=\ngoogle.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=\ngoogle.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=\ngoogle.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=\ngoogle.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=\ngoogle.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=\ngoogle.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=\ngoogle.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=\ngoogle.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=\ngoogle.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U=\ngoogle.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=\ngoogle.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA=\ngoogle.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=\ngoogle.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=\ngoogle.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=\ngoogle.golang.org/genproto v0.0.0-20200904004341-0bd0a958aa1d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=\ngoogle.golang.org/genproto v0.0.0-20201109203340-2640f1f9cdfb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=\ngoogle.golang.org/genproto v0.0.0-20201201144952-b05cb90ed32e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=\ngoogle.golang.org/genproto v0.0.0-20201210142538-e3217bee35cc/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=\ngoogle.golang.org/genproto v0.0.0-20201214200347-8c77b98c765d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=\ngoogle.golang.org/genproto v0.0.0-20210108203827-ffc7fda8c3d7/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=\ngoogle.golang.org/genproto v0.0.0-20210222152913-aa3ee6e6a81c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=\ngoogle.golang.org/genproto v0.0.0-20210226172003-ab064af71705/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=\ngoogle.golang.org/genproto v0.0.0-20210303154014-9728d6b83eeb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=\ngoogle.golang.org/genproto v0.0.0-20210310155132-4ce2db91004e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=\ngoogle.golang.org/genproto v0.0.0-20210319143718-93e7006c17a6/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=\ngoogle.golang.org/genproto v0.0.0-20210329143202-679c6ae281ee/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A=\ngoogle.golang.org/genproto v0.0.0-20210402141018-6c239bbf2bb1/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A=\ngoogle.golang.org/genproto v0.0.0-20210513213006-bf773b8c8384/go.mod h1:P3QM42oQyzQSnHPnZ/vqoCdDmzH28fzWByN9asMeM8A=\ngoogle.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0=\ngoogle.golang.org/genproto v0.0.0-20210604141403-392c879c8b08/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0=\ngoogle.golang.org/genproto v0.0.0-20210608205507-b6d2f5bf0d7d/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0=\ngoogle.golang.org/genproto v0.0.0-20210624195500-8bfb893ecb84/go.mod h1:SzzZ/N+nwJDaO1kznhnlzqS8ocJICar6hYhVyhi++24=\ngoogle.golang.org/genproto v0.0.0-20210713002101-d411969a0d9a/go.mod h1:AxrInvYm1dci+enl5hChSFPOmmUF1+uAa/UsgNRWd7k=\ngoogle.golang.org/genproto v0.0.0-20210716133855-ce7ef5c701ea/go.mod h1:AxrInvYm1dci+enl5hChSFPOmmUF1+uAa/UsgNRWd7k=\ngoogle.golang.org/genproto v0.0.0-20210728212813-7823e685a01f/go.mod h1:ob2IJxKrgPT52GcgX759i1sleT07tiKowYBGbczaW48=\ngoogle.golang.org/genproto v0.0.0-20210805201207-89edb61ffb67/go.mod h1:ob2IJxKrgPT52GcgX759i1sleT07tiKowYBGbczaW48=\ngoogle.golang.org/genproto v0.0.0-20210813162853-db860fec028c/go.mod h1:cFeNkxwySK631ADgubI+/XFU/xp8FD5KIVV4rj8UC5w=\ngoogle.golang.org/genproto v0.0.0-20210821163610-241b8fcbd6c8/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY=\ngoogle.golang.org/genproto v0.0.0-20210828152312-66f60bf46e71/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY=\ngoogle.golang.org/genproto v0.0.0-20210831024726-fe130286e0e2/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY=\ngoogle.golang.org/genproto v0.0.0-20210903162649-d08c68adba83/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY=\ngoogle.golang.org/genproto v0.0.0-20210909211513-a8c4777a87af/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY=\ngoogle.golang.org/genproto v0.0.0-20210924002016-3dee208752a0/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=\ngoogle.golang.org/genproto v0.0.0-20211118181313-81c1377c94b1/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=\ngoogle.golang.org/genproto v0.0.0-20211206160659-862468c7d6e0/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=\ngoogle.golang.org/genproto v0.0.0-20211208223120-3a66f561d7aa/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=\ngoogle.golang.org/genproto v0.0.0-20211221195035-429b39de9b1c/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=\ngoogle.golang.org/genproto v0.0.0-20220126215142-9970aeb2e350/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=\ngoogle.golang.org/genproto v0.0.0-20220207164111-0872dc986b00/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=\ngoogle.golang.org/genproto v0.0.0-20220218161850-94dd64e39d7c/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI=\ngoogle.golang.org/genproto v0.0.0-20220222213610-43724f9ea8cf/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI=\ngoogle.golang.org/genproto v0.0.0-20220304144024-325a89244dc8/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI=\ngoogle.golang.org/genproto v0.0.0-20220310185008-1973136f34c6/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI=\ngoogle.golang.org/genproto v0.0.0-20220324131243-acbaeb5b85eb/go.mod h1:hAL49I2IFola2sVEjAn7MEwsja0xp51I0tlGAf9hz4E=\ngoogle.golang.org/genproto v0.0.0-20220329172620-7be39ac1afc7/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo=\ngoogle.golang.org/genproto v0.0.0-20220407144326-9054f6ed7bac/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo=\ngoogle.golang.org/genproto v0.0.0-20220413183235-5e96e2839df9/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo=\ngoogle.golang.org/genproto v0.0.0-20220414192740-2d67ff6cf2b4/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo=\ngoogle.golang.org/genproto v0.0.0-20220421151946-72621c1f0bd3/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo=\ngoogle.golang.org/genproto v0.0.0-20220429170224-98d788798c3e/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo=\ngoogle.golang.org/genproto v0.0.0-20220502173005-c8bf987b8c21/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4=\ngoogle.golang.org/genproto v0.0.0-20220505152158-f39f71e6c8f3/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4=\ngoogle.golang.org/genproto v0.0.0-20220518221133-4f43b3371335/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4=\ngoogle.golang.org/genproto v0.0.0-20220523171625-347a074981d8/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4=\ngoogle.golang.org/genproto v0.0.0-20220608133413-ed9918b62aac/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA=\ngoogle.golang.org/genproto v0.0.0-20220616135557-88e70c0c3a90/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA=\ngoogle.golang.org/genproto v0.0.0-20220617124728-180714bec0ad/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA=\ngoogle.golang.org/genproto v0.0.0-20220624142145-8cd45d7dbd1f/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA=\ngoogle.golang.org/genproto v0.0.0-20220628213854-d9e0b6570c03/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA=\ngoogle.golang.org/genproto v0.0.0-20220722212130-b98a9ff5e252/go.mod h1:GkXuJDJ6aQ7lnJcRF+SJVgFdQhypqgl3LB1C9vabdRE=\ngoogle.golang.org/genproto v0.0.0-20220801145646-83ce21fca29f/go.mod h1:iHe1svFLAZg9VWz891+QbRMwUv9O/1Ww+/mngYeThbc=\ngoogle.golang.org/genproto v0.0.0-20220815135757-37a418bb8959/go.mod h1:dbqgFATTzChvnt+ujMdZwITVAJHFtfyN1qUhDqEiIlk=\ngoogle.golang.org/genproto v0.0.0-20220817144833-d7fd3f11b9b1/go.mod h1:dbqgFATTzChvnt+ujMdZwITVAJHFtfyN1qUhDqEiIlk=\ngoogle.golang.org/genproto v0.0.0-20220822174746-9e6da59bd2fc/go.mod h1:dbqgFATTzChvnt+ujMdZwITVAJHFtfyN1qUhDqEiIlk=\ngoogle.golang.org/genproto v0.0.0-20220829144015-23454907ede3/go.mod h1:dbqgFATTzChvnt+ujMdZwITVAJHFtfyN1qUhDqEiIlk=\ngoogle.golang.org/genproto v0.0.0-20220829175752-36a9c930ecbf/go.mod h1:dbqgFATTzChvnt+ujMdZwITVAJHFtfyN1qUhDqEiIlk=\ngoogle.golang.org/genproto v0.0.0-20220913154956-18f8339a66a5/go.mod h1:0Nb8Qy+Sk5eDzHnzlStwW3itdNaWoZA5XeSG+R3JHSo=\ngoogle.golang.org/genproto v0.0.0-20220914142337-ca0e39ece12f/go.mod h1:0Nb8Qy+Sk5eDzHnzlStwW3itdNaWoZA5XeSG+R3JHSo=\ngoogle.golang.org/genproto v0.0.0-20220915135415-7fd63a7952de/go.mod h1:0Nb8Qy+Sk5eDzHnzlStwW3itdNaWoZA5XeSG+R3JHSo=\ngoogle.golang.org/genproto v0.0.0-20220916172020-2692e8806bfa/go.mod h1:0Nb8Qy+Sk5eDzHnzlStwW3itdNaWoZA5XeSG+R3JHSo=\ngoogle.golang.org/genproto v0.0.0-20220919141832-68c03719ef51/go.mod h1:0Nb8Qy+Sk5eDzHnzlStwW3itdNaWoZA5XeSG+R3JHSo=\ngoogle.golang.org/genproto v0.0.0-20220920201722-2b89144ce006/go.mod h1:ht8XFiar2npT/g4vkk7O0WYS1sHOHbdujxbEp7CJWbw=\ngoogle.golang.org/genproto v0.0.0-20220926165614-551eb538f295/go.mod h1:woMGP53BroOrRY3xTxlbr8Y3eB/nzAvvFM83q7kG2OI=\ngoogle.golang.org/genproto v0.0.0-20220926220553-6981cbe3cfce/go.mod h1:woMGP53BroOrRY3xTxlbr8Y3eB/nzAvvFM83q7kG2OI=\ngoogle.golang.org/genproto v0.0.0-20221010155953-15ba04fc1c0e/go.mod h1:3526vdqwhZAwq4wsRUaVG555sVgsNmIjRtO7t/JH29U=\ngoogle.golang.org/genproto v0.0.0-20221014173430-6e2ab493f96b/go.mod h1:1vXfmgAz9N9Jx0QA82PqRVauvCz1SGSz739p0f183jM=\ngoogle.golang.org/genproto v0.0.0-20221014213838-99cd37c6964a/go.mod h1:1vXfmgAz9N9Jx0QA82PqRVauvCz1SGSz739p0f183jM=\ngoogle.golang.org/genproto v0.0.0-20221024153911-1573dae28c9c/go.mod h1:9qHF0xnpdSfF6knlcsnpzUu5y+rpwgbvsyGAZPBMg4s=\ngoogle.golang.org/genproto v0.0.0-20221024183307-1bc688fe9f3e/go.mod h1:9qHF0xnpdSfF6knlcsnpzUu5y+rpwgbvsyGAZPBMg4s=\ngoogle.golang.org/genproto v0.0.0-20221027153422-115e99e71e1c/go.mod h1:CGI5F/G+E5bKwmfYo09AXuVN4dD894kIKUFmVbP2/Fo=\ngoogle.golang.org/genproto v0.0.0-20221109142239-94d6d90a7d66/go.mod h1:rZS5c/ZVYMaOGBfO68GWtjOw/eLaZM1X6iVtgjZ+EWg=\ngoogle.golang.org/genproto v0.0.0-20221114212237-e4508ebdbee1/go.mod h1:rZS5c/ZVYMaOGBfO68GWtjOw/eLaZM1X6iVtgjZ+EWg=\ngoogle.golang.org/genproto v0.0.0-20221117204609-8f9c96812029/go.mod h1:rZS5c/ZVYMaOGBfO68GWtjOw/eLaZM1X6iVtgjZ+EWg=\ngoogle.golang.org/genproto v0.0.0-20221118155620-16455021b5e6/go.mod h1:rZS5c/ZVYMaOGBfO68GWtjOw/eLaZM1X6iVtgjZ+EWg=\ngoogle.golang.org/genproto v0.0.0-20221201164419-0e50fba7f41c/go.mod h1:rZS5c/ZVYMaOGBfO68GWtjOw/eLaZM1X6iVtgjZ+EWg=\ngoogle.golang.org/genproto v0.0.0-20221201204527-e3fa12d562f3/go.mod h1:rZS5c/ZVYMaOGBfO68GWtjOw/eLaZM1X6iVtgjZ+EWg=\ngoogle.golang.org/genproto v0.0.0-20221202195650-67e5cbc046fd/go.mod h1:cTsE614GARnxrLsqKREzmNYJACSWWpAWdNMwnD7c2BE=\ngoogle.golang.org/genproto v0.0.0-20221227171554-f9683d7f8bef/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM=\ngoogle.golang.org/genproto v0.0.0-20230110181048-76db0878b65f/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM=\ngoogle.golang.org/genproto v0.0.0-20230112194545-e10362b5ecf9/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM=\ngoogle.golang.org/genproto v0.0.0-20230113154510-dbe35b8444a5/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM=\ngoogle.golang.org/genproto v0.0.0-20230123190316-2c411cf9d197/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM=\ngoogle.golang.org/genproto v0.0.0-20230124163310-31e0e69b6fc2/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM=\ngoogle.golang.org/genproto v0.0.0-20230125152338-dcaf20b6aeaa/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM=\ngoogle.golang.org/genproto v0.0.0-20230127162408-596548ed4efa/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM=\ngoogle.golang.org/genproto v0.0.0-20230209215440-0dfe4f8abfcc/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM=\ngoogle.golang.org/genproto v0.0.0-20230216225411-c8e22ba71e44/go.mod h1:8B0gmkoRebU8ukX6HP+4wrVQUY1+6PkQ44BSyIlflHA=\ngoogle.golang.org/genproto v0.0.0-20230222225845-10f96fb3dbec/go.mod h1:3Dl5ZL0q0isWJt+FVcfpQyirqemEuLAK/iFvg1UP1Hw=\ngoogle.golang.org/genproto v0.0.0-20230223222841-637eb2293923/go.mod h1:3Dl5ZL0q0isWJt+FVcfpQyirqemEuLAK/iFvg1UP1Hw=\ngoogle.golang.org/genproto v0.0.0-20230303212802-e74f57abe488/go.mod h1:TvhZT5f700eVlTNwND1xoEZQeWTB2RY/65kplwl/bFA=\ngoogle.golang.org/genproto v0.0.0-20230306155012-7f2fa6fef1f4/go.mod h1:NWraEVixdDnqcqQ30jipen1STv2r/n24Wb7twVTGR4s=\ngoogle.golang.org/genproto v0.0.0-20230320184635-7606e756e683/go.mod h1:NWraEVixdDnqcqQ30jipen1STv2r/n24Wb7twVTGR4s=\ngoogle.golang.org/genproto v0.0.0-20230323212658-478b75c54725/go.mod h1:UUQDJDOlWu4KYeJZffbWgBkS1YFobzKbLVfK69pe0Ak=\ngoogle.golang.org/genproto v0.0.0-20240213162025-012b6fc9bca9 h1:9+tzLLstTlPTRyJTh+ah5wIMsBW5c4tQwGTN3thOW9Y=\ngoogle.golang.org/genproto v0.0.0-20240213162025-012b6fc9bca9/go.mod h1:mqHbVIp48Muh7Ywss/AD6I5kNVKZMmAa/QEW58Gxp2s=\ngoogle.golang.org/genproto/googleapis/api v0.0.0-20250603155806-513f23925822 h1:oWVWY3NzT7KJppx2UKhKmzPq4SRe0LdCijVRwvGeikY=\ngoogle.golang.org/genproto/googleapis/api v0.0.0-20250603155806-513f23925822/go.mod h1:h3c4v36UTKzUiuaOKQ6gr3S+0hovBtUrXzTG/i3+XEc=\ngoogle.golang.org/genproto/googleapis/bytestream v0.0.0-20240304161311-37d4d3c04a78/go.mod h1:vh/N7795ftP0AkN1w8XKqN4w1OdUKXW5Eummda+ofv8=\ngoogle.golang.org/genproto/googleapis/rpc v0.0.0-20250603155806-513f23925822 h1:fc6jSaCT0vBduLYZHYrBBNY4dsWuvgyff9noRNDdBeE=\ngoogle.golang.org/genproto/googleapis/rpc v0.0.0-20250603155806-513f23925822/go.mod h1:qQ0YXyHHx3XkvlzUtpXDkS29lDSafHMZBAZDc03LQ3A=\ngoogle.golang.org/grpc v1.14.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw=\ngoogle.golang.org/grpc v1.16.0/go.mod h1:0JHn/cJsOMiMfNA9+DeHDlAU7KAAB5GDlYFpa9MZMio=\ngoogle.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs=\ngoogle.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=\ngoogle.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=\ngoogle.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=\ngoogle.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=\ngoogle.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=\ngoogle.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=\ngoogle.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=\ngoogle.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=\ngoogle.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60=\ngoogle.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk=\ngoogle.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=\ngoogle.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=\ngoogle.golang.org/grpc v1.31.1/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=\ngoogle.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0=\ngoogle.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc=\ngoogle.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA51WJ8=\ngoogle.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=\ngoogle.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=\ngoogle.golang.org/grpc v1.36.1/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=\ngoogle.golang.org/grpc v1.37.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM=\ngoogle.golang.org/grpc v1.37.1/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM=\ngoogle.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM=\ngoogle.golang.org/grpc v1.39.0/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnDzfrE=\ngoogle.golang.org/grpc v1.39.1/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnDzfrE=\ngoogle.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34=\ngoogle.golang.org/grpc v1.40.1/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34=\ngoogle.golang.org/grpc v1.42.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU=\ngoogle.golang.org/grpc v1.44.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU=\ngoogle.golang.org/grpc v1.45.0/go.mod h1:lN7owxKUQEqMfSyQikvvk5tf/6zMPsrK+ONuO11+0rQ=\ngoogle.golang.org/grpc v1.46.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk=\ngoogle.golang.org/grpc v1.46.2/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk=\ngoogle.golang.org/grpc v1.47.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk=\ngoogle.golang.org/grpc v1.48.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk=\ngoogle.golang.org/grpc v1.49.0/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI=\ngoogle.golang.org/grpc v1.50.0/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI=\ngoogle.golang.org/grpc v1.50.1/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI=\ngoogle.golang.org/grpc v1.51.0/go.mod h1:wgNDFcnuBGmxLKI/qn4T+m5BtEBYXJPvibbUPsAIPww=\ngoogle.golang.org/grpc v1.53.0/go.mod h1:OnIrk0ipVdj4N5d9IUoFUx72/VlD7+jUsHwZgwSMQpw=\ngoogle.golang.org/grpc v1.54.0/go.mod h1:PUSEXI6iWghWaB6lXM4knEgpJNu2qUcKfDtNci3EC2g=\ngoogle.golang.org/grpc v1.72.2/go.mod h1:wH5Aktxcg25y1I3w7H69nHfXdOG3UiadoBtjh3izSDM=\ngoogle.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw=\ngoogle.golang.org/grpc/cmd/protoc-gen-go-grpc v1.3.0/go.mod h1:Dk1tviKTvMCz5tvh7t+fh94dhmQVHuCt2OzJB3CTW9Y=\ngoogle.golang.org/grpc/examples v0.0.0-20230224211313-3775f633ce20/go.mod h1:Nr5H8+MlGWr5+xX/STzdoEqJrO+YteqFbMyCsrb6mH0=\ngoogle.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=\ngoogle.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=\ngoogle.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=\ngoogle.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE=\ngoogle.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=\ngoogle.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=\ngoogle.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=\ngoogle.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=\ngoogle.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4=\ngoogle.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=\ngoogle.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=\ngoogle.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=\ngoogle.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=\ngoogle.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=\ngoogle.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=\ngoogle.golang.org/protobuf v1.28.2-0.20230222093303-bc1253ad3743/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=\ngoogle.golang.org/protobuf v1.29.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=\ngoogle.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=\ngoogle.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8=\ngoogle.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=\ngoogle.golang.org/protobuf v1.36.6 h1:z1NpPI8ku2WgiWnf+t9wTPsn6eP1L7ksHUlkfLvd9xY=\ngoogle.golang.org/protobuf v1.36.6/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY=\ngopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=\ngopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=\ngopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=\ngopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=\ngopkg.in/check.v1 v1.0.0-20200902074654-038fdea0a05b/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=\ngopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=\ngopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=\ngopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=\ngopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=\ngopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=\ngopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=\ngopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=\ngopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=\ngopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=\ngopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=\ngopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=\ngopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=\ngopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=\ngopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=\ngopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=\ngopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=\ngotest.tools/v3 v3.0.3/go.mod h1:Z7Lb0S5l+klDB31fvDQX8ss/FlKDxtlFlw3Oa8Ymbl8=\ngotest.tools/v3 v3.5.1/go.mod h1:isy3WKz7GK6uNw/sbHzfKBLvlvXwUyV06n6brMxxopU=\ngrpc.go4.org v0.0.0-20170609214715-11d0a25b4919/go.mod h1:77eQGdRu53HpSqPFJFmuJdjuHRquDANNeA4x7B8WQ9o=\nhonnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=\nhonnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=\nhonnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=\nhonnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=\nhonnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=\nhonnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=\nhonnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=\nhonnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=\nhonnef.co/go/tools v0.1.3/go.mod h1:NgwopIslSNH47DimFoV78dnkksY2EFtX0ajyb3K/las=\nlukechampine.com/uint128 v1.1.1/go.mod h1:c4eWIwlEGaxC/+H1VguhU4PHXNWDCDMUlWdIWl2j1gk=\nlukechampine.com/uint128 v1.2.0/go.mod h1:c4eWIwlEGaxC/+H1VguhU4PHXNWDCDMUlWdIWl2j1gk=\nlukechampine.com/uint128 v1.3.0/go.mod h1:c4eWIwlEGaxC/+H1VguhU4PHXNWDCDMUlWdIWl2j1gk=\nmodernc.org/cc/v3 v3.36.0/go.mod h1:NFUHyPn4ekoC/JHeZFfZurN6ixxawE1BnVonP/oahEI=\nmodernc.org/cc/v3 v3.36.2/go.mod h1:NFUHyPn4ekoC/JHeZFfZurN6ixxawE1BnVonP/oahEI=\nmodernc.org/cc/v3 v3.36.3/go.mod h1:NFUHyPn4ekoC/JHeZFfZurN6ixxawE1BnVonP/oahEI=\nmodernc.org/cc/v3 v3.40.0/go.mod h1:/bTg4dnWkSXowUO6ssQKnOV0yMVxDYNIsIrzqTFDGH0=\nmodernc.org/ccgo/v3 v3.0.0-20220428102840-41399a37e894/go.mod h1:eI31LL8EwEBKPpNpA4bU1/i+sKOwOrQy8D87zWUcRZc=\nmodernc.org/ccgo/v3 v3.0.0-20220430103911-bc99d88307be/go.mod h1:bwdAnOoaIt8Ax9YdWGjxWsdkPcZyRPHqrOvJxaKAKGw=\nmodernc.org/ccgo/v3 v3.16.4/go.mod h1:tGtX0gE9Jn7hdZFeU88slbTh1UtCYKusWOoCJuvkWsQ=\nmodernc.org/ccgo/v3 v3.16.6/go.mod h1:tGtX0gE9Jn7hdZFeU88slbTh1UtCYKusWOoCJuvkWsQ=\nmodernc.org/ccgo/v3 v3.16.8/go.mod h1:zNjwkizS+fIFDrDjIAgBSCLkWbJuHF+ar3QRn+Z9aws=\nmodernc.org/ccgo/v3 v3.16.9/go.mod h1:zNMzC9A9xeNUepy6KuZBbugn3c0Mc9TeiJO4lgvkJDo=\nmodernc.org/ccgo/v3 v3.16.13/go.mod h1:2Quk+5YgpImhPjv2Qsob1DnZ/4som1lJTodubIcoUkY=\nmodernc.org/ccorpus v1.11.6/go.mod h1:2gEUTrWqdpH2pXsmTM1ZkjeSrUWDpjMu2T6m29L/ErQ=\nmodernc.org/httpfs v1.0.6/go.mod h1:7dosgurJGp0sPaRanU53W4xZYKh14wfzX420oZADeHM=\nmodernc.org/libc v0.0.0-20220428101251-2d5f3daf273b/go.mod h1:p7Mg4+koNjc8jkqwcoFBJx7tXkpj00G77X7A72jXPXA=\nmodernc.org/libc v1.16.0/go.mod h1:N4LD6DBE9cf+Dzf9buBlzVJndKr/iJHG97vGLHYnb5A=\nmodernc.org/libc v1.16.1/go.mod h1:JjJE0eu4yeK7tab2n4S1w8tlWd9MxXLRzheaRnAKymU=\nmodernc.org/libc v1.16.17/go.mod h1:hYIV5VZczAmGZAnG15Vdngn5HSF5cSkbvfz2B7GRuVU=\nmodernc.org/libc v1.16.19/go.mod h1:p7Mg4+koNjc8jkqwcoFBJx7tXkpj00G77X7A72jXPXA=\nmodernc.org/libc v1.17.0/go.mod h1:XsgLldpP4aWlPlsjqKRdHPqCxCjISdHfM/yeWC5GyW0=\nmodernc.org/libc v1.17.1/go.mod h1:FZ23b+8LjxZs7XtFMbSzL/EhPxNbfZbErxEHc7cbD9s=\nmodernc.org/libc v1.22.4/go.mod h1:jj+Z7dTNX8fBScMVNRAYZ/jF91K8fdT2hYMThc3YjBY=\nmodernc.org/mathutil v1.2.2/go.mod h1:mZW8CKdRPY1v87qxC/wUdX5O1qDzXMP5TH3wjfpga6E=\nmodernc.org/mathutil v1.4.1/go.mod h1:mZW8CKdRPY1v87qxC/wUdX5O1qDzXMP5TH3wjfpga6E=\nmodernc.org/mathutil v1.5.0/go.mod h1:mZW8CKdRPY1v87qxC/wUdX5O1qDzXMP5TH3wjfpga6E=\nmodernc.org/memory v1.1.1/go.mod h1:/0wo5ibyrQiaoUoH7f9D8dnglAmILJ5/cxZlRECf+Nw=\nmodernc.org/memory v1.2.0/go.mod h1:/0wo5ibyrQiaoUoH7f9D8dnglAmILJ5/cxZlRECf+Nw=\nmodernc.org/memory v1.2.1/go.mod h1:PkUhL0Mugw21sHPeskwZW4D6VscE/GQJOnIpCnW6pSU=\nmodernc.org/memory v1.5.0/go.mod h1:PkUhL0Mugw21sHPeskwZW4D6VscE/GQJOnIpCnW6pSU=\nmodernc.org/opt v0.1.1/go.mod h1:WdSiB5evDcignE70guQKxYUl14mgWtbClRi5wmkkTX0=\nmodernc.org/opt v0.1.3/go.mod h1:WdSiB5evDcignE70guQKxYUl14mgWtbClRi5wmkkTX0=\nmodernc.org/sqlite v1.18.1/go.mod h1:6ho+Gow7oX5V+OiOQ6Tr4xeqbx13UZ6t+Fw9IRUG4d4=\nmodernc.org/sqlite v1.21.2/go.mod h1:cxbLkB5WS32DnQqeH4h4o1B0eMr8W/y8/RGuxQ3JsC0=\nmodernc.org/strutil v1.1.1/go.mod h1:DE+MQQ/hjKBZS2zNInV5hhcipt5rLPWkmpbGeW5mmdw=\nmodernc.org/strutil v1.1.3/go.mod h1:MEHNA7PdEnEwLvspRMtWTNnp2nnyvMfkimT1NKNAGbw=\nmodernc.org/tcl v1.13.1/go.mod h1:XOLfOwzhkljL4itZkK6T72ckMgvj0BDsnKNdZVUOecw=\nmodernc.org/tcl v1.15.1/go.mod h1:aEjeGJX2gz1oWKOLDVZ2tnEWLUrIn8H+GFu+akoDhqs=\nmodernc.org/token v1.0.0/go.mod h1:UGzOrNV1mAFSEB63lOFHIpNRUVMvYTc6yu1SMY/XTDM=\nmodernc.org/token v1.1.0/go.mod h1:UGzOrNV1mAFSEB63lOFHIpNRUVMvYTc6yu1SMY/XTDM=\nmodernc.org/z v1.5.1/go.mod h1:eWFB510QWW5Th9YGZT81s+LwvaAs3Q2yr4sP0rmLkv8=\nmodernc.org/z v1.7.0/go.mod h1:hVdgNMh8ggTuRG1rGU8x+xGRFfiQUIAw0ZqlPy8+HyQ=\npluginrpc.com/pluginrpc v0.5.0 h1:tOQj2D35hOmvHyPu8e7ohW2/QvAnEtKscy2IJYWQ2yo=\npluginrpc.com/pluginrpc v0.5.0/go.mod h1:UNWZ941hcVAoOZUn8YZsMmOZBzbUjQa3XMns8RQLp9o=\nrsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=\nrsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4=\nrsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=\nrsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=\nsourcegraph.com/sourcegraph/go-diff v0.5.0/go.mod h1:kuch7UrkMzY0X+p9CRK03kfuPQ2zzQcaEFbx8wA8rck=\nsourcegraph.com/sqs/pbtypes v0.0.0-20180604144634-d3ebe8f20ae4/go.mod h1:ketZ/q3QxT9HOBeFhu6RdvsftgpsbFHBF5Cas6cDKZ0=\n"
  },
  {
    "path": ".bingo/copyright.mod",
    "content": "module _ // Auto generated by https://github.com/bwplotka/bingo. DO NOT EDIT\n\ngo 1.16\n\nrequire github.com/efficientgo/tools/copyright v0.0.0-20210326193628-425a09c04e05\n"
  },
  {
    "path": ".bingo/copyright.sum",
    "content": "cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=\ngithub.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=\ngithub.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751 h1:JYp7IbQjafoB+tBA3gMyHYHrpOtNuDiK/uB5uXxq5wM=\ngithub.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=\ngithub.com/alecthomas/units v0.0.0-20201120081800-1786d5ef83d4 h1:EBTWhcAX7rNQ80RLwLCpHZBBrJuzallFHnF+yMXo928=\ngithub.com/alecthomas/units v0.0.0-20201120081800-1786d5ef83d4/go.mod h1:OMCwj8VM1Kc9e19TLln2VL61YJF0x1XFtfdL4JdbSyE=\ngithub.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=\ngithub.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=\ngithub.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=\ngithub.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=\ngithub.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=\ngithub.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=\ngithub.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=\ngithub.com/efficientgo/tools v0.0.0-20201228165755-e2b84817bf79 h1:Pi2rMrMQeQ45UAZr8Ple+eSk9WCyglYpkFh0r22E00c=\ngithub.com/efficientgo/tools v0.0.0-20201228165755-e2b84817bf79/go.mod h1:jQUsxCcf91LHRhOnGqrx/yrleJbosynzf29/UlCbzlk=\ngithub.com/efficientgo/tools/copyright v0.0.0-20210326193628-425a09c04e05 h1:JAC2XGXFeRL0Kp6dHAe6bR565uD7M5TOu1CC4u4PBXw=\ngithub.com/efficientgo/tools/copyright v0.0.0-20210326193628-425a09c04e05/go.mod h1:5J0wuuxLMX06WeEgnpf+SvTCptlR9+RHRNO/WEMAwSw=\ngithub.com/efficientgo/tools/core v0.0.0-20210106193344-1108f4e7d16b h1:yi5z8x/FKDHrqtEFiAsxF5b7Sz2+CJrRwBC2kbyhVcA=\ngithub.com/efficientgo/tools/core v0.0.0-20210106193344-1108f4e7d16b/go.mod h1:RJm2+KCRfMUwgEgRte3obd5uLdVY5YbDZjgSMPY0HSA=\ngithub.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=\ngithub.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=\ngithub.com/felixge/fgprof v0.9.1/go.mod h1:7/HK6JFtFaARhIljgP2IV8rJLIoHDoOYoUphsnGvqxE=\ngithub.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=\ngithub.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=\ngithub.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=\ngithub.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=\ngithub.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=\ngithub.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=\ngithub.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs=\ngithub.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w=\ngithub.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=\ngithub.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8=\ngithub.com/golang/protobuf v1.4.3 h1:JjCZWpVbqXDqFVmTfYWEVTMIYrL/NPdPSCHPJ0T/raM=\ngithub.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=\ngithub.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=\ngithub.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=\ngithub.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=\ngithub.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=\ngithub.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=\ngithub.com/google/pprof v0.0.0-20200615235658-03e1cf38a040/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=\ngithub.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=\ngithub.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=\ngithub.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=\ngithub.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=\ngithub.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=\ngithub.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=\ngithub.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=\ngithub.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=\ngithub.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=\ngithub.com/protoconfig/protoconfig/go v0.0.0-20210106192113-733758adefac h1:PWrv6uwNBua14NbS74ukVgXgdRDQPx/2B+Rf6KXXoQk=\ngithub.com/protoconfig/protoconfig/go v0.0.0-20210106192113-733758adefac/go.mod h1:ig8lL2CeTS14ijDIIRoi6pTap0BHc0Xrnke+SKmn9QM=\ngithub.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=\ngithub.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=\ngithub.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=\ngithub.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=\ngo.uber.org/goleak v1.1.10/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A=\ngolang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=\ngolang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=\ngolang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=\ngolang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=\ngolang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=\ngolang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=\ngolang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=\ngolang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=\ngolang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=\ngolang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=\ngolang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=\ngolang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=\ngolang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=\ngolang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=\ngolang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=\ngolang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=\ngolang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=\ngolang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=\ngolang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=\ngolang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=\ngolang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=\ngolang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=\ngolang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=\ngolang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=\ngolang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=\ngolang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=\ngolang.org/x/tools v0.0.0-20191108193012-7d206e10da11/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=\ngolang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=\ngolang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=\ngolang.org/x/tools v0.0.0-20201020161133-226fd2f889ca/go.mod h1:z6u4i615ZeAfBE4XtMziQW1fSVJXACjjbWkB/mvPzlU=\ngolang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=\ngolang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=\ngolang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=\ngolang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=\ngoogle.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=\ngoogle.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=\ngoogle.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=\ngoogle.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=\ngoogle.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=\ngoogle.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=\ngoogle.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=\ngoogle.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=\ngoogle.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=\ngoogle.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=\ngoogle.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=\ngoogle.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE=\ngoogle.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=\ngoogle.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=\ngoogle.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=\ngoogle.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=\ngoogle.golang.org/protobuf v1.25.0 h1:Ejskq+SyPohKW+1uil0JJMtmHCgJPJ/qWTxr8qp+R4c=\ngoogle.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=\ngopkg.in/alecthomas/kingpin.v2 v2.2.6 h1:jMFz6MfLP0/4fUyZle81rXUoxOBFi19VUFKVDOQfozc=\ngopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=\ngopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=\ngopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=\ngopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=\ngopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=\ngopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=\ngopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=\nhonnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=\nhonnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=\n"
  },
  {
    "path": ".bingo/go.mod",
    "content": "module _ // Fake go.mod auto-created by 'bingo' for go -moddir compatibility with non-Go projects. Commit this file, together with other .mod files."
  },
  {
    "path": ".bingo/goimports.mod",
    "content": "module _ // Auto generated by https://github.com/bwplotka/bingo. DO NOT EDIT\n\ngo 1.14\n\nrequire golang.org/x/tools v0.7.0 // cmd/goimports\n"
  },
  {
    "path": ".bingo/goimports.sum",
    "content": "github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=\ngolang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=\ngolang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=\ngolang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=\ngolang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=\ngolang.org/x/mod v0.9.0 h1:KENHtAZL2y3NLMYZeHY9DW8HW8V+kQyJsY/V9JlKvCs=\ngolang.org/x/mod v0.9.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=\ngolang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=\ngolang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=\ngolang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=\ngolang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=\ngolang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc=\ngolang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=\ngolang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.6.0 h1:MVltZSvRTcU2ljQOhs94SXPftV6DCNnZViHeQps87pQ=\ngolang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=\ngolang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=\ngolang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=\ngolang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U=\ngolang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=\ngolang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=\ngolang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=\ngolang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=\ngolang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=\ngolang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=\ngolang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=\ngolang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=\ngolang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=\ngolang.org/x/tools v0.7.0 h1:W4OVu8VVOaIO0yzWMNdepAulS7YfoS3Zabrm8DOXXU4=\ngolang.org/x/tools v0.7.0/go.mod h1:4pg6aUX35JBAogB10C9AtvVL+qowtN4pT3CGSQex14s=\ngolang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=\n"
  },
  {
    "path": ".bingo/golangci-lint.mod",
    "content": "module _ // Auto generated by https://github.com/bwplotka/bingo. DO NOT EDIT\n\ngo 1.24.5\n\nrequire github.com/golangci/golangci-lint/v2 v2.3.0 // cmd/golangci-lint\n"
  },
  {
    "path": ".bingo/golangci-lint.sum",
    "content": "4d63.com/gocheckcompilerdirectives v1.3.0 h1:Ew5y5CtcAAQeTVKUVFrE7EwHMrTO6BggtEj8BZSjZ3A=\n4d63.com/gocheckcompilerdirectives v1.3.0/go.mod h1:ofsJ4zx2QAuIP/NO/NAh1ig6R1Fb18/GI7RVMwz7kAY=\n4d63.com/gochecknoglobals v0.2.2 h1:H1vdnwnMaZdQW/N+NrkT1SZMTBmcwHe9Vq8lJcYYTtU=\n4d63.com/gochecknoglobals v0.2.2/go.mod h1:lLxwTQjL5eIesRbvnzIP3jZtG140FnTdz+AlMa+ogt0=\ncloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=\ncloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=\ncloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU=\ncloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU=\ncloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY=\ncloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc=\ncloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0=\ncloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To=\ncloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4=\ncloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M=\ncloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc=\ncloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk=\ncloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs=\ncloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc=\ncloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY=\ncloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o=\ncloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE=\ncloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc=\ncloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg=\ncloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc=\ncloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ=\ncloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE=\ncloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk=\ncloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I=\ncloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw=\ncloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA=\ncloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU=\ncloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw=\ncloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos=\ncloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk=\ncloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs=\ncloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0=\ncodeberg.org/chavacava/garif v0.2.0 h1:F0tVjhYbuOCnvNcU3YSpO6b3Waw6Bimy4K0mM8y6MfY=\ncodeberg.org/chavacava/garif v0.2.0/go.mod h1:P2BPbVbT4QcvLZrORc2T29szK3xEOlnl0GiPTJmEqBQ=\ndmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=\ngithub.com/4meepo/tagalign v1.4.2 h1:0hcLHPGMjDyM1gHG58cS73aQF8J4TdVR96TZViorO9E=\ngithub.com/4meepo/tagalign v1.4.2/go.mod h1:+p4aMyFM+ra7nb41CnFG6aSDXqRxU/w1VQqScKqDARI=\ngithub.com/Abirdcfly/dupword v0.1.6 h1:qeL6u0442RPRe3mcaLcbaCi2/Y/hOcdtw6DE9odjz9c=\ngithub.com/Abirdcfly/dupword v0.1.6/go.mod h1:s+BFMuL/I4YSiFv29snqyjwzDp4b65W2Kvy+PKzZ6cw=\ngithub.com/AlwxSin/noinlineerr v1.0.5 h1:RUjt63wk1AYWTXtVXbSqemlbVTb23JOSRiNsshj7TbY=\ngithub.com/AlwxSin/noinlineerr v1.0.5/go.mod h1:+QgkkoYrMH7RHvcdxdlI7vYYEdgeoFOVjU9sUhw/rQc=\ngithub.com/Antonboom/errname v1.1.0 h1:A+ucvdpMwlo/myWrkHEUEBWc/xuXdud23S8tmTb/oAE=\ngithub.com/Antonboom/errname v1.1.0/go.mod h1:O1NMrzgUcVBGIfi3xlVuvX8Q/VP/73sseCaAppfjqZw=\ngithub.com/Antonboom/nilnil v1.1.0 h1:jGxJxjgYS3VUUtOTNk8Z1icwT5ESpLH/426fjmQG+ng=\ngithub.com/Antonboom/nilnil v1.1.0/go.mod h1:b7sAlogQjFa1wV8jUW3o4PMzDVFLbTux+xnQdvzdcIE=\ngithub.com/Antonboom/testifylint v1.6.1 h1:6ZSytkFWatT8mwZlmRCHkWz1gPi+q6UBSbieji2Gj/o=\ngithub.com/Antonboom/testifylint v1.6.1/go.mod h1:k+nEkathI2NFjKO6HvwmSrbzUcQ6FAnbZV+ZRrnXPLI=\ngithub.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=\ngithub.com/BurntSushi/toml v1.5.0 h1:W5quZX/G/csjUnuI8SUYlsHs9M38FC7znL0lIO+DvMg=\ngithub.com/BurntSushi/toml v1.5.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho=\ngithub.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=\ngithub.com/Djarvur/go-err113 v0.0.0-20210108212216-aea10b59be24 h1:sHglBQTwgx+rWPdisA5ynNEsoARbiCBOyGcJM4/OzsM=\ngithub.com/Djarvur/go-err113 v0.0.0-20210108212216-aea10b59be24/go.mod h1:4UJr5HIiMZrwgkSPdsjy2uOQExX/WEILpIrO9UPGuXs=\ngithub.com/GaijinEntertainment/go-exhaustruct/v3 v3.3.1 h1:Sz1JIXEcSfhz7fUi7xHnhpIE0thVASYjvosApmHuD2k=\ngithub.com/GaijinEntertainment/go-exhaustruct/v3 v3.3.1/go.mod h1:n/LSCXNuIYqVfBlVXyHfMQkZDdp1/mmxfSjADd3z1Zg=\ngithub.com/Masterminds/semver/v3 v3.3.1 h1:QtNSWtVZ3nBfk8mAOu/B6v7FMJ+NHTIgUPi7rj+4nv4=\ngithub.com/Masterminds/semver/v3 v3.3.1/go.mod h1:4V+yj/TJE1HU9XfppCwVMZq3I84lprf4nC11bSS5beM=\ngithub.com/OpenPeeDeeP/depguard/v2 v2.2.1 h1:vckeWVESWp6Qog7UZSARNqfu/cZqvki8zsuj3piCMx4=\ngithub.com/OpenPeeDeeP/depguard/v2 v2.2.1/go.mod h1:q4DKzC4UcVaAvcfd41CZh0PWpGgzrVxUYBlgKNGquUo=\ngithub.com/alecthomas/chroma/v2 v2.19.0 h1:Im+SLRgT8maArxv81mULDWN8oKxkzboH07CHesxElq4=\ngithub.com/alecthomas/chroma/v2 v2.19.0/go.mod h1:RVX6AvYm4VfYe/zsk7mjHueLDZor3aWCNE14TFlepBk=\ngithub.com/alecthomas/go-check-sumtype v0.3.1 h1:u9aUvbGINJxLVXiFvHUlPEaD7VDULsrxJb4Aq31NLkU=\ngithub.com/alecthomas/go-check-sumtype v0.3.1/go.mod h1:A8TSiN3UPRw3laIgWEUOHHLPa6/r9MtoigdlP5h3K/E=\ngithub.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=\ngithub.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=\ngithub.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=\ngithub.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=\ngithub.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho=\ngithub.com/alexkohler/nakedret/v2 v2.0.6 h1:ME3Qef1/KIKr3kWX3nti3hhgNxw6aqN5pZmQiFSsuzQ=\ngithub.com/alexkohler/nakedret/v2 v2.0.6/go.mod h1:l3RKju/IzOMQHmsEvXwkqMDzHHvurNQfAgE1eVmT40Q=\ngithub.com/alexkohler/prealloc v1.0.0 h1:Hbq0/3fJPQhNkN0dR95AVrr6R7tou91y0uHG5pOcUuw=\ngithub.com/alexkohler/prealloc v1.0.0/go.mod h1:VetnK3dIgFBBKmg0YnD9F9x6Icjd+9cvfHR56wJVlKE=\ngithub.com/alingse/asasalint v0.0.11 h1:SFwnQXJ49Kx/1GghOFz1XGqHYKp21Kq1nHad/0WQRnw=\ngithub.com/alingse/asasalint v0.0.11/go.mod h1:nCaoMhw7a9kSJObvQyVzNTPBDbNpdocqrSP7t/cW5+I=\ngithub.com/alingse/nilnesserr v0.2.0 h1:raLem5KG7EFVb4UIDAXgrv3N2JIaffeKNtcEXkEWd/w=\ngithub.com/alingse/nilnesserr v0.2.0/go.mod h1:1xJPrXonEtX7wyTq8Dytns5P2hNzoWymVUIaKm4HNFg=\ngithub.com/ashanbrown/forbidigo/v2 v2.1.0 h1:NAxZrWqNUQiDz19FKScQ/xvwzmij6BiOw3S0+QUQ+Hs=\ngithub.com/ashanbrown/forbidigo/v2 v2.1.0/go.mod h1:0zZfdNAuZIL7rSComLGthgc/9/n2FqspBOH90xlCHdA=\ngithub.com/ashanbrown/makezero/v2 v2.0.1 h1:r8GtKetWOgoJ4sLyUx97UTwyt2dO7WkGFHizn/Lo8TY=\ngithub.com/ashanbrown/makezero/v2 v2.0.1/go.mod h1:kKU4IMxmYW1M4fiEHMb2vc5SFoPzXvgbMR9gIp5pjSw=\ngithub.com/aymanbagabas/go-osc52/v2 v2.0.1 h1:HwpRHbFMcZLEVr42D4p7XBqjyuxQH5SMiErDT4WkJ2k=\ngithub.com/aymanbagabas/go-osc52/v2 v2.0.1/go.mod h1:uYgXzlJ7ZpABp8OJ+exZzJJhRNQ2ASbcXHWsFqH8hp8=\ngithub.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=\ngithub.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=\ngithub.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=\ngithub.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=\ngithub.com/bkielbasa/cyclop v1.2.3 h1:faIVMIGDIANuGPWH031CZJTi2ymOQBULs9H21HSMa5w=\ngithub.com/bkielbasa/cyclop v1.2.3/go.mod h1:kHTwA9Q0uZqOADdupvcFJQtp/ksSnytRMe8ztxG8Fuo=\ngithub.com/blizzy78/varnamelen v0.8.0 h1:oqSblyuQvFsW1hbBHh1zfwrKe3kcSj0rnXkKzsQ089M=\ngithub.com/blizzy78/varnamelen v0.8.0/go.mod h1:V9TzQZ4fLJ1DSrjVDfl89H7aMnTvKkApdHeyESmyR7k=\ngithub.com/bombsimon/wsl/v4 v4.7.0 h1:1Ilm9JBPRczjyUs6hvOPKvd7VL1Q++PL8M0SXBDf+jQ=\ngithub.com/bombsimon/wsl/v4 v4.7.0/go.mod h1:uV/+6BkffuzSAVYD+yGyld1AChO7/EuLrCF/8xTiapg=\ngithub.com/bombsimon/wsl/v5 v5.1.0 h1:pLmVRBMxSL1D3/rCe65s/iCSFqU37Cz5/8dVEB4UNBw=\ngithub.com/bombsimon/wsl/v5 v5.1.0/go.mod h1:Gp8lD04z27wm3FANIUPZycXp+8huVsn0oxc+n4qfV9I=\ngithub.com/breml/bidichk v0.3.3 h1:WSM67ztRusf1sMoqH6/c4OBCUlRVTKq+CbSeo0R17sE=\ngithub.com/breml/bidichk v0.3.3/go.mod h1:ISbsut8OnjB367j5NseXEGGgO/th206dVa427kR8YTE=\ngithub.com/breml/errchkjson v0.4.1 h1:keFSS8D7A2T0haP9kzZTi7o26r7kE3vymjZNeNDRDwg=\ngithub.com/breml/errchkjson v0.4.1/go.mod h1:a23OvR6Qvcl7DG/Z4o0el6BRAjKnaReoPQFciAl9U3s=\ngithub.com/butuzov/ireturn v0.4.0 h1:+s76bF/PfeKEdbG8b54aCocxXmi0wvYdOVsWxVO7n8E=\ngithub.com/butuzov/ireturn v0.4.0/go.mod h1:ghI0FrCmap8pDWZwfPisFD1vEc56VKH4NpQUxDHta70=\ngithub.com/butuzov/mirror v1.3.0 h1:HdWCXzmwlQHdVhwvsfBb2Au0r3HyINry3bDWLYXiKoc=\ngithub.com/butuzov/mirror v1.3.0/go.mod h1:AEij0Z8YMALaq4yQj9CPPVYOyJQyiexpQEQgihajRfI=\ngithub.com/catenacyber/perfsprint v0.9.1 h1:5LlTp4RwTooQjJCvGEFV6XksZvWE7wCOUvjD2z0vls0=\ngithub.com/catenacyber/perfsprint v0.9.1/go.mod h1:q//VWC2fWbcdSLEY1R3l8n0zQCDPdE4IjZwyY1HMunM=\ngithub.com/ccojocar/zxcvbn-go v1.0.4 h1:FWnCIRMXPj43ukfX000kvBZvV6raSxakYr1nzyNrUcc=\ngithub.com/ccojocar/zxcvbn-go v1.0.4/go.mod h1:3GxGX+rHmueTUMvm5ium7irpyjmm7ikxYFOSJB21Das=\ngithub.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=\ngithub.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=\ngithub.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=\ngithub.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=\ngithub.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=\ngithub.com/charithe/durationcheck v0.0.10 h1:wgw73BiocdBDQPik+zcEoBG/ob8uyBHf2iyoHGPf5w4=\ngithub.com/charithe/durationcheck v0.0.10/go.mod h1:bCWXb7gYRysD1CU3C+u4ceO49LoGOY1C1L6uouGNreQ=\ngithub.com/charmbracelet/colorprofile v0.2.3-0.20250311203215-f60798e515dc h1:4pZI35227imm7yK2bGPcfpFEmuY1gc2YSTShr4iJBfs=\ngithub.com/charmbracelet/colorprofile v0.2.3-0.20250311203215-f60798e515dc/go.mod h1:X4/0JoqgTIPSFcRA/P6INZzIuyqdFY5rm8tb41s9okk=\ngithub.com/charmbracelet/lipgloss v1.1.0 h1:vYXsiLHVkK7fp74RkV7b2kq9+zDLoEU4MZoFqR/noCY=\ngithub.com/charmbracelet/lipgloss v1.1.0/go.mod h1:/6Q8FR2o+kj8rz4Dq0zQc3vYf7X+B0binUUBwA0aL30=\ngithub.com/charmbracelet/x/ansi v0.8.0 h1:9GTq3xq9caJW8ZrBTe0LIe2fvfLR/bYXKTx2llXn7xE=\ngithub.com/charmbracelet/x/ansi v0.8.0/go.mod h1:wdYl/ONOLHLIVmQaxbIYEC/cRKOQyjTkowiI4blgS9Q=\ngithub.com/charmbracelet/x/cellbuf v0.0.13-0.20250311204145-2c3ea96c31dd h1:vy0GVL4jeHEwG5YOXDmi86oYw2yuYUGqz6a8sLwg0X8=\ngithub.com/charmbracelet/x/cellbuf v0.0.13-0.20250311204145-2c3ea96c31dd/go.mod h1:xe0nKWGd3eJgtqZRaN9RjMtK7xUYchjzPr7q6kcvCCs=\ngithub.com/charmbracelet/x/term v0.2.1 h1:AQeHeLZ1OqSXhrAWpYUtZyX1T3zVxfpZuEQMIQaGIAQ=\ngithub.com/charmbracelet/x/term v0.2.1/go.mod h1:oQ4enTYFV7QN4m0i9mzHrViD7TQKvNEEkHUMCmsxdUg=\ngithub.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=\ngithub.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=\ngithub.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=\ngithub.com/ckaznocha/intrange v0.3.1 h1:j1onQyXvHUsPWujDH6WIjhyH26gkRt/txNlV7LspvJs=\ngithub.com/ckaznocha/intrange v0.3.1/go.mod h1:QVepyz1AkUoFQkpEqksSYpNpUo3c5W7nWh/s6SHIJJk=\ngithub.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=\ngithub.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=\ngithub.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g=\ngithub.com/curioswitch/go-reassign v0.3.0 h1:dh3kpQHuADL3cobV/sSGETA8DOv457dwl+fbBAhrQPs=\ngithub.com/curioswitch/go-reassign v0.3.0/go.mod h1:nApPCCTtqLJN/s8HfItCcKV0jIPwluBOvZP+dsJGA88=\ngithub.com/daixiang0/gci v0.13.6 h1:RKuEOSkGpSadkGbvZ6hJ4ddItT3cVZ9Vn9Rybk6xjl8=\ngithub.com/daixiang0/gci v0.13.6/go.mod h1:12etP2OniiIdP4q+kjUGrC/rUagga7ODbqsom5Eo5Yk=\ngithub.com/dave/dst v0.27.3 h1:P1HPoMza3cMEquVf9kKy8yXsFirry4zEnWOdYPOoIzY=\ngithub.com/dave/dst v0.27.3/go.mod h1:jHh6EOibnHgcUW3WjKHisiooEkYwqpHLBSX1iOBhEyc=\ngithub.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=\ngithub.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=\ngithub.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=\ngithub.com/denis-tingaikin/go-header v0.5.0 h1:SRdnP5ZKvcO9KKRP1KJrhFR3RrlGuD+42t4429eC9k8=\ngithub.com/denis-tingaikin/go-header v0.5.0/go.mod h1:mMenU5bWrok6Wl2UsZjy+1okegmwQ3UgWl4V1D8gjlY=\ngithub.com/dlclark/regexp2 v1.11.5 h1:Q/sSnsKerHeCkc/jSTNq1oCm7KiVgUMZRDUoRu0JQZQ=\ngithub.com/dlclark/regexp2 v1.11.5/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8=\ngithub.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=\ngithub.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=\ngithub.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=\ngithub.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=\ngithub.com/ettle/strcase v0.2.0 h1:fGNiVF21fHXpX1niBgk0aROov1LagYsOwV/xqKDKR/Q=\ngithub.com/ettle/strcase v0.2.0/go.mod h1:DajmHElDSaX76ITe3/VHVyMin4LWSJN5Z909Wp+ED1A=\ngithub.com/fatih/color v1.18.0 h1:S8gINlzdQ840/4pfAwic/ZE0djQEH3wM94VfqLTZcOM=\ngithub.com/fatih/color v1.18.0/go.mod h1:4FelSpRwEGDpQ12mAdzqdOukCy4u8WUtOY6lkT/6HfU=\ngithub.com/fatih/structtag v1.2.0 h1:/OdNE99OxoI/PqaW/SuSK9uxxT3f/tcSZgon/ssNSx4=\ngithub.com/fatih/structtag v1.2.0/go.mod h1:mBJUNpUnHmRKrKlQQlmCrh5PuhftFbNv8Ys4/aAZl94=\ngithub.com/firefart/nonamedreturns v1.0.6 h1:vmiBcKV/3EqKY3ZiPxCINmpS431OcE1S47AQUwhrg8E=\ngithub.com/firefart/nonamedreturns v1.0.6/go.mod h1:R8NisJnSIpvPWheCq0mNRXJok6D8h7fagJTF8EMEwCo=\ngithub.com/fsnotify/fsnotify v1.5.4 h1:jRbGcIw6P2Meqdwuo0H1p6JVLbL5DHKAKlYndzMwVZI=\ngithub.com/fsnotify/fsnotify v1.5.4/go.mod h1:OVB6XrOHzAwXMpEM7uPOzcehqUV2UqJxmVXmkdnm1bU=\ngithub.com/fzipp/gocyclo v0.6.0 h1:lsblElZG7d3ALtGMx9fmxeTKZaLLpU8mET09yN4BBLo=\ngithub.com/fzipp/gocyclo v0.6.0/go.mod h1:rXPyn8fnlpa0R2csP/31uerbiVBugk5whMdlyaLkLoA=\ngithub.com/ghostiam/protogetter v0.3.15 h1:1KF5sXel0HE48zh1/vn0Loiw25A9ApyseLzQuif1mLY=\ngithub.com/ghostiam/protogetter v0.3.15/go.mod h1:WZ0nw9pfzsgxuRsPOFQomgDVSWtDLJRfQJEhsGbmQMA=\ngithub.com/go-critic/go-critic v0.13.0 h1:kJzM7wzltQasSUXtYyTl6UaPVySO6GkaR1thFnJ6afY=\ngithub.com/go-critic/go-critic v0.13.0/go.mod h1:M/YeuJ3vOCQDnP2SU+ZhjgRzwzcBW87JqLpMJLrZDLI=\ngithub.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=\ngithub.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=\ngithub.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=\ngithub.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=\ngithub.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=\ngithub.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY=\ngithub.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=\ngithub.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=\ngithub.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A=\ngithub.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=\ngithub.com/go-toolsmith/astcast v1.1.0 h1:+JN9xZV1A+Re+95pgnMgDboWNVnIMMQXwfBwLRPgSC8=\ngithub.com/go-toolsmith/astcast v1.1.0/go.mod h1:qdcuFWeGGS2xX5bLM/c3U9lewg7+Zu4mr+xPwZIB4ZU=\ngithub.com/go-toolsmith/astcopy v1.1.0 h1:YGwBN0WM+ekI/6SS6+52zLDEf8Yvp3n2seZITCUBt5s=\ngithub.com/go-toolsmith/astcopy v1.1.0/go.mod h1:hXM6gan18VA1T/daUEHCFcYiW8Ai1tIwIzHY6srfEAw=\ngithub.com/go-toolsmith/astequal v1.0.3/go.mod h1:9Ai4UglvtR+4up+bAD4+hCj7iTo4m/OXVTSLnCyTAx4=\ngithub.com/go-toolsmith/astequal v1.1.0/go.mod h1:sedf7VIdCL22LD8qIvv7Nn9MuWJruQA/ysswh64lffQ=\ngithub.com/go-toolsmith/astequal v1.2.0 h1:3Fs3CYZ1k9Vo4FzFhwwewC3CHISHDnVUPC4x0bI2+Cw=\ngithub.com/go-toolsmith/astequal v1.2.0/go.mod h1:c8NZ3+kSFtFY/8lPso4v8LuJjdJiUFVnSuU3s0qrrDY=\ngithub.com/go-toolsmith/astfmt v1.1.0 h1:iJVPDPp6/7AaeLJEruMsBUlOYCmvg0MoCfJprsOmcco=\ngithub.com/go-toolsmith/astfmt v1.1.0/go.mod h1:OrcLlRwu0CuiIBp/8b5PYF9ktGVZUjlNMV634mhwuQ4=\ngithub.com/go-toolsmith/astp v1.1.0 h1:dXPuCl6u2llURjdPLLDxJeZInAeZ0/eZwFJmqZMnpQA=\ngithub.com/go-toolsmith/astp v1.1.0/go.mod h1:0T1xFGz9hicKs8Z5MfAqSUitoUYS30pDMsRVIDHs8CA=\ngithub.com/go-toolsmith/strparse v1.0.0/go.mod h1:YI2nUKP9YGZnL/L1/DLFBfixrcjslWct4wyljWhSRy8=\ngithub.com/go-toolsmith/strparse v1.1.0 h1:GAioeZUK9TGxnLS+qfdqNbA4z0SSm5zVNtCQiyP2Bvw=\ngithub.com/go-toolsmith/strparse v1.1.0/go.mod h1:7ksGy58fsaQkGQlY8WVoBFNyEPMGuJin1rfoPS4lBSQ=\ngithub.com/go-toolsmith/typep v1.1.0 h1:fIRYDyF+JywLfqzyhdiHzRop/GQDxxNhLGQ6gFUNHus=\ngithub.com/go-toolsmith/typep v1.1.0/go.mod h1:fVIw+7zjdsMxDA3ITWnH1yOiw1rnTQKCsF/sk2H/qig=\ngithub.com/go-viper/mapstructure/v2 v2.4.0 h1:EBsztssimR/CONLSZZ04E8qAkxNYq4Qp9LvH92wZUgs=\ngithub.com/go-viper/mapstructure/v2 v2.4.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM=\ngithub.com/go-xmlfmt/xmlfmt v1.1.3 h1:t8Ey3Uy7jDSEisW2K3somuMKIpzktkWptA0iFCnRUWY=\ngithub.com/go-xmlfmt/xmlfmt v1.1.3/go.mod h1:aUCEOzzezBEjDBbFBoSiya/gduyIiWYRP6CnSFIV8AM=\ngithub.com/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y=\ngithub.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8=\ngithub.com/gofrs/flock v0.12.1 h1:MTLVXXHf8ekldpJk3AKicLij9MdwOWkZ+a/jHHZby9E=\ngithub.com/gofrs/flock v0.12.1/go.mod h1:9zxTsyu5xtJ9DK+1tFZyibEV7y3uwDxPPfbxeeHCoD0=\ngithub.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=\ngithub.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=\ngithub.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=\ngithub.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=\ngithub.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=\ngithub.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=\ngithub.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=\ngithub.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y=\ngithub.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=\ngithub.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=\ngithub.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=\ngithub.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4=\ngithub.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=\ngithub.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=\ngithub.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=\ngithub.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=\ngithub.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=\ngithub.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk=\ngithub.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=\ngithub.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=\ngithub.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs=\ngithub.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w=\ngithub.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=\ngithub.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8=\ngithub.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=\ngithub.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=\ngithub.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=\ngithub.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=\ngithub.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg=\ngithub.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=\ngithub.com/golangci/dupl v0.0.0-20250308024227-f665c8d69b32 h1:WUvBfQL6EW/40l6OmeSBYQJNSif4O11+bmWEz+C7FYw=\ngithub.com/golangci/dupl v0.0.0-20250308024227-f665c8d69b32/go.mod h1:NUw9Zr2Sy7+HxzdjIULge71wI6yEg1lWQr7Evcu8K0E=\ngithub.com/golangci/go-printf-func-name v0.1.0 h1:dVokQP+NMTO7jwO4bwsRwLWeudOVUPPyAKJuzv8pEJU=\ngithub.com/golangci/go-printf-func-name v0.1.0/go.mod h1:wqhWFH5mUdJQhweRnldEywnR5021wTdZSNgwYceV14s=\ngithub.com/golangci/gofmt v0.0.0-20250106114630-d62b90e6713d h1:viFft9sS/dxoYY0aiOTsLKO2aZQAPT4nlQCsimGcSGE=\ngithub.com/golangci/gofmt v0.0.0-20250106114630-d62b90e6713d/go.mod h1:ivJ9QDg0XucIkmwhzCDsqcnxxlDStoTl89jDMIoNxKY=\ngithub.com/golangci/golangci-lint/v2 v2.3.0 h1:SgxoaAXH8vMuuSnvRDjfF0sxWeIplxJTcs4o6gGEu9Q=\ngithub.com/golangci/golangci-lint/v2 v2.3.0/go.mod h1:9eHPNOsTOqLGSnDsfPRcOaC2m52stgt37uxsjtQwjg0=\ngithub.com/golangci/golines v0.0.0-20250217134842-442fd0091d95 h1:AkK+w9FZBXlU/xUmBtSJN1+tAI4FIvy5WtnUnY8e4p8=\ngithub.com/golangci/golines v0.0.0-20250217134842-442fd0091d95/go.mod h1:k9mmcyWKSTMcPPvQUCfRWWQ9VHJ1U9Dc0R7kaXAgtnQ=\ngithub.com/golangci/misspell v0.7.0 h1:4GOHr/T1lTW0hhR4tgaaV1WS/lJ+ncvYCoFKmqJsj0c=\ngithub.com/golangci/misspell v0.7.0/go.mod h1:WZyyI2P3hxPY2UVHs3cS8YcllAeyfquQcKfdeE9AFVg=\ngithub.com/golangci/plugin-module-register v0.1.2 h1:e5WM6PO6NIAEcij3B053CohVp3HIYbzSuP53UAYgOpg=\ngithub.com/golangci/plugin-module-register v0.1.2/go.mod h1:1+QGTsKBvAIvPvoY/os+G5eoqxWn70HYDm2uvUyGuVw=\ngithub.com/golangci/revgrep v0.8.0 h1:EZBctwbVd0aMeRnNUsFogoyayvKHyxlV3CdUA46FX2s=\ngithub.com/golangci/revgrep v0.8.0/go.mod h1:U4R/s9dlXZsg8uJmaR1GrloUr14D7qDl8gi2iPXJH8k=\ngithub.com/golangci/swaggoswag v0.0.0-20250504205917-77f2aca3143e h1:ai0EfmVYE2bRA5htgAG9r7s3tHsfjIhN98WshBTJ9jM=\ngithub.com/golangci/swaggoswag v0.0.0-20250504205917-77f2aca3143e/go.mod h1:Vrn4B5oR9qRwM+f54koyeH3yzphlecwERs0el27Fr/s=\ngithub.com/golangci/unconvert v0.0.0-20250410112200-a129a6e6413e h1:gD6P7NEo7Eqtt0ssnqSJNNndxe69DOQ24A5h7+i3KpM=\ngithub.com/golangci/unconvert v0.0.0-20250410112200-a129a6e6413e/go.mod h1:h+wZwLjUTJnm/P2rwlbJdRPZXOzaT36/FwnPnY2inzc=\ngithub.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=\ngithub.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=\ngithub.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=\ngithub.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=\ngithub.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=\ngithub.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=\ngithub.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=\ngithub.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=\ngithub.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=\ngithub.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=\ngithub.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=\ngithub.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=\ngithub.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=\ngithub.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=\ngithub.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=\ngithub.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=\ngithub.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=\ngithub.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=\ngithub.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=\ngithub.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=\ngithub.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=\ngithub.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=\ngithub.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=\ngithub.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=\ngithub.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=\ngithub.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=\ngithub.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=\ngithub.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=\ngithub.com/gordonklaus/ineffassign v0.1.0 h1:y2Gd/9I7MdY1oEIt+n+rowjBNDcLQq3RsH5hwJd0f9s=\ngithub.com/gordonklaus/ineffassign v0.1.0/go.mod h1:Qcp2HIAYhR7mNUVSIxZww3Guk4it82ghYcEXIAk+QT0=\ngithub.com/gostaticanalysis/analysisutil v0.7.1 h1:ZMCjoue3DtDWQ5WyU16YbjbQEQ3VuzwxALrpYd+HeKk=\ngithub.com/gostaticanalysis/analysisutil v0.7.1/go.mod h1:v21E3hY37WKMGSnbsw2S/ojApNWb6C1//mXO48CXbVc=\ngithub.com/gostaticanalysis/comment v1.4.1/go.mod h1:ih6ZxzTHLdadaiSnF5WY3dxUoXfXAlTaRzuaNDlSado=\ngithub.com/gostaticanalysis/comment v1.4.2/go.mod h1:KLUTGDv6HOCotCH8h2erHKmpci2ZoR8VPu34YA2uzdM=\ngithub.com/gostaticanalysis/comment v1.5.0 h1:X82FLl+TswsUMpMh17srGRuKaaXprTaytmEpgnKIDu8=\ngithub.com/gostaticanalysis/comment v1.5.0/go.mod h1:V6eb3gpCv9GNVqb6amXzEUX3jXLVK/AdA+IrAMSqvEc=\ngithub.com/gostaticanalysis/forcetypeassert v0.2.0 h1:uSnWrrUEYDr86OCxWa4/Tp2jeYDlogZiZHzGkWFefTk=\ngithub.com/gostaticanalysis/forcetypeassert v0.2.0/go.mod h1:M5iPavzE9pPqWyeiVXSFghQjljW1+l/Uke3PXHS6ILY=\ngithub.com/gostaticanalysis/nilerr v0.1.1 h1:ThE+hJP0fEp4zWLkWHWcRyI2Od0p7DlgYG3Uqrmrcpk=\ngithub.com/gostaticanalysis/nilerr v0.1.1/go.mod h1:wZYb6YI5YAxxq0i1+VJbY0s2YONW0HU0GPE3+5PWN4A=\ngithub.com/gostaticanalysis/testutil v0.3.1-0.20210208050101-bfb5c8eec0e4/go.mod h1:D+FIZ+7OahH3ePw/izIEeH5I06eKs1IKI4Xr64/Am3M=\ngithub.com/hashicorp/go-immutable-radix/v2 v2.1.0 h1:CUW5RYIcysz+D3B+l1mDeXrQ7fUvGGCwJfdASSzbrfo=\ngithub.com/hashicorp/go-immutable-radix/v2 v2.1.0/go.mod h1:hgdqLXA4f6NIjRVisM1TJ9aOJVNRqKZj+xDGF6m7PBw=\ngithub.com/hashicorp/go-version v1.2.1/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=\ngithub.com/hashicorp/go-version v1.7.0 h1:5tqGy27NaOTB8yJKUZELlFAS/LTKJkrmONwQKeRZfjY=\ngithub.com/hashicorp/go-version v1.7.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=\ngithub.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=\ngithub.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=\ngithub.com/hashicorp/golang-lru/v2 v2.0.7 h1:a+bsQ5rvGLjzHuww6tVxozPZFVghXaHOwFs4luLUK2k=\ngithub.com/hashicorp/golang-lru/v2 v2.0.7/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM=\ngithub.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4=\ngithub.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=\ngithub.com/hexops/gotextdiff v1.0.3 h1:gitA9+qJrrTCsiCl7+kh75nPqQt1cx4ZkudSTLoUqJM=\ngithub.com/hexops/gotextdiff v1.0.3/go.mod h1:pSWU5MAI3yDq+fZBTazCSJysOMbxWL1BSow5/V2vxeg=\ngithub.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=\ngithub.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=\ngithub.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=\ngithub.com/jgautheron/goconst v1.8.2 h1:y0XF7X8CikZ93fSNT6WBTb/NElBu9IjaY7CCYQrCMX4=\ngithub.com/jgautheron/goconst v1.8.2/go.mod h1:A0oxgBCHy55NQn6sYpO7UdnA9p+h7cPtoOZUmvNIako=\ngithub.com/jingyugao/rowserrcheck v1.1.1 h1:zibz55j/MJtLsjP1OF4bSdgXxwL1b+Vn7Tjzq7gFzUs=\ngithub.com/jingyugao/rowserrcheck v1.1.1/go.mod h1:4yvlZSDb3IyDTUZJUmpZfm2Hwok+Dtp+nu2qOq+er9c=\ngithub.com/jjti/go-spancheck v0.6.5 h1:lmi7pKxa37oKYIMScialXUK6hP3iY5F1gu+mLBPgYB8=\ngithub.com/jjti/go-spancheck v0.6.5/go.mod h1:aEogkeatBrbYsyW6y5TgDfihCulDYciL1B7rG2vSsrU=\ngithub.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4=\ngithub.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=\ngithub.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=\ngithub.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=\ngithub.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=\ngithub.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=\ngithub.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk=\ngithub.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=\ngithub.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM=\ngithub.com/julz/importas v0.2.0 h1:y+MJN/UdL63QbFJHws9BVC5RpA2iq0kpjrFajTGivjQ=\ngithub.com/julz/importas v0.2.0/go.mod h1:pThlt589EnCYtMnmhmRYY/qn9lCf/frPOK+WMx3xiJY=\ngithub.com/karamaru-alpha/copyloopvar v1.2.1 h1:wmZaZYIjnJ0b5UoKDjUHrikcV0zuPyyxI4SVplLd2CI=\ngithub.com/karamaru-alpha/copyloopvar v1.2.1/go.mod h1:nFmMlFNlClC2BPvNaHMdkirmTJxVCY0lhxBtlfOypMM=\ngithub.com/kisielk/errcheck v1.9.0 h1:9xt1zI9EBfcYBvdU1nVrzMzzUPUtPKs9bVSIM3TAb3M=\ngithub.com/kisielk/errcheck v1.9.0/go.mod h1:kQxWMMVZgIkDq7U8xtG/n2juOjbLgZtedi0D+/VL/i8=\ngithub.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=\ngithub.com/kkHAIKE/contextcheck v1.1.6 h1:7HIyRcnyzxL9Lz06NGhiKvenXq7Zw6Q0UQu/ttjfJCE=\ngithub.com/kkHAIKE/contextcheck v1.1.6/go.mod h1:3dDbMRNBFaq8HFXWC1JyvDSPm43CmE6IuHam8Wr0rkg=\ngithub.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=\ngithub.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=\ngithub.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=\ngithub.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=\ngithub.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=\ngithub.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=\ngithub.com/kulti/thelper v0.6.3 h1:ElhKf+AlItIu+xGnI990no4cE2+XaSu1ULymV2Yulxs=\ngithub.com/kulti/thelper v0.6.3/go.mod h1:DsqKShOvP40epevkFrvIwkCMNYxMeTNjdWL4dqWHZ6I=\ngithub.com/kunwardeep/paralleltest v1.0.14 h1:wAkMoMeGX/kGfhQBPODT/BL8XhK23ol/nuQ3SwFaUw8=\ngithub.com/kunwardeep/paralleltest v1.0.14/go.mod h1:di4moFqtfz3ToSKxhNjhOZL+696QtJGCFe132CbBLGk=\ngithub.com/lasiar/canonicalheader v1.1.2 h1:vZ5uqwvDbyJCnMhmFYimgMZnJMjwljN5VGY0VKbMXb4=\ngithub.com/lasiar/canonicalheader v1.1.2/go.mod h1:qJCeLFS0G/QlLQ506T+Fk/fWMa2VmBUiEI2cuMK4djI=\ngithub.com/ldez/exptostd v0.4.4 h1:58AtQjnLcT/tI5W/1KU7xE/O7zW9RAWB6c/ScQAnfus=\ngithub.com/ldez/exptostd v0.4.4/go.mod h1:QfdzPw6oHjFVdNV7ILoPu5sw3OZ3OG1JS0I5JN3J4Js=\ngithub.com/ldez/gomoddirectives v0.7.0 h1:EOx8Dd56BZYSez11LVgdj025lKwlP0/E5OLSl9HDwsY=\ngithub.com/ldez/gomoddirectives v0.7.0/go.mod h1:wR4v8MN9J8kcwvrkzrx6sC9xe9Cp68gWYCsda5xvyGc=\ngithub.com/ldez/grignotin v0.9.0 h1:MgOEmjZIVNn6p5wPaGp/0OKWyvq42KnzAt/DAb8O4Ow=\ngithub.com/ldez/grignotin v0.9.0/go.mod h1:uaVTr0SoZ1KBii33c47O1M8Jp3OP3YDwhZCmzT9GHEk=\ngithub.com/ldez/tagliatelle v0.7.1 h1:bTgKjjc2sQcsgPiT902+aadvMjCeMHrY7ly2XKFORIk=\ngithub.com/ldez/tagliatelle v0.7.1/go.mod h1:3zjxUpsNB2aEZScWiZTHrAXOl1x25t3cRmzfK1mlo2I=\ngithub.com/ldez/usetesting v0.5.0 h1:3/QtzZObBKLy1F4F8jLuKJiKBjjVFi1IavpoWbmqLwc=\ngithub.com/ldez/usetesting v0.5.0/go.mod h1:Spnb4Qppf8JTuRgblLrEWb7IE6rDmUpGvxY3iRrzvDQ=\ngithub.com/leonklingele/grouper v1.1.2 h1:o1ARBDLOmmasUaNDesWqWCIFH3u7hoFlM84YrjT3mIY=\ngithub.com/leonklingele/grouper v1.1.2/go.mod h1:6D0M/HVkhs2yRKRFZUoGjeDy7EZTfFBE9gl4kjmIGkA=\ngithub.com/lucasb-eyer/go-colorful v1.2.0 h1:1nnpGOrhyZZuNyfu1QjKiUICQ74+3FNCN69Aj6K7nkY=\ngithub.com/lucasb-eyer/go-colorful v1.2.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0=\ngithub.com/macabu/inamedparam v0.2.0 h1:VyPYpOc10nkhI2qeNUdh3Zket4fcZjEWe35poddBCpE=\ngithub.com/macabu/inamedparam v0.2.0/go.mod h1:+Pee9/YfGe5LJ62pYXqB89lJ+0k5bsR8Wgz/C0Zlq3U=\ngithub.com/magiconair/properties v1.8.6 h1:5ibWZ6iY0NctNGWo87LalDlEZ6R41TqbbDamhfG/Qzo=\ngithub.com/magiconair/properties v1.8.6/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60=\ngithub.com/manuelarte/embeddedstructfieldcheck v0.3.0 h1:VhGqK8gANDvFYDxQkjPbv7/gDJtsGU9k6qj/hC2hgso=\ngithub.com/manuelarte/embeddedstructfieldcheck v0.3.0/go.mod h1:LSo/IQpPfx1dXMcX4ibZCYA7Yy6ayZHIaOGM70+1Wy8=\ngithub.com/manuelarte/funcorder v0.5.0 h1:llMuHXXbg7tD0i/LNw8vGnkDTHFpTnWqKPI85Rknc+8=\ngithub.com/manuelarte/funcorder v0.5.0/go.mod h1:Yt3CiUQthSBMBxjShjdXMexmzpP8YGvGLjrxJNkO2hA=\ngithub.com/maratori/testableexamples v1.0.0 h1:dU5alXRrD8WKSjOUnmJZuzdxWOEQ57+7s93SLMxb2vI=\ngithub.com/maratori/testableexamples v1.0.0/go.mod h1:4rhjL1n20TUTT4vdh3RDqSizKLyXp7K2u6HgraZCGzE=\ngithub.com/maratori/testpackage v1.1.1 h1:S58XVV5AD7HADMmD0fNnziNHqKvSdDuEKdPD1rNTU04=\ngithub.com/maratori/testpackage v1.1.1/go.mod h1:s4gRK/ym6AMrqpOa/kEbQTV4Q4jb7WeLZzVhVVVOQMc=\ngithub.com/matoous/godox v1.1.0 h1:W5mqwbyWrwZv6OQ5Z1a/DHGMOvXYCBP3+Ht7KMoJhq4=\ngithub.com/matoous/godox v1.1.0/go.mod h1:jgE/3fUXiTurkdHOLT5WEkThTSuE7yxHv5iWPa80afs=\ngithub.com/matryer/is v1.4.0/go.mod h1:8I/i5uYgLzgsgEloJE1U6xx5HkBQpAZvepWuujKwMRU=\ngithub.com/mattn/go-colorable v0.1.14 h1:9A9LHSqF/7dyVVX6g0U9cwm9pG3kP9gSzcuIPHPsaIE=\ngithub.com/mattn/go-colorable v0.1.14/go.mod h1:6LmQG8QLFO4G5z1gPvYEzlUgJ2wF+stgPZH1UqBm1s8=\ngithub.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=\ngithub.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=\ngithub.com/mattn/go-runewidth v0.0.16 h1:E5ScNMtiwvlvB5paMFdw9p4kSQzbXFikJ5SQO6TULQc=\ngithub.com/mattn/go-runewidth v0.0.16/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=\ngithub.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU=\ngithub.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=\ngithub.com/mgechev/revive v1.11.0 h1:b/gLLpBE427o+Xmd8G58gSA+KtBwxWinH/A565Awh0w=\ngithub.com/mgechev/revive v1.11.0/go.mod h1:tI0oLF/2uj+InHCBLrrqfTKfjtFTBCFFfG05auyzgdw=\ngithub.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y=\ngithub.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=\ngithub.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY=\ngithub.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=\ngithub.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=\ngithub.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=\ngithub.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=\ngithub.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=\ngithub.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=\ngithub.com/moricho/tparallel v0.3.2 h1:odr8aZVFA3NZrNybggMkYO3rgPRcqjeQUlBBFVxKHTI=\ngithub.com/moricho/tparallel v0.3.2/go.mod h1:OQ+K3b4Ln3l2TZveGCywybl68glfLEwFGqvnjok8b+U=\ngithub.com/muesli/termenv v0.16.0 h1:S5AlUN9dENB57rsbnkPyfdGuWIlkmzJjbFf0Tf5FWUc=\ngithub.com/muesli/termenv v0.16.0/go.mod h1:ZRfOIKPFDYQoDFF4Olj7/QJbW60Ol/kL1pU3VfY/Cnk=\ngithub.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=\ngithub.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=\ngithub.com/nakabonne/nestif v0.3.1 h1:wm28nZjhQY5HyYPx+weN3Q65k6ilSBxDb8v5S81B81U=\ngithub.com/nakabonne/nestif v0.3.1/go.mod h1:9EtoZochLn5iUprVDmDjqGKPofoUEBL8U4Ngq6aY7OE=\ngithub.com/nishanths/exhaustive v0.12.0 h1:vIY9sALmw6T/yxiASewa4TQcFsVYZQQRUQJhKRf3Swg=\ngithub.com/nishanths/exhaustive v0.12.0/go.mod h1:mEZ95wPIZW+x8kC4TgC+9YCUgiST7ecevsVDTgc2obs=\ngithub.com/nishanths/predeclared v0.2.2 h1:V2EPdZPliZymNAn79T8RkNApBjMmVKh5XRpLm/w98Vk=\ngithub.com/nishanths/predeclared v0.2.2/go.mod h1:RROzoN6TnGQupbC+lqggsOlcgysk3LMK/HI84Mp280c=\ngithub.com/nunnatsa/ginkgolinter v0.20.0 h1:OmWLkAFO2HUTYcU6mprnKud1Ey5pVdiVNYGO5HVicx8=\ngithub.com/nunnatsa/ginkgolinter v0.20.0/go.mod h1:dCIuFlTPfQerXgGUju3VygfAFPdC5aE1mdacCDKDJcQ=\ngithub.com/otiai10/copy v1.2.0/go.mod h1:rrF5dJ5F0t/EWSYODDu4j9/vEeYHMkc8jt0zJChqQWw=\ngithub.com/otiai10/curr v0.0.0-20150429015615-9b4961190c95/go.mod h1:9qAhocn7zKJG+0mI8eUu6xqkFDYS2kb2saOteoSB3cE=\ngithub.com/otiai10/curr v1.0.0/go.mod h1:LskTG5wDwr8Rs+nNQ+1LlxRjAtTZZjtJW4rMXl6j4vs=\ngithub.com/otiai10/mint v1.3.0/go.mod h1:F5AjcsTsWUqX+Na9fpHb52P8pcRX2CI6A3ctIT91xUo=\ngithub.com/otiai10/mint v1.3.1/go.mod h1:/yxELlJQ0ufhjUwhshSj+wFjZ78CnZ48/1wtmBH1OTc=\ngithub.com/pelletier/go-toml v1.9.5 h1:4yBQzkHv+7BHq2PQUZF3Mx0IYxG7LsP222s7Agd3ve8=\ngithub.com/pelletier/go-toml v1.9.5/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c=\ngithub.com/pelletier/go-toml/v2 v2.2.4 h1:mye9XuhQ6gvn5h28+VilKrrPoQVanw5PMw/TB0t5Ec4=\ngithub.com/pelletier/go-toml/v2 v2.2.4/go.mod h1:2gIqNv+qfxSVS7cM2xJQKtLSTLUE9V8t9Stt+h56mCY=\ngithub.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=\ngithub.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=\ngithub.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=\ngithub.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=\ngithub.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=\ngithub.com/polyfloyd/go-errorlint v1.8.0 h1:DL4RestQqRLr8U4LygLw8g2DX6RN1eBJOpa2mzsrl1Q=\ngithub.com/polyfloyd/go-errorlint v1.8.0/go.mod h1:G2W0Q5roxbLCt0ZQbdoxQxXktTjwNyDbEaj3n7jvl4s=\ngithub.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=\ngithub.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo=\ngithub.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M=\ngithub.com/prometheus/client_golang v1.11.0/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0=\ngithub.com/prometheus/client_golang v1.12.1 h1:ZiaPsmm9uiBeaSMRznKsCDNtPCS0T3JVDGF+06gjBzk=\ngithub.com/prometheus/client_golang v1.12.1/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY=\ngithub.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=\ngithub.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=\ngithub.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=\ngithub.com/prometheus/client_model v0.2.0 h1:uq5h0d+GuxiXLJLNABMgp2qUWDPiLvgCzz2dUR+/W/M=\ngithub.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=\ngithub.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=\ngithub.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo=\ngithub.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc=\ngithub.com/prometheus/common v0.32.1 h1:hWIdL3N2HoUx3B8j3YN9mWor0qhY/NlEKZEaXxuIRh4=\ngithub.com/prometheus/common v0.32.1/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls=\ngithub.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=\ngithub.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=\ngithub.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU=\ngithub.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA=\ngithub.com/prometheus/procfs v0.7.3 h1:4jVXhlkAyzOScmCkXBTOLRLTz8EeU+eyjrwB/EPq0VU=\ngithub.com/prometheus/procfs v0.7.3/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA=\ngithub.com/quasilyte/go-ruleguard v0.4.4 h1:53DncefIeLX3qEpjzlS1lyUmQoUEeOWPFWqaTJq9eAQ=\ngithub.com/quasilyte/go-ruleguard v0.4.4/go.mod h1:Vl05zJ538vcEEwu16V/Hdu7IYZWyKSwIy4c88Ro1kRE=\ngithub.com/quasilyte/go-ruleguard/dsl v0.3.22 h1:wd8zkOhSNr+I+8Qeciml08ivDt1pSXe60+5DqOpCjPE=\ngithub.com/quasilyte/go-ruleguard/dsl v0.3.22/go.mod h1:KeCP03KrjuSO0H1kTuZQCWlQPulDV6YMIXmpQss17rU=\ngithub.com/quasilyte/gogrep v0.5.0 h1:eTKODPXbI8ffJMN+W2aE0+oL0z/nh8/5eNdiO34SOAo=\ngithub.com/quasilyte/gogrep v0.5.0/go.mod h1:Cm9lpz9NZjEoL1tgZ2OgeUKPIxL1meE7eo60Z6Sk+Ng=\ngithub.com/quasilyte/regex/syntax v0.0.0-20210819130434-b3f0c404a727 h1:TCg2WBOl980XxGFEZSS6KlBGIV0diGdySzxATTWoqaU=\ngithub.com/quasilyte/regex/syntax v0.0.0-20210819130434-b3f0c404a727/go.mod h1:rlzQ04UMyJXu/aOvhd8qT+hvDrFpiwqp8MRXDY9szc0=\ngithub.com/quasilyte/stdinfo v0.0.0-20220114132959-f7386bf02567 h1:M8mH9eK4OUR4lu7Gd+PU1fV2/qnDNfzT635KRSObncs=\ngithub.com/quasilyte/stdinfo v0.0.0-20220114132959-f7386bf02567/go.mod h1:DWNGW8A4Y+GyBgPuaQJuWiy0XYftx4Xm/y5Jqk9I6VQ=\ngithub.com/raeperd/recvcheck v0.2.0 h1:GnU+NsbiCqdC2XX5+vMZzP+jAJC5fht7rcVTAhX74UI=\ngithub.com/raeperd/recvcheck v0.2.0/go.mod h1:n04eYkwIR0JbgD73wT8wL4JjPC3wm0nFtzBnWNocnYU=\ngithub.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=\ngithub.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ=\ngithub.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=\ngithub.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=\ngithub.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ=\ngithub.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc=\ngithub.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=\ngithub.com/ryancurrah/gomodguard v1.4.1 h1:eWC8eUMNZ/wM/PWuZBv7JxxqT5fiIKSIyTvjb7Elr+g=\ngithub.com/ryancurrah/gomodguard v1.4.1/go.mod h1:qnMJwV1hX9m+YJseXEBhd2s90+1Xn6x9dLz11ualI1I=\ngithub.com/ryanrolds/sqlclosecheck v0.5.1 h1:dibWW826u0P8jNLsLN+En7+RqWWTYrjCB9fJfSfdyCU=\ngithub.com/ryanrolds/sqlclosecheck v0.5.1/go.mod h1:2g3dUjoS6AL4huFdv6wn55WpLIDjY7ZgUR4J8HOO/XQ=\ngithub.com/sanposhiho/wastedassign/v2 v2.1.0 h1:crurBF7fJKIORrV85u9UUpePDYGWnwvv3+A96WvwXT0=\ngithub.com/sanposhiho/wastedassign/v2 v2.1.0/go.mod h1:+oSmSC+9bQ+VUAxA66nBb0Z7N8CK7mscKTDYC6aIek4=\ngithub.com/santhosh-tekuri/jsonschema/v6 v6.0.2 h1:KRzFb2m7YtdldCEkzs6KqmJw4nqEVZGK7IN2kJkjTuQ=\ngithub.com/santhosh-tekuri/jsonschema/v6 v6.0.2/go.mod h1:JXeL+ps8p7/KNMjDQk3TCwPpBy0wYklyWTfbkIzdIFU=\ngithub.com/sashamelentyev/interfacebloat v1.1.0 h1:xdRdJp0irL086OyW1H/RTZTr1h/tMEOsumirXcOJqAw=\ngithub.com/sashamelentyev/interfacebloat v1.1.0/go.mod h1:+Y9yU5YdTkrNvoX0xHc84dxiN1iBi9+G8zZIhPVoNjQ=\ngithub.com/sashamelentyev/usestdlibvars v1.29.0 h1:8J0MoRrw4/NAXtjQqTHrbW9NN+3iMf7Knkq057v4XOQ=\ngithub.com/sashamelentyev/usestdlibvars v1.29.0/go.mod h1:8PpnjHMk5VdeWlVb4wCdrB8PNbLqZ3wBZTZWkrpZZL8=\ngithub.com/securego/gosec/v2 v2.22.6 h1:mixR+X+Z5fT6QddWY8jyU9gs43CyW0SnADHB6kJm8NY=\ngithub.com/securego/gosec/v2 v2.22.6/go.mod h1:510TFNDMrIPytokyHQAVLvPeDr41Yihn2ak8P+XQfNE=\ngithub.com/shurcooL/go v0.0.0-20180423040247-9e1955d9fb6e/go.mod h1:TDJrrUr11Vxrven61rcy3hJMUqaf/CLWYhHNPmT14Lk=\ngithub.com/shurcooL/go-goon v0.0.0-20170922171312-37c2f522c041/go.mod h1:N5mDOmsrJOB+vfqUK+7DmDyjhSLIIBnXo9lvZJj3MWQ=\ngithub.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=\ngithub.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=\ngithub.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88=\ngithub.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=\ngithub.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=\ngithub.com/sivchari/containedctx v1.0.3 h1:x+etemjbsh2fB5ewm5FeLNi5bUjK0V8n0RB+Wwfd0XE=\ngithub.com/sivchari/containedctx v1.0.3/go.mod h1:c1RDvCbnJLtH4lLcYD/GqwiBSSf4F5Qk0xld2rBqzJ4=\ngithub.com/sonatard/noctx v0.3.5 h1:KJmJt2jEXFu2JLlGfjpGNOjyjc4qvfzl4918XJ4Odpc=\ngithub.com/sonatard/noctx v0.3.5/go.mod h1:64XdbzFb18XL4LporKXp8poqZtPKbCrqQ402CV+kJas=\ngithub.com/sourcegraph/go-diff v0.7.0 h1:9uLlrd5T46OXs5qpp8L/MTltk0zikUGi0sNNyCpA8G0=\ngithub.com/sourcegraph/go-diff v0.7.0/go.mod h1:iBszgVvyxdc8SFZ7gm69go2KDdt3ag071iBaWPF6cjs=\ngithub.com/spf13/afero v1.14.0 h1:9tH6MapGnn/j0eb0yIXiLjERO8RB6xIVZRDCX7PtqWA=\ngithub.com/spf13/afero v1.14.0/go.mod h1:acJQ8t0ohCGuMN3O+Pv0V0hgMxNYDlvdk+VTfyZmbYo=\ngithub.com/spf13/cast v1.5.0 h1:rj3WzYc11XZaIZMPKmwP96zkFEnnAmV8s6XbB2aY32w=\ngithub.com/spf13/cast v1.5.0/go.mod h1:SpXXQ5YoyJw6s3/6cMTQuxvgRl3PCJiyaX9p6b155UU=\ngithub.com/spf13/cobra v1.9.1 h1:CXSaggrXdbHK9CF+8ywj8Amf7PBRmPCOJugH954Nnlo=\ngithub.com/spf13/cobra v1.9.1/go.mod h1:nDyEzZ8ogv936Cinf6g1RU9MRY64Ir93oCnqb9wxYW0=\ngithub.com/spf13/jwalterweatherman v1.1.0 h1:ue6voC5bR5F8YxI5S67j9i582FU4Qvo2bmqnqMYADFk=\ngithub.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo=\ngithub.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=\ngithub.com/spf13/pflag v1.0.6/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=\ngithub.com/spf13/pflag v1.0.7 h1:vN6T9TfwStFPFM5XzjsvmzZkLuaLX+HS+0SeFLRgU6M=\ngithub.com/spf13/pflag v1.0.7/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=\ngithub.com/spf13/viper v1.12.0 h1:CZ7eSOd3kZoaYDLbXnmzgQI5RlciuXBMA+18HwHRfZQ=\ngithub.com/spf13/viper v1.12.0/go.mod h1:b6COn30jlNxbm/V2IqWiNWkJ+vZNiMNksliPCiuKtSI=\ngithub.com/ssgreg/nlreturn/v2 v2.2.1 h1:X4XDI7jstt3ySqGU86YGAURbxw3oTDPK9sPEi6YEwQ0=\ngithub.com/ssgreg/nlreturn/v2 v2.2.1/go.mod h1:E/iiPB78hV7Szg2YfRgyIrk1AD6JVMTRkkxBiELzh2I=\ngithub.com/stbenjam/no-sprintf-host-port v0.2.0 h1:i8pxvGrt1+4G0czLr/WnmyH7zbZ8Bg8etvARQ1rpyl4=\ngithub.com/stbenjam/no-sprintf-host-port v0.2.0/go.mod h1:eL0bQ9PasS0hsyTyfTjjG+E80QIyPnBVQbYZyv20Jfk=\ngithub.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=\ngithub.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=\ngithub.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY=\ngithub.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA=\ngithub.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=\ngithub.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=\ngithub.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=\ngithub.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=\ngithub.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=\ngithub.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=\ngithub.com/subosito/gotenv v1.4.1 h1:jyEFiXpy21Wm81FBN71l9VoMMV8H8jG+qIK3GCpY6Qs=\ngithub.com/subosito/gotenv v1.4.1/go.mod h1:ayKnFf/c6rvx/2iiLrJUk1e6plDbT3edrFNGqEflhK0=\ngithub.com/tdakkota/asciicheck v0.4.1 h1:bm0tbcmi0jezRA2b5kg4ozmMuGAFotKI3RZfrhfovg8=\ngithub.com/tdakkota/asciicheck v0.4.1/go.mod h1:0k7M3rCfRXb0Z6bwgvkEIMleKH3kXNz9UqJ9Xuqopr8=\ngithub.com/tenntenn/modver v1.0.1/go.mod h1:bePIyQPb7UeioSRkw3Q0XeMhYZSMx9B8ePqg6SAMGH0=\ngithub.com/tenntenn/text/transform v0.0.0-20200319021203-7eef512accb3/go.mod h1:ON8b8w4BN/kE1EOhwT0o+d62W65a6aPw1nouo9LMgyY=\ngithub.com/tetafro/godot v1.5.1 h1:PZnjCol4+FqaEzvZg5+O8IY2P3hfY9JzRBNPv1pEDS4=\ngithub.com/tetafro/godot v1.5.1/go.mod h1:cCdPtEndkmqqrhiCfkmxDodMQJ/f3L1BCNskCUZdTwk=\ngithub.com/timakin/bodyclose v0.0.0-20241222091800-1db5c5ca4d67 h1:9LPGD+jzxMlnk5r6+hJnar67cgpDIz/iyD+rfl5r2Vk=\ngithub.com/timakin/bodyclose v0.0.0-20241222091800-1db5c5ca4d67/go.mod h1:mkjARE7Yr8qU23YcGMSALbIxTQ9r9QBVahQOBRfU460=\ngithub.com/timonwong/loggercheck v0.11.0 h1:jdaMpYBl+Uq9mWPXv1r8jc5fC3gyXx4/WGwTnnNKn4M=\ngithub.com/timonwong/loggercheck v0.11.0/go.mod h1:HEAWU8djynujaAVX7QI65Myb8qgfcZ1uKbdpg3ZzKl8=\ngithub.com/tomarrell/wrapcheck/v2 v2.11.0 h1:BJSt36snX9+4WTIXeJ7nvHBQBcm1h2SjQMSlmQ6aFSU=\ngithub.com/tomarrell/wrapcheck/v2 v2.11.0/go.mod h1:wFL9pDWDAbXhhPZZt+nG8Fu+h29TtnZ2MW6Lx4BRXIU=\ngithub.com/tommy-muehle/go-mnd/v2 v2.5.1 h1:NowYhSdyE/1zwK9QCLeRb6USWdoif80Ie+v+yU8u1Zw=\ngithub.com/tommy-muehle/go-mnd/v2 v2.5.1/go.mod h1:WsUAkMJMYww6l/ufffCD3m+P7LEvr8TnZn9lwVDlgzw=\ngithub.com/ultraware/funlen v0.2.0 h1:gCHmCn+d2/1SemTdYMiKLAHFYxTYz7z9VIDRaTGyLkI=\ngithub.com/ultraware/funlen v0.2.0/go.mod h1:ZE0q4TsJ8T1SQcjmkhN/w+MceuatI6pBFSxxyteHIJA=\ngithub.com/ultraware/whitespace v0.2.0 h1:TYowo2m9Nfj1baEQBjuHzvMRbp19i+RCcRYrSWoFa+g=\ngithub.com/ultraware/whitespace v0.2.0/go.mod h1:XcP1RLD81eV4BW8UhQlpaR+SDc2givTvyI8a586WjW8=\ngithub.com/uudashr/gocognit v1.2.0 h1:3BU9aMr1xbhPlvJLSydKwdLN3tEUUrzPSSM8S4hDYRA=\ngithub.com/uudashr/gocognit v1.2.0/go.mod h1:k/DdKPI6XBZO1q7HgoV2juESI2/Ofj9AcHPZhBBdrTU=\ngithub.com/uudashr/iface v1.4.1 h1:J16Xl1wyNX9ofhpHmQ9h9gk5rnv2A6lX/2+APLTo0zU=\ngithub.com/uudashr/iface v1.4.1/go.mod h1:pbeBPlbuU2qkNDn0mmfrxP2X+wjPMIQAy+r1MBXSXtg=\ngithub.com/xen0n/gosmopolitan v1.3.0 h1:zAZI1zefvo7gcpbCOrPSHJZJYA9ZgLfJqtKzZ5pHqQM=\ngithub.com/xen0n/gosmopolitan v1.3.0/go.mod h1:rckfr5T6o4lBtM1ga7mLGKZmLxswUoH1zxHgNXOsEt4=\ngithub.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e h1:JVG44RsyaB9T2KIHavMF/ppJZNG9ZpyihvCd0w101no=\ngithub.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e/go.mod h1:RbqR21r5mrJuqunuUZ/Dhy/avygyECGrLceyNeo4LiM=\ngithub.com/yagipy/maintidx v1.0.0 h1:h5NvIsCz+nRDapQ0exNv4aJ0yXSI0420omVANTv3GJM=\ngithub.com/yagipy/maintidx v1.0.0/go.mod h1:0qNf/I/CCZXSMhsRsrEPDZ+DkekpKLXAJfsTACwgXLk=\ngithub.com/yeya24/promlinter v0.3.0 h1:JVDbMp08lVCP7Y6NP3qHroGAO6z2yGKQtS5JsjqtoFs=\ngithub.com/yeya24/promlinter v0.3.0/go.mod h1:cDfJQQYv9uYciW60QT0eeHlFodotkYZlL+YcPQN+mW4=\ngithub.com/ykadowak/zerologlint v0.1.5 h1:Gy/fMz1dFQN9JZTPjv1hxEk+sRWm05row04Yoolgdiw=\ngithub.com/ykadowak/zerologlint v0.1.5/go.mod h1:KaUskqF3e/v59oPmdq1U1DnKcuHokl2/K1U4pmIELKg=\ngithub.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=\ngithub.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=\ngithub.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=\ngithub.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=\ngithub.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=\ngithub.com/yuin/goldmark v1.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=\ngithub.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=\ngitlab.com/bosi/decorder v0.4.2 h1:qbQaV3zgwnBZ4zPMhGLW4KZe7A7NwxEhJx39R3shffo=\ngitlab.com/bosi/decorder v0.4.2/go.mod h1:muuhHoaJkA9QLcYHq4Mj8FJUwDZ+EirSHRiaTcTf6T8=\ngo-simpler.org/musttag v0.13.1 h1:lw2sJyu7S1X8lc8zWUAdH42y+afdcCnHhWpnkWvd6vU=\ngo-simpler.org/musttag v0.13.1/go.mod h1:8r450ehpMLQgvpb6sg+hV5Ur47eH6olp/3yEanfG97k=\ngo-simpler.org/sloglint v0.11.1 h1:xRbPepLT/MHPTCA6TS/wNfZrDzkGvCCqUv4Bdwc3H7s=\ngo-simpler.org/sloglint v0.11.1/go.mod h1:2PowwiCOK8mjiF+0KGifVOT8ZsCNiFzvfyJeJOIt8MQ=\ngo.augendre.info/arangolint v0.2.0 h1:2NP/XudpPmfBhQKX4rMk+zDYIj//qbt4hfZmSSTcpj8=\ngo.augendre.info/arangolint v0.2.0/go.mod h1:Vx4KSJwu48tkE+8uxuf0cbBnAPgnt8O1KWiT7bljq7w=\ngo.augendre.info/fatcontext v0.8.0 h1:2dfk6CQbDGeu1YocF59Za5Pia7ULeAM6friJ3LP7lmk=\ngo.augendre.info/fatcontext v0.8.0/go.mod h1:oVJfMgwngMsHO+KB2MdgzcO+RvtNdiCEOlWvSFtax/s=\ngo.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=\ngo.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8=\ngo.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=\ngo.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=\ngo.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=\ngo.uber.org/atomic v1.7.0 h1:ADUqmZGgLDDfbSL9ZmPxKTybcoEYHgpYfELNoN+7hsw=\ngo.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=\ngo.uber.org/automaxprocs v1.6.0 h1:O3y2/QNTOdbF+e/dpXNNW7Rx2hZ4sTIPyybbxyNqTUs=\ngo.uber.org/automaxprocs v1.6.0/go.mod h1:ifeIMSnPZuznNm6jmdzmU3/bfk01Fe2fotchwEFJ8r8=\ngo.uber.org/multierr v1.6.0 h1:y6IPFStTAIT5Ytl7/XYmHvzXQ7S3g/IeZW9hyZ5thw4=\ngo.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU=\ngo.uber.org/zap v1.24.0 h1:FiJd5l1UOLj0wCgbSE0rwwXHzEdAZS6hiiSnxJN/D60=\ngo.uber.org/zap v1.24.0/go.mod h1:2kMP+WWQ8aoFoedH3T2sq6iJ2yDWpHbP0f6MQbS9Gkg=\ngolang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=\ngolang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=\ngolang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=\ngolang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=\ngolang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=\ngolang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=\ngolang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=\ngolang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc=\ngolang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4=\ngolang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=\ngolang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=\ngolang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=\ngolang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek=\ngolang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY=\ngolang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=\ngolang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=\ngolang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=\ngolang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM=\ngolang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU=\ngolang.org/x/exp v0.0.0-20240909161429-701f63a606c0 h1:e66Fs6Z+fZTbFBAxKfP3PALWBtpfqks2bwGcexMxgtk=\ngolang.org/x/exp/typeparams v0.0.0-20220428152302-39d4317da171/go.mod h1:AbB0pIl9nAr9wVwH+Z2ZpaocVmF5I4GyWCDIsVjR0bk=\ngolang.org/x/exp/typeparams v0.0.0-20230203172020-98cc5a0785f9/go.mod h1:AbB0pIl9nAr9wVwH+Z2ZpaocVmF5I4GyWCDIsVjR0bk=\ngolang.org/x/exp/typeparams v0.0.0-20250620022241-b7579e27df2b h1:KdrhdYPDUvJTvrDK9gdjfFd6JTk8vA1WJoldYSi0kHo=\ngolang.org/x/exp/typeparams v0.0.0-20250620022241-b7579e27df2b/go.mod h1:LKZHyeOpPuZcMgxeHjJp4p5yvxrCX1xDvH10zYHhjjQ=\ngolang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=\ngolang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=\ngolang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=\ngolang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=\ngolang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=\ngolang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=\ngolang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=\ngolang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=\ngolang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=\ngolang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs=\ngolang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=\ngolang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=\ngolang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE=\ngolang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o=\ngolang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=\ngolang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY=\ngolang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=\ngolang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=\ngolang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=\ngolang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=\ngolang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=\ngolang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=\ngolang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3/go.mod h1:3p9vT2HGsQu2K1YbXdKPJLVgG5VJdoTa1poYQBtP1AY=\ngolang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=\ngolang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=\ngolang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=\ngolang.org/x/mod v0.13.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=\ngolang.org/x/mod v0.26.0 h1:EGMPT//Ezu+ylkCijjPc+f4Aih7sZvaAr+O3EHBxvZg=\ngolang.org/x/mod v0.26.0/go.mod h1:/j6NAhSk8iQ723BGAUyoAcn7SlD7s15Dp9Nd/SfeaFQ=\ngolang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=\ngolang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=\ngolang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=\ngolang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=\ngolang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=\ngolang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=\ngolang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=\ngolang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=\ngolang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=\ngolang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=\ngolang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=\ngolang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=\ngolang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=\ngolang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=\ngolang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=\ngolang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=\ngolang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=\ngolang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=\ngolang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=\ngolang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=\ngolang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=\ngolang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=\ngolang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=\ngolang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=\ngolang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=\ngolang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=\ngolang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=\ngolang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=\ngolang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=\ngolang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=\ngolang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=\ngolang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=\ngolang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=\ngolang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=\ngolang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=\ngolang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=\ngolang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk=\ngolang.org/x/net v0.16.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE=\ngolang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=\ngolang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=\ngolang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=\ngolang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=\ngolang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=\ngolang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=\ngolang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y=\ngolang.org/x/sync v0.4.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y=\ngolang.org/x/sync v0.16.0 h1:ycBJEhp9p4vXvUZNszeOq0kGTPghopOL8q0fq3vstxw=\ngolang.org/x/sync v0.16.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=\ngolang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=\ngolang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=\ngolang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=\ngolang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=\ngolang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20211105183446-c75c47738b0c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.34.0 h1:H5Y5sJ2L2JRdyv7ROF1he/lPdvFsd0mJHFw2ThKHxLA=\ngolang.org/x/sys v0.34.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=\ngolang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=\ngolang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=\ngolang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=\ngolang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=\ngolang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU=\ngolang.org/x/term v0.13.0/go.mod h1:LTmsnFJwVN6bCy1rVCoS+qHT1HhALEFxKncY3WNNh4U=\ngolang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=\ngolang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=\ngolang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=\ngolang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=\ngolang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=\ngolang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=\ngolang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=\ngolang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=\ngolang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=\ngolang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=\ngolang.org/x/text v0.27.0 h1:4fGWRpyh641NLlecmyl4LOe6yDdfaYNrGb2zdfo4JV4=\ngolang.org/x/text v0.27.0/go.mod h1:1D28KMCvyooCX9hBiosv5Tz/+YLxj0j7XhWjpSUF7CU=\ngolang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=\ngolang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=\ngolang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=\ngolang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=\ngolang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=\ngolang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=\ngolang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=\ngolang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=\ngolang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=\ngolang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=\ngolang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=\ngolang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=\ngolang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=\ngolang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=\ngolang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=\ngolang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=\ngolang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=\ngolang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=\ngolang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=\ngolang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=\ngolang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=\ngolang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=\ngolang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=\ngolang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=\ngolang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=\ngolang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=\ngolang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=\ngolang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=\ngolang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=\ngolang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=\ngolang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=\ngolang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=\ngolang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=\ngolang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw=\ngolang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw=\ngolang.org/x/tools v0.0.0-20200324003944-a576cf524670/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8=\ngolang.org/x/tools v0.0.0-20200329025819-fd4102a86c65/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8=\ngolang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8=\ngolang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=\ngolang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=\ngolang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=\ngolang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=\ngolang.org/x/tools v0.0.0-20200724022722-7017fd6b1305/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=\ngolang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=\ngolang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=\ngolang.org/x/tools v0.0.0-20200820010801-b793a1359eac/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=\ngolang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=\ngolang.org/x/tools v0.0.0-20201023174141-c8cfbd0f21e6/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=\ngolang.org/x/tools v0.1.1-0.20210205202024-ef80cdb6ec6d/go.mod h1:9bzcO0MWcOuT0tm1iBGzDVPshzfwoVvREIui8C+MHqU=\ngolang.org/x/tools v0.1.1-0.20210302220138-2ac05c832e1a/go.mod h1:9bzcO0MWcOuT0tm1iBGzDVPshzfwoVvREIui8C+MHqU=\ngolang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=\ngolang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=\ngolang.org/x/tools v0.1.10/go.mod h1:Uh6Zz+xoGYZom868N8YTex3t7RhtHDBrE8Gzo9bV56E=\ngolang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=\ngolang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=\ngolang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58=\ngolang.org/x/tools v0.14.0/go.mod h1:uYBEerGOWcJyEORxN+Ek8+TT266gXkNlHdJBwexUsBg=\ngolang.org/x/tools v0.35.0 h1:mBffYraMEf7aa0sB+NuKnuCy8qI/9Bughn8dC2Gu5r0=\ngolang.org/x/tools v0.35.0/go.mod h1:NKdj5HkL/73byiZSJjqJgKn3ep7KjFkBOkR/Hps3VPw=\ngolang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=\ngolang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=\ngolang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=\ngolang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=\ngoogle.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE=\ngoogle.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M=\ngoogle.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=\ngoogle.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=\ngoogle.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=\ngoogle.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=\ngoogle.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=\ngoogle.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=\ngoogle.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=\ngoogle.golang.org/api v0.19.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=\ngoogle.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=\ngoogle.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=\ngoogle.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE=\ngoogle.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE=\ngoogle.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM=\ngoogle.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc=\ngoogle.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=\ngoogle.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=\ngoogle.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=\ngoogle.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0=\ngoogle.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=\ngoogle.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=\ngoogle.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=\ngoogle.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=\ngoogle.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=\ngoogle.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=\ngoogle.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=\ngoogle.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=\ngoogle.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=\ngoogle.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8=\ngoogle.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=\ngoogle.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=\ngoogle.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=\ngoogle.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=\ngoogle.golang.org/genproto v0.0.0-20200115191322-ca5a22157cba/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=\ngoogle.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=\ngoogle.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA=\ngoogle.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=\ngoogle.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=\ngoogle.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=\ngoogle.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=\ngoogle.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=\ngoogle.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=\ngoogle.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=\ngoogle.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=\ngoogle.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U=\ngoogle.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=\ngoogle.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA=\ngoogle.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=\ngoogle.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=\ngoogle.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=\ngoogle.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=\ngoogle.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=\ngoogle.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=\ngoogle.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=\ngoogle.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=\ngoogle.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=\ngoogle.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=\ngoogle.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=\ngoogle.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60=\ngoogle.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk=\ngoogle.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=\ngoogle.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=\ngoogle.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=\ngoogle.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=\ngoogle.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=\ngoogle.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE=\ngoogle.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=\ngoogle.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=\ngoogle.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=\ngoogle.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=\ngoogle.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4=\ngoogle.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=\ngoogle.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=\ngoogle.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=\ngoogle.golang.org/protobuf v1.36.6 h1:z1NpPI8ku2WgiWnf+t9wTPsn6eP1L7ksHUlkfLvd9xY=\ngoogle.golang.org/protobuf v1.36.6/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY=\ngopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=\ngopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=\ngopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=\ngopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=\ngopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=\ngopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA=\ngopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=\ngopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=\ngopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=\ngopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=\ngopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=\ngopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=\ngopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=\ngopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=\ngopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=\ngopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=\ngopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=\nhonnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=\nhonnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=\nhonnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=\nhonnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=\nhonnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=\nhonnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=\nhonnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=\nhonnef.co/go/tools v0.6.1 h1:R094WgE8K4JirYjBaOpz/AvTyUu/3wbmAoskKN/pxTI=\nhonnef.co/go/tools v0.6.1/go.mod h1:3puzxxljPCe8RGJX7BIy1plGbxEOZni5mR2aXe3/uk4=\nmvdan.cc/gofumpt v0.8.0 h1:nZUCeC2ViFaerTcYKstMmfysj6uhQrA2vJe+2vwGU6k=\nmvdan.cc/gofumpt v0.8.0/go.mod h1:vEYnSzyGPmjvFkqJWtXkh79UwPWP9/HMxQdGEXZHjpg=\nmvdan.cc/unparam v0.0.0-20250301125049-0df0534333a4 h1:WjUu4yQoT5BHT1w8Zu56SP8367OuBV5jvo+4Ulppyf8=\nmvdan.cc/unparam v0.0.0-20250301125049-0df0534333a4/go.mod h1:rthT7OuvRbaGcd5ginj6dA2oLE7YNlta9qhBNNdCaLE=\nrsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=\nrsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=\nrsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=\n"
  },
  {
    "path": ".bingo/mdox.mod",
    "content": "module _ // Auto generated by https://github.com/bwplotka/bingo. DO NOT EDIT\n\ngo 1.20\n\nrequire github.com/bwplotka/mdox v0.9.0\n"
  },
  {
    "path": ".bingo/mdox.sum",
    "content": "cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=\ncloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=\ncloud.google.com/go v0.37.4/go.mod h1:NHPJ89PdicEuT9hdPXMROBD91xc5uRDxsMtSB16k7hw=\ncloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU=\ncloud.google.com/go v0.39.0/go.mod h1:rVLT6fkc8chs9sfPtFc1SBH6em7n+ZoXaG+87tDISts=\ncloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU=\ncloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY=\ncloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc=\ncloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0=\ncloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To=\ncloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4=\ncloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M=\ncloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc=\ncloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk=\ncloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs=\ncloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc=\ncloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY=\ncloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o=\ncloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE=\ncloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc=\ncloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg=\ncloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc=\ncloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ=\ncloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE=\ncloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk=\ncloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I=\ncloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw=\ncloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA=\ncloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU=\ncloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw=\ncloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos=\ncloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk=\ncloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs=\ncloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0=\ncontrib.go.opencensus.io/exporter/aws v0.0.0-20181029163544-2befc13012d0/go.mod h1:uu1P0UCM/6RbsMrgPa98ll8ZcHM858i/AD06a9aLRCA=\ncontrib.go.opencensus.io/exporter/ocagent v0.4.12/go.mod h1:450APlNTSR6FrvC3CTRqYosuDstRB9un7SOx2k/9ckA=\ncontrib.go.opencensus.io/exporter/stackdriver v0.11.0/go.mod h1:hA7rlmtavV03FGxzWXAPBUnZeZBhWN/QYQAuMtxc9Bk=\ncontrib.go.opencensus.io/integrations/ocsql v0.1.4/go.mod h1:8DsSdjz3F+APR+0z0WkU1aRorQCFfRxvqjUUPMbF3fE=\ncontrib.go.opencensus.io/resource v0.0.0-20190131005048-21591786a5e0/go.mod h1:F361eGI91LCmW1I/Saf+rX0+OFcigGlFvXwEGEnkRLA=\ndmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=\ngithub.com/Azure/azure-amqp-common-go v1.1.3/go.mod h1:FhZtXirFANw40UXI2ntweO+VOkfaw8s6vZxUiRhLYW8=\ngithub.com/Azure/azure-amqp-common-go v1.1.4/go.mod h1:FhZtXirFANw40UXI2ntweO+VOkfaw8s6vZxUiRhLYW8=\ngithub.com/Azure/azure-pipeline-go v0.1.8/go.mod h1:XA1kFWRVhSK+KNFiOhfv83Fv8L9achrP7OxIzeTn1Yg=\ngithub.com/Azure/azure-pipeline-go v0.1.9/go.mod h1:XA1kFWRVhSK+KNFiOhfv83Fv8L9achrP7OxIzeTn1Yg=\ngithub.com/Azure/azure-sdk-for-go v21.3.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc=\ngithub.com/Azure/azure-sdk-for-go v27.3.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc=\ngithub.com/Azure/azure-service-bus-go v0.4.1/go.mod h1:d9ho9e/06euiTwGpKxmlbpPhFUsfCsq6a4tZ68r51qI=\ngithub.com/Azure/azure-storage-blob-go v0.6.0/go.mod h1:oGfmITT1V6x//CswqY2gtAHND+xIP64/qL7a5QJix0Y=\ngithub.com/Azure/go-autorest v11.0.0+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24=\ngithub.com/Azure/go-autorest v11.1.1+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24=\ngithub.com/Azure/go-autorest v11.1.2+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24=\ngithub.com/Azure/go-autorest/tracing v0.1.0/go.mod h1:ROEEAFwXycQw7Sn3DXNtEedEvdeRAgDr0izn4z5Ij88=\ngithub.com/BurntSushi/locker v0.0.0-20171006230638-a6e239ea1c69/go.mod h1:L1AbZdiDllfyYH5l5OkAaZtk7VkWe89bPJFmnDBNHxg=\ngithub.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=\ngithub.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=\ngithub.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=\ngithub.com/GeertJohan/go.incremental v1.0.0/go.mod h1:6fAjUhbVuX1KcMD3c8TEgVUqmo4seqhv0i0kdATSkM0=\ngithub.com/GeertJohan/go.rice v1.0.0/go.mod h1:eH6gbSOAUv07dQuZVnBmoDP8mgsM1rtixis4Tib9if0=\ngithub.com/GoogleCloudPlatform/cloudsql-proxy v0.0.0-20190418212003-6ac0b49e7197/go.mod h1:aJ4qN3TfrelA6NZ6AXsXRfmEVaYin3EDbSPJrKS8OXo=\ngithub.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0=\ngithub.com/Kunde21/markdownfmt/v2 v2.1.1-0.20210810103848-727f02f4c51c h1:rnouiLtDKeaWKnxRViK454oCI8jkhWv5fItCvZ9nJOU=\ngithub.com/Kunde21/markdownfmt/v2 v2.1.1-0.20210810103848-727f02f4c51c/go.mod h1:LFJueuHZej/Z7Xhqh/XgClfkDjZiiEBOLVTt1Duq1r0=\ngithub.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=\ngithub.com/PuerkitoBio/goquery v1.5.1 h1:PSPBGne8NIUWw+/7vFBV+kG2J/5MOjbzc7154OaKCSE=\ngithub.com/PuerkitoBio/goquery v1.5.1/go.mod h1:GsLWisAFVj4WgDibEWF4pvYnkVQBpKBKeU+7zCJoLcc=\ngithub.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0=\ngithub.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE=\ngithub.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo=\ngithub.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI=\ngithub.com/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/4+TcAqDqk/vUH7g=\ngithub.com/afex/hystrix-go v0.0.0-20180502004556-fa1af6a1f4f5/go.mod h1:SkGFH1ia65gfNATL8TAiHDNxPzPdmEL5uirI2Uyuz6c=\ngithub.com/akavel/rsrc v0.8.0/go.mod h1:uLoCtb9J+EyAqh+26kdrTgmzRBFPGOolLWKpdxkKq+c=\ngithub.com/alecthomas/assert v0.0.0-20170929043011-405dbfeb8e38/go.mod h1:r7bzyVFMNntcxPZXK3/+KdruV1H5KSlyVY0gc+NgInI=\ngithub.com/alecthomas/chroma v0.7.2-0.20200305040604-4f3623dce67a/go.mod h1:fv5SzZPFJbwp2NXJWpFIX7DZS4HgV1K4ew4Pc2OZD9s=\ngithub.com/alecthomas/chroma v0.7.3/go.mod h1:sko8vR34/90zvl5QdcUdvzL3J8NKjAUx9va9jPuFNoM=\ngithub.com/alecthomas/chroma v0.8.2 h1:x3zkuE2lUk/RIekyAJ3XRqSCP4zwWDfcw/YJCuCAACg=\ngithub.com/alecthomas/chroma v0.8.2/go.mod h1:sko8vR34/90zvl5QdcUdvzL3J8NKjAUx9va9jPuFNoM=\ngithub.com/alecthomas/colour v0.0.0-20160524082231-60882d9e2721/go.mod h1:QO9JBoKquHd+jz9nshCh40fOfO+JzsoXy8qTHF68zU0=\ngithub.com/alecthomas/kong v0.1.17-0.20190424132513-439c674f7ae0/go.mod h1:+inYUSluD+p4L8KdviBSgzcqEjUQOfC5fQDRFuc36lI=\ngithub.com/alecthomas/kong v0.2.1-0.20190708041108-0548c6b1afae/go.mod h1:+inYUSluD+p4L8KdviBSgzcqEjUQOfC5fQDRFuc36lI=\ngithub.com/alecthomas/kong v0.2.4/go.mod h1:kQOmtJgV+Lb4aj+I2LEn40cbtawdWJ9Y8QLq+lElKxE=\ngithub.com/alecthomas/kong-hcl v0.1.8-0.20190615233001-b21fea9723c8/go.mod h1:MRgZdU3vrFd05IQ89AxUZ0aYdF39BYoNFa324SodPCA=\ngithub.com/alecthomas/repr v0.0.0-20180818092828-117648cd9897/go.mod h1:xTS7Pm1pD1mvyM075QCDSRqH6qRLXylzS24ZTpRiSzQ=\ngithub.com/alecthomas/repr v0.0.0-20181024024818-d37bc2a10ba1/go.mod h1:xTS7Pm1pD1mvyM075QCDSRqH6qRLXylzS24ZTpRiSzQ=\ngithub.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=\ngithub.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751 h1:JYp7IbQjafoB+tBA3gMyHYHrpOtNuDiK/uB5uXxq5wM=\ngithub.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=\ngithub.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=\ngithub.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=\ngithub.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho=\ngithub.com/alecthomas/units v0.0.0-20210208195552-ff826a37aa15 h1:AUNCr9CiJuwrRYS3XieqF+Z9B9gNxo/eANAJCF2eiN4=\ngithub.com/alecthomas/units v0.0.0-20210208195552-ff826a37aa15/go.mod h1:OMCwj8VM1Kc9e19TLln2VL61YJF0x1XFtfdL4JdbSyE=\ngithub.com/andybalholm/cascadia v1.1.0/go.mod h1:GsXiBklL0woXo1j/WYWtSYYC4ouU9PqHO0sqidkEA4Y=\ngithub.com/andybalholm/cascadia v1.2.0 h1:vuRCkM5Ozh/BfmsaTm26kbjm0mIOM3yS5Ek/F5h18aE=\ngithub.com/andybalholm/cascadia v1.2.0/go.mod h1:YCyR8vOZT9aZ1CHEd8ap0gMVm2aFgxBp0T0eFw1RUQY=\ngithub.com/antchfx/htmlquery v1.2.3 h1:sP3NFDneHx2stfNXCKbhHFo8XgNjCACnU/4AO5gWz6M=\ngithub.com/antchfx/htmlquery v1.2.3/go.mod h1:B0ABL+F5irhhMWg54ymEZinzMSi0Kt3I2if0BLYa3V0=\ngithub.com/antchfx/xmlquery v1.2.4/go.mod h1:KQQuESaxSlqugE2ZBcM/qn+ebIpt+d+4Xx7YcSGAIrM=\ngithub.com/antchfx/xmlquery v1.3.4 h1:RuhsI4AA5Ma4XoXhaAr2VjJxU0Xp0W2zy/f9ZIpsF4s=\ngithub.com/antchfx/xmlquery v1.3.4/go.mod h1:64w0Xesg2sTaawIdNqMB+7qaW/bSqkQm+ssPaCMWNnc=\ngithub.com/antchfx/xpath v1.1.6/go.mod h1:Yee4kTMuNiPYJ7nSNorELQMr1J33uOpXDMByNYhvtNk=\ngithub.com/antchfx/xpath v1.1.8/go.mod h1:Yee4kTMuNiPYJ7nSNorELQMr1J33uOpXDMByNYhvtNk=\ngithub.com/antchfx/xpath v1.1.10 h1:cJ0pOvEdN/WvYXxvRrzQH9x5QWKpzHacYO8qzCcDYAg=\ngithub.com/antchfx/xpath v1.1.10/go.mod h1:Yee4kTMuNiPYJ7nSNorELQMr1J33uOpXDMByNYhvtNk=\ngithub.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ=\ngithub.com/apache/thrift v0.13.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ=\ngithub.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o=\ngithub.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8=\ngithub.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY=\ngithub.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8=\ngithub.com/armon/go-radix v1.0.0/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8=\ngithub.com/aryann/difflib v0.0.0-20170710044230-e206f873d14a/go.mod h1:DAHtR1m6lCRdSC2Tm3DSWRPvIPr6xNKyeHdqDQSQT+A=\ngithub.com/aws/aws-lambda-go v1.13.3/go.mod h1:4UKl9IzQMoD+QF79YdCuzCwp8VbmG4VAQwij/eHl5CU=\ngithub.com/aws/aws-sdk-go v1.15.27/go.mod h1:mFuSZ37Z9YOHbQEwBWztmVzqXrEkub65tZoCYDt7FT0=\ngithub.com/aws/aws-sdk-go v1.18.6/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo=\ngithub.com/aws/aws-sdk-go v1.19.16/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo=\ngithub.com/aws/aws-sdk-go v1.27.0/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo=\ngithub.com/aws/aws-sdk-go v1.27.1/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo=\ngithub.com/aws/aws-sdk-go-v2 v0.18.0/go.mod h1:JWVYvqSMppoMJC0x5wdwiImzgXTI9FuZwxzkQq9wy+g=\ngithub.com/aymerick/douceur v0.2.0 h1:Mv+mAeH1Q+n9Fr+oyamOlAkUNPWPlA8PPGR0QAaYuPk=\ngithub.com/aymerick/douceur v0.2.0/go.mod h1:wlT5vV2O3h55X9m7iVYN0TBM0NH/MmbLnd30/FjWUq4=\ngithub.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=\ngithub.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=\ngithub.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=\ngithub.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=\ngithub.com/bep/debounce v1.2.0/go.mod h1:H8yggRPQKLUhUoqrJC1bO2xNya7vanpDl7xR3ISbCJ0=\ngithub.com/bep/gitmap v1.1.2/go.mod h1:g9VRETxFUXNWzMiuxOwcudo6DfZkW9jOsOW0Ft4kYaY=\ngithub.com/bep/golibsass v0.6.0/go.mod h1:DL87K8Un/+pWUS75ggYv41bliGiolxzDKWJAq3eJ1MA=\ngithub.com/bep/tmc v0.5.1/go.mod h1:tGYHN8fS85aJPhDLgXETVKp+PR382OvFi2+q2GkGsq0=\ngithub.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs=\ngithub.com/bwplotka/mdox v0.9.0 h1:NRrJNWGDUjA2dWeWiJv/4WNQZp5+OcVYIHz94T6ksxs=\ngithub.com/bwplotka/mdox v0.9.0/go.mod h1:d9tSrvKyHqgb/IuvvhncvLzbV1SfSfhH56ct1TOYncw=\ngithub.com/casbin/casbin/v2 v2.1.2/go.mod h1:YcPU1XXisHhLzuxH9coDNf2FbKpjGlbCg3n9yuLkIJQ=\ngithub.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM=\ngithub.com/census-instrumentation/opencensus-proto v0.2.0/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=\ngithub.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=\ngithub.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko=\ngithub.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=\ngithub.com/cespare/xxhash/v2 v2.1.1 h1:6MnRN8NT7+YBpUIWxHtefFZOKTAPgGjpQSxqLNn0+qY=\ngithub.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=\ngithub.com/charmbracelet/glamour v0.3.0 h1:3H+ZrKlSg8s+WU6V7eF2eRVYt8lCueffbi7r2+ffGkc=\ngithub.com/charmbracelet/glamour v0.3.0/go.mod h1:TzF0koPZhqq0YVBNL100cPHznAAjVj7fksX2RInwjGw=\ngithub.com/cheekybits/is v0.0.0-20150225183255-68e9c0620927/go.mod h1:h/aW8ynjgkuj+NQRlZcDbAbM1ORAbXjXX77sX7T289U=\ngithub.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=\ngithub.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=\ngithub.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=\ngithub.com/clbanning/x2j v0.0.0-20191024224557-825249438eec/go.mod h1:jMjuTZXRI4dUb/I5gc9Hdhagfvm9+RyrPryS/auMzxE=\ngithub.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=\ngithub.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=\ngithub.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8=\ngithub.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI=\ngithub.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk=\ngithub.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=\ngithub.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk=\ngithub.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=\ngithub.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=\ngithub.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=\ngithub.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=\ngithub.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=\ngithub.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE=\ngithub.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=\ngithub.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY=\ngithub.com/daaku/go.zipexe v1.0.0/go.mod h1:z8IiR6TsVLEYKwXAoE/I+8ys/sDkgTzSL0CLnGVd57E=\ngithub.com/danwakefield/fnmatch v0.0.0-20160403171240-cbb64ac3d964 h1:y5HC9v93H5EPKqaS1UYVg1uYah5Xf51mBfIoWehClUQ=\ngithub.com/danwakefield/fnmatch v0.0.0-20160403171240-cbb64ac3d964/go.mod h1:Xd9hchkHSWYkEqJwUGisez3G1QY8Ryz0sdWrLPMGjLk=\ngithub.com/davecgh/go-spew v0.0.0-20161028175848-04cdfd42973b/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=\ngithub.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=\ngithub.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=\ngithub.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=\ngithub.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no=\ngithub.com/dimchansky/utfbom v1.1.0/go.mod h1:rO41eb7gLfo8SF1jd9F8HplJm1Fewwi4mQvIirEdv+8=\ngithub.com/disintegration/gift v1.2.1/go.mod h1:Jh2i7f7Q2BM7Ezno3PhfezbR1xpUg9dUg3/RlKGr4HI=\ngithub.com/dlclark/regexp2 v1.1.6/go.mod h1:2pZnwuY/m+8K6iRw6wQdMtk+rH5tNGR1i55kozfMjCc=\ngithub.com/dlclark/regexp2 v1.2.0 h1:8sAhBGEM0dRWogWqWyQeIJnxjWO6oIjl8FKqREDsGfk=\ngithub.com/dlclark/regexp2 v1.2.0/go.mod h1:2pZnwuY/m+8K6iRw6wQdMtk+rH5tNGR1i55kozfMjCc=\ngithub.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=\ngithub.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=\ngithub.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs=\ngithub.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU=\ngithub.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I=\ngithub.com/edsrzf/mmap-go v1.0.0/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M=\ngithub.com/efficientgo/tools/core v0.0.0-20210609125236-d73259166f20 h1:3wGt9Bx/h2D/0yOlYIhWB7GmsFBPG9vWDg90UUGgn8c=\ngithub.com/efficientgo/tools/core v0.0.0-20210609125236-d73259166f20/go.mod h1:OmVcnJopJL8d3X3sSXTiypGoUSgFq1aDGmlrdi9dn/M=\ngithub.com/efficientgo/tools/extkingpin v0.0.0-20210609125236-d73259166f20 h1:kM/ALyvAnTrwSB+nlKqoKaDnZbInp1YImZvW+gtHwc8=\ngithub.com/efficientgo/tools/extkingpin v0.0.0-20210609125236-d73259166f20/go.mod h1:ZV0utlglOczUWv3ih2AbqPSoLoFzdplUYxwV62eZi6Q=\ngithub.com/envoyproxy/go-control-plane v0.6.9/go.mod h1:SBwIajubJHhxtWwsL9s8ss4safvEdbitLhGGK48rN6g=\ngithub.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=\ngithub.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=\ngithub.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=\ngithub.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=\ngithub.com/evanw/esbuild v0.6.5/go.mod h1:mptxmSXIzBIKKCe4jo9A5SToEd1G+AKZ9JmY85dYRJ0=\ngithub.com/fatih/color v1.7.0 h1:DkWD4oS2D8LGGgTQ6IvwJJXSL5Vp2ffcQg58nFV38Ys=\ngithub.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=\ngithub.com/fatih/structtag v1.2.0/go.mod h1:mBJUNpUnHmRKrKlQQlmCrh5PuhftFbNv8Ys4/aAZl94=\ngithub.com/felixge/fgprof v0.9.1 h1:E6FUJ2Mlv043ipLOCFqo8+cHo9MhQ203E2cdEK/isEs=\ngithub.com/felixge/fgprof v0.9.1/go.mod h1:7/HK6JFtFaARhIljgP2IV8rJLIoHDoOYoUphsnGvqxE=\ngithub.com/fortytw2/leaktest v1.2.0/go.mod h1:jDsjWgpAGjm2CA7WthBh/CdZYEPF31XHquHwclZch5g=\ngithub.com/fortytw2/leaktest v1.3.0/go.mod h1:jDsjWgpAGjm2CA7WthBh/CdZYEPF31XHquHwclZch5g=\ngithub.com/franela/goblin v0.0.0-20200105215937-c9ffbefa60db/go.mod h1:7dvUGVsVBjqR7JHJk0brhHOZYGmfBYOrK0ZhYMEtBr4=\ngithub.com/franela/goreq v0.0.0-20171204163338-bcd34c9993f8/go.mod h1:ZhphrRTfi2rbfLwlschooIH4+wKKDR4Pdxhh+TRoA20=\ngithub.com/frankban/quicktest v1.4.1/go.mod h1:36zfPVQyHxymz4cH7wlDmVwDrJuljRB60qkgn7rorfQ=\ngithub.com/frankban/quicktest v1.7.2/go.mod h1:jaStnuzAqU1AJdCO0l53JDCJrVDKcS03DbaAcR7Ks/o=\ngithub.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=\ngithub.com/getkin/kin-openapi v0.14.0/go.mod h1:WGRs2ZMM1Q8LR1QBEwUxC6RJEfaBcD0s+pcEVXFuAjw=\ngithub.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=\ngithub.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=\ngithub.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=\ngithub.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=\ngithub.com/go-ini/ini v1.25.4/go.mod h1:ByCAeIL28uOIIG0E3PJtZPDL8WnHpFKFOtgjp+3Ies8=\ngithub.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=\ngithub.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=\ngithub.com/go-kit/kit v0.10.0 h1:dXFJfIHVvUcpSgDOV+Ne6t7jXri8Tfv2uOLHUZ2XNuo=\ngithub.com/go-kit/kit v0.10.0/go.mod h1:xUsJbQ/Fp4kEt7AFgCuvyX4a71u8h9jB8tj/ORgOZ7o=\ngithub.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY=\ngithub.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=\ngithub.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=\ngithub.com/go-logfmt/logfmt v0.5.0 h1:TrB8swr/68K7m9CcGut2g3UOihhbcbiMAYiuTXdEih4=\ngithub.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A=\ngithub.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=\ngithub.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=\ngithub.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=\ngithub.com/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y=\ngithub.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8=\ngithub.com/gocolly/colly v1.2.0 h1:qRz9YAn8FIH0qzgNUw+HT9UN7wm1oF9OBAilwEWpyrI=\ngithub.com/gocolly/colly v1.2.0/go.mod h1:Hof5T3ZswNVsOHYmba1u03W65HDWgpV5HifSuueE0EA=\ngithub.com/gocolly/colly/v2 v2.1.1-0.20201013153555-8252c346cfb0 h1:f+kHjWsqjft+/nCpQ6TcV3Lgs4lc+6rvBt2sfL4XsbE=\ngithub.com/gocolly/colly/v2 v2.1.1-0.20201013153555-8252c346cfb0/go.mod h1:I2MuhsLjQ+Ex+IzK3afNS8/1qP3AedHOusRPcRdC5o0=\ngithub.com/gogo/googleapis v1.1.0/go.mod h1:gf4bu3Q80BeJ6H1S1vYPm8/ELATdvryBaNFGgqEef3s=\ngithub.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=\ngithub.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=\ngithub.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4=\ngithub.com/gohugoio/hugo v0.74.3 h1:fAMS4JYV+T9YiHj+be4mrYDFzNgx91UY+Gok/FdbSzU=\ngithub.com/gohugoio/hugo v0.74.3/go.mod h1:qTy3SQXdyeRLfUMMdGZeySMGMzvi3D31prjuIbAwImk=\ngithub.com/gohugoio/testmodBuilder/mods v0.0.0-20190520184928-c56af20f2e95/go.mod h1:bOlVlCa1/RajcHpXkrUXPSHB/Re1UnlXxD1Qp8SKOd8=\ngithub.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=\ngithub.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=\ngithub.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=\ngithub.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=\ngithub.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=\ngithub.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e h1:1r7pUrabqp18hOBcwBwiTsbnFeTZHV9eER/QT5JVZxY=\ngithub.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=\ngithub.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=\ngithub.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=\ngithub.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y=\ngithub.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=\ngithub.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=\ngithub.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=\ngithub.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4=\ngithub.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=\ngithub.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=\ngithub.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=\ngithub.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=\ngithub.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=\ngithub.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk=\ngithub.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=\ngithub.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=\ngithub.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs=\ngithub.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w=\ngithub.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=\ngithub.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8=\ngithub.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=\ngithub.com/golang/protobuf v1.4.3 h1:JjCZWpVbqXDqFVmTfYWEVTMIYrL/NPdPSCHPJ0T/raM=\ngithub.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=\ngithub.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=\ngithub.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=\ngithub.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=\ngithub.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=\ngithub.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=\ngithub.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=\ngithub.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=\ngithub.com/google/go-cmp v0.3.2-0.20191028172631-481baca67f93/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=\ngithub.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=\ngithub.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=\ngithub.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=\ngithub.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=\ngithub.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=\ngithub.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=\ngithub.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=\ngithub.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=\ngithub.com/google/martian v2.1.1-0.20190517191504-25dcb96d9e51+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=\ngithub.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=\ngithub.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=\ngithub.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=\ngithub.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=\ngithub.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=\ngithub.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=\ngithub.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=\ngithub.com/google/pprof v0.0.0-20200615235658-03e1cf38a040/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=\ngithub.com/google/pprof v0.0.0-20200708004538-1a94d8640e99 h1:Ak8CrdlwwXwAZxzS66vgPt4U8yUZX7JwLvVR58FN5jM=\ngithub.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=\ngithub.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=\ngithub.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=\ngithub.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=\ngithub.com/google/wire v0.2.2/go.mod h1:7FHVg6mFpFQrjeUZrm+BaD50N5jnDKm50uVPTpyYOmU=\ngithub.com/googleapis/gax-go v2.0.2+incompatible/go.mod h1:SFVmujtThgffbyetf+mdk2eWhX2bMyUtNHzFKcPA9HY=\ngithub.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=\ngithub.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=\ngithub.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=\ngithub.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg=\ngithub.com/gorilla/csrf v1.6.0/go.mod h1:7tSf8kmjNYr7IWDCYhd3U8Ck34iQ/Yw5CJu7bAkHEGI=\ngithub.com/gorilla/css v1.0.0 h1:BQqNyPTi50JCFMTw/b67hByjMVXZRwGha6wxVGkeihY=\ngithub.com/gorilla/css v1.0.0/go.mod h1:Dn721qIggHpt4+EFCcTLTU/vk5ySda2ReITrtgBl60c=\ngithub.com/gorilla/handlers v1.4.1/go.mod h1:Qkdc/uu4tH4g6mTK6auzZ766c4CA0Ng8+o/OAirnOIQ=\ngithub.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=\ngithub.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=\ngithub.com/gorilla/securecookie v1.1.1/go.mod h1:ra0sb63/xPlUeL+yeDciTfxMRAA+MP+HVt/4epWDjd4=\ngithub.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=\ngithub.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=\ngithub.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=\ngithub.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs=\ngithub.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de4/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs=\ngithub.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk=\ngithub.com/grpc-ecosystem/grpc-gateway v1.8.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=\ngithub.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=\ngithub.com/grpc-ecosystem/grpc-gateway v1.9.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=\ngithub.com/hashicorp/consul/api v1.3.0/go.mod h1:MmDNSzIMUjNpY/mQ398R4bk2FnqQLoPndWW5VkKPlCE=\ngithub.com/hashicorp/consul/sdk v0.3.0/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8=\ngithub.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=\ngithub.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80=\ngithub.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60=\ngithub.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM=\ngithub.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk=\ngithub.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU=\ngithub.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU=\ngithub.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4=\ngithub.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=\ngithub.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=\ngithub.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=\ngithub.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90=\ngithub.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=\ngithub.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=\ngithub.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=\ngithub.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64=\ngithub.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ=\ngithub.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I=\ngithub.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc=\ngithub.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=\ngithub.com/hudl/fargo v1.3.0/go.mod h1:y3CKSmjA+wD2gak7sUSXTAoopbhU08POFhmITJgmKTg=\ngithub.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=\ngithub.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=\ngithub.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo=\ngithub.com/jawher/mow.cli v1.1.0/go.mod h1:aNaQlc7ozF3vw6IJ2dHjp2ZFiA4ozMIYY6PyuRJwlUg=\ngithub.com/jdkato/prose v1.1.1/go.mod h1:jkF0lkxaX5PFSlk9l4Gh9Y+T57TqUZziWT7uZbW5ADg=\ngithub.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=\ngithub.com/jmespath/go-jmespath v0.0.0-20160202185014-0b12d6b521d8/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k=\ngithub.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k=\ngithub.com/joho/godotenv v1.3.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqxOKXbg=\ngithub.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo=\ngithub.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4=\ngithub.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=\ngithub.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=\ngithub.com/json-iterator/go v1.1.8/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=\ngithub.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=\ngithub.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=\ngithub.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=\ngithub.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk=\ngithub.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=\ngithub.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=\ngithub.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM=\ngithub.com/kennygrant/sanitize v1.2.4 h1:gN25/otpP5vAsO2djbMhF/LQX6R7+O1TB4yv8NzpJ3o=\ngithub.com/kennygrant/sanitize v1.2.4/go.mod h1:LGsjYYtgxbetdg5owWB2mpgUL6e2nfw2eObZ0u0qvak=\ngithub.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=\ngithub.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=\ngithub.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=\ngithub.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=\ngithub.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=\ngithub.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=\ngithub.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=\ngithub.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=\ngithub.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=\ngithub.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=\ngithub.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw=\ngithub.com/kyokomi/emoji v2.2.1+incompatible/go.mod h1:mZ6aGCD7yk8j6QY6KICwnZ2pxoszVseX1DNoGtU2tBA=\ngithub.com/lib/pq v1.1.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=\ngithub.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20190605223551-bc2310a04743/go.mod h1:qklhhLq1aX+mtWk9cPHPzaBjWImj5ULL6C7HFJtXQMM=\ngithub.com/lightstep/lightstep-tracer-go v0.18.1/go.mod h1:jlF1pusYV4pidLvZ+XD0UBX0ZE6WURAspgAczcDHrL4=\ngithub.com/lucasb-eyer/go-colorful v1.2.0 h1:1nnpGOrhyZZuNyfu1QjKiUICQ74+3FNCN69Aj6K7nkY=\ngithub.com/lucasb-eyer/go-colorful v1.2.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0=\ngithub.com/lyft/protoc-gen-validate v0.0.13/go.mod h1:XbGvPuh87YZc5TdIa2/I4pLk0QoUACkjt2znoq26NVQ=\ngithub.com/magefile/mage v1.9.0/go.mod h1:z5UZb/iS3GoOSn0JgWuiw7dxlurVYTu+/jHXqQg881A=\ngithub.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=\ngithub.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=\ngithub.com/markbates/inflect v1.0.0/go.mod h1:oTeZL2KHA7CUX6X+fovmK9OvIOFuqu0TwdQrZjLTh88=\ngithub.com/matryer/try v0.0.0-20161228173917-9ac251b645a2/go.mod h1:0KeJpeMD6o+O4hW7qJOT7vyQPKrWmj26uf5wMc/IiIs=\ngithub.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=\ngithub.com/mattn/go-colorable v0.1.6 h1:6Su7aK7lXmJ/U79bYtBjLNaha4Fs1Rg9plHpcH+vvnE=\ngithub.com/mattn/go-colorable v0.1.6/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=\ngithub.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=\ngithub.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=\ngithub.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY=\ngithub.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=\ngithub.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=\ngithub.com/mattn/go-runewidth v0.0.7/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=\ngithub.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=\ngithub.com/mattn/go-runewidth v0.0.10/go.mod h1:RAqKPSqVFrSLVXbA8x7dzmKdmGzieGRCM46jaSJTDAk=\ngithub.com/mattn/go-runewidth v0.0.13 h1:lTGmDsbAYt5DmK6OnoV7EuIF1wEIFAcxld6ypU4OSgU=\ngithub.com/mattn/go-runewidth v0.0.13/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=\ngithub.com/mattn/go-shellwords v1.0.10 h1:Y7Xqm8piKOO3v10Thp7Z36h4FYFjt5xB//6XvOrs2Gw=\ngithub.com/mattn/go-shellwords v1.0.10/go.mod h1:EZzvwXDESEeg03EKmM+RmDnNOPKG4lLtQsUlTZDWQ8Y=\ngithub.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU=\ngithub.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=\ngithub.com/microcosm-cc/bluemonday v1.0.6 h1:ZOvqHKtnx0fUpnbQm3m3zKFWE+DRC+XB1onh8JoEObE=\ngithub.com/microcosm-cc/bluemonday v1.0.6/go.mod h1:HOT/6NaBlR0f9XlxD3zolN6Z3N8Lp4pvhp+jLS5ihnI=\ngithub.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=\ngithub.com/miekg/mmark v1.3.6/go.mod h1:w7r9mkTvpS55jlfyn22qJ618itLryxXBhA7Jp3FIlkw=\ngithub.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc=\ngithub.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=\ngithub.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=\ngithub.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI=\ngithub.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS42BGNg=\ngithub.com/mitchellh/hashstructure v1.0.0/go.mod h1:QjSHrPWS+BGUVBYkbTZWEnOh3G1DutKwClXU/ABz6AQ=\ngithub.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY=\ngithub.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=\ngithub.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=\ngithub.com/mitchellh/mapstructure v1.2.2 h1:dxe5oCinTXiTIcfgmZecdCzPmAJKd46KsCWc35r0TV4=\ngithub.com/mitchellh/mapstructure v1.2.2/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=\ngithub.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=\ngithub.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=\ngithub.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=\ngithub.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=\ngithub.com/muesli/reflow v0.2.0/go.mod h1:qT22vjVmM9MIUeLgsVYe/Ye7eZlbv9dZjL3dVhUqLX8=\ngithub.com/muesli/reflow v0.2.1-0.20210115123740-9e1d0d53df68 h1:y1p/ycavWjGT9FnmSjdbWUlLGvcxrY0Rw3ATltrxOhk=\ngithub.com/muesli/reflow v0.2.1-0.20210115123740-9e1d0d53df68/go.mod h1:Xk+z4oIWdQqJzsxyjgl3P22oYZnHdZ8FFTHAQQt5BMQ=\ngithub.com/muesli/smartcrop v0.3.0/go.mod h1:i2fCI/UorTfgEpPPLWiFBv4pye+YAG78RwcQLUkocpI=\ngithub.com/muesli/termenv v0.8.1 h1:9q230czSP3DHVpkaPDXGp0TOfAwyjyYwXlUCQxQSaBk=\ngithub.com/muesli/termenv v0.8.1/go.mod h1:kzt/D/4a88RoheZmwfqorY3A+tnsSMA9HJC/fQSFKo0=\ngithub.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=\ngithub.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=\ngithub.com/nats-io/jwt v0.3.0/go.mod h1:fRYCDE99xlTsqUzISS1Bi75UBJ6ljOJQOAAu5VglpSg=\ngithub.com/nats-io/jwt v0.3.2/go.mod h1:/euKqTS1ZD+zzjYrY7pseZrTtWQSjujC7xjPc8wL6eU=\ngithub.com/nats-io/nats-server/v2 v2.1.2/go.mod h1:Afk+wRZqkMQs/p45uXdrVLuab3gwv3Z8C4HTBu8GD/k=\ngithub.com/nats-io/nats.go v1.9.1/go.mod h1:ZjDU1L/7fJ09jvUSRVBR2e7+RnLiiIQyqyzEE/Zbp4w=\ngithub.com/nats-io/nkeys v0.1.0/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w=\ngithub.com/nats-io/nkeys v0.1.3/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w=\ngithub.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c=\ngithub.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646/go.mod h1:jpp1/29i3P1S/RLdc7JQKbRpFeM1dOBd8T9ki5s+AY8=\ngithub.com/nicksnyder/go-i18n v1.10.0/go.mod h1:HrK7VCrbOvQoUAQ7Vpy7i87N7JZZZ7R2xBGjv0j365Q=\ngithub.com/niklasfasching/go-org v1.3.0 h1:X8Ob7WOF61iP4KnisZo1eVVei8/GzmNz3ymJrYLnIic=\ngithub.com/niklasfasching/go-org v1.3.0/go.mod h1:AsLD6X7djzRIz4/RFZu8vwRL0VGjUvGZCCH1Nz0VdrU=\ngithub.com/nkovacs/streamquote v0.0.0-20170412213628-49af9bddb229/go.mod h1:0aYXnNPJ8l7uZxf45rWW1a/uME32OF0rhiYGNQ2oF2E=\ngithub.com/oklog/oklog v0.3.2/go.mod h1:FCV+B7mhrz4o+ueLpx+KqkyXRGMWOYEvfiXtdGtbWGs=\ngithub.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA=\ngithub.com/oklog/run v1.1.0 h1:GEenZ1cK0+q0+wsJew9qUg/DyD8k3JzYsZAi5gYi2mA=\ngithub.com/oklog/run v1.1.0/go.mod h1:sVPdnTZT1zYwAJeCMu2Th4T21pA3FPOQRfWjQlk7DVU=\ngithub.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U=\ngithub.com/olekukonko/tablewriter v0.0.0-20170122224234-a0225b3f23b5/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo=\ngithub.com/olekukonko/tablewriter v0.0.4/go.mod h1:zq6QwlOf5SlnkVbMSr5EoBv3636FWnp+qbPhuoO21uA=\ngithub.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec=\ngithub.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY=\ngithub.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=\ngithub.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=\ngithub.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=\ngithub.com/op/go-logging v0.0.0-20160315200505-970db520ece7/go.mod h1:HzydrMdWErDVzsI23lYNej1Htcns9BCg93Dk0bBINWk=\ngithub.com/opentracing-contrib/go-observer v0.0.0-20170622124052-a52f23424492/go.mod h1:Ngi6UdF0k5OKD5t5wlmGhe/EDKPoUM3BXZSSfIuJbis=\ngithub.com/opentracing/basictracer-go v1.0.0/go.mod h1:QfBfYuafItcjQuMwinw9GhYKwFXS9KnPs5lxoYwgW74=\ngithub.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=\ngithub.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=\ngithub.com/openzipkin-contrib/zipkin-go-opentracing v0.4.5/go.mod h1:/wsWhb9smxSfWAKL3wpBW7V8scJMt8N8gnaMCS9E/cA=\ngithub.com/openzipkin/zipkin-go v0.1.6/go.mod h1:QgAqvLzwWbR/WpD4A3cGpPtJrZXNIiJc5AZX7/PBEpw=\ngithub.com/openzipkin/zipkin-go v0.2.1/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4=\ngithub.com/openzipkin/zipkin-go v0.2.2/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4=\ngithub.com/pact-foundation/pact-go v1.0.4/go.mod h1:uExwJY4kCzNPcHRj+hCR/HBbOOIwwtUjcrb0b5/5kLM=\ngithub.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=\ngithub.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k=\ngithub.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=\ngithub.com/pelletier/go-toml v1.6.0/go.mod h1:5N711Q9dKgbdkxHL+MEfF31hpT7l0S0s/t2kKREewys=\ngithub.com/performancecopilot/speed v3.0.0+incompatible/go.mod h1:/CLtqpZ5gBg1M9iaPbIdPPGyKcA8hKdoy6hAWba7Yac=\ngithub.com/pierrec/lz4 v1.0.2-0.20190131084431-473cd7ce01a1/go.mod h1:3/3N9NVKO0jef7pBehbT1qWhCMrIgbYNnFAZCqQ5LRc=\ngithub.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY=\ngithub.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=\ngithub.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=\ngithub.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=\ngithub.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=\ngithub.com/pkg/profile v1.2.1/go.mod h1:hJw3o1OdXxsrSjjVksARp5W95eeEaEfptyVZyv6JUPA=\ngithub.com/pmezard/go-difflib v0.0.0-20151028094244-d8ed2627bdf0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=\ngithub.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=\ngithub.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI=\ngithub.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=\ngithub.com/prometheus/client_golang v0.9.3-0.20190127221311-3c4408c8b829/go.mod h1:p2iRAGwDERtqlqzRXnrOVns+ignqQo//hLXqYxZYVNs=\ngithub.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso=\ngithub.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo=\ngithub.com/prometheus/client_golang v1.3.0/go.mod h1:hJaj2vgQTGQmVCsAACORcieXFeDPbaTKGT+JTgUa3og=\ngithub.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M=\ngithub.com/prometheus/client_golang v1.11.0 h1:HNkLOAEQMIDv/K+04rukrLx6ch7msSRwf3/SASFAGtQ=\ngithub.com/prometheus/client_golang v1.11.0/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0=\ngithub.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=\ngithub.com/prometheus/client_model v0.0.0-20190115171406-56726106282f/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=\ngithub.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=\ngithub.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=\ngithub.com/prometheus/client_model v0.1.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=\ngithub.com/prometheus/client_model v0.2.0 h1:uq5h0d+GuxiXLJLNABMgp2qUWDPiLvgCzz2dUR+/W/M=\ngithub.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=\ngithub.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro=\ngithub.com/prometheus/common v0.2.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=\ngithub.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=\ngithub.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=\ngithub.com/prometheus/common v0.7.0/go.mod h1:DjGbpBbp5NYNiECxcL/VnbXCCaQpKd3tt26CguLLsqA=\ngithub.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo=\ngithub.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc=\ngithub.com/prometheus/common v0.30.0 h1:JEkYlQnpzrzQFxi6gnukFPdQ+ac82oRhzMcIduJu/Ug=\ngithub.com/prometheus/common v0.30.0/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls=\ngithub.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=\ngithub.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=\ngithub.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=\ngithub.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=\ngithub.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A=\ngithub.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU=\ngithub.com/prometheus/procfs v0.6.0 h1:mxy4L2jP6qMonqmq+aTtOx1ifVWUgG/TAmntgbh3xv4=\ngithub.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA=\ngithub.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU=\ngithub.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4=\ngithub.com/rivo/uniseg v0.1.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=\ngithub.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY=\ngithub.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=\ngithub.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=\ngithub.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=\ngithub.com/rogpeppe/go-internal v1.5.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc=\ngithub.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g=\ngithub.com/russross/blackfriday v1.5.3-0.20200218234912-41c5fccfd6f6/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g=\ngithub.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=\ngithub.com/rwcarlsen/goexif v0.0.0-20190401172101-9e8deecbddbd/go.mod h1:hPqNNc0+uJM6H+SuU8sEs5K5IQeKccPqeSjfgcKGgPk=\ngithub.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts=\ngithub.com/saintfish/chardet v0.0.0-20120816061221-3af4cd4741ca h1:NugYot0LIVPxTvN8n+Kvkn6TrbMyxQiuvKdEwFdR9vI=\ngithub.com/saintfish/chardet v0.0.0-20120816061221-3af4cd4741ca/go.mod h1:uugorj2VCxiV1x+LzaIdVa9b4S4qGAcH6cbhh4qVxOU=\ngithub.com/samuel/go-zookeeper v0.0.0-20190923202752-2cc03de413da/go.mod h1:gi+0XIa01GRL2eRQVjQkKGqKF3SF9vZR/HnPullcV2E=\ngithub.com/sanity-io/litter v1.2.0/go.mod h1:JF6pZUFgu2Q0sBZ+HSV35P8TVPI1TTzEwyu9FXAw2W4=\ngithub.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc=\ngithub.com/sergi/go-diff v1.0.0 h1:Kpca3qRNrduNnOQeazBd0ysaKrUJiIuISHxogkT9RPQ=\ngithub.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo=\ngithub.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=\ngithub.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=\ngithub.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=\ngithub.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88=\ngithub.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=\ngithub.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=\ngithub.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM=\ngithub.com/sony/gobreaker v0.4.1/go.mod h1:ZKptC7FHNvhBz7dN2LGjPVBz2sZJmc0/PkyDJOjmxWY=\ngithub.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=\ngithub.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ=\ngithub.com/spf13/afero v1.2.2 h1:5jhuqJyZCZf2JRofRvN/nIFgIWNzPa3/Vz8mYylgbWc=\ngithub.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk=\ngithub.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=\ngithub.com/spf13/cast v1.3.1 h1:nFm6S0SMdyzrzcmThSipiEubIDy8WEXKNZ0UOgiRpng=\ngithub.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=\ngithub.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ=\ngithub.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU=\ngithub.com/spf13/fsync v0.9.0/go.mod h1:fNtJEfG3HiltN3y4cPOz6MLjos9+2pIEqLIgszqhp/0=\ngithub.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo=\ngithub.com/spf13/jwalterweatherman v1.1.0 h1:ue6voC5bR5F8YxI5S67j9i582FU4Qvo2bmqnqMYADFk=\ngithub.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo=\ngithub.com/spf13/pflag v1.0.1/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=\ngithub.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=\ngithub.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=\ngithub.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s=\ngithub.com/spf13/viper v1.6.1/go.mod h1:t3iDnF5Jlj76alVNuyFBk5oUMCvsrkbvZK0WQdfDi5k=\ngithub.com/streadway/amqp v0.0.0-20190404075320-75d898a42a94/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw=\ngithub.com/streadway/amqp v0.0.0-20190827072141-edfb9018d271/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw=\ngithub.com/streadway/handy v0.0.0-20190108123426-d5acb3125c2a/go.mod h1:qNTQ5P5JnDBl6z3cMAg/SywNDC5ABu5ApDIw6lUbRmI=\ngithub.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=\ngithub.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=\ngithub.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE=\ngithub.com/stretchr/testify v0.0.0-20161117074351-18a02ba4a312/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=\ngithub.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=\ngithub.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=\ngithub.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=\ngithub.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=\ngithub.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=\ngithub.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw=\ngithub.com/tdewolff/minify/v2 v2.6.2/go.mod h1:BkDSm8aMMT0ALGmpt7j3Ra7nLUgZL0qhyrAHXwxcy5w=\ngithub.com/tdewolff/parse/v2 v2.4.2/go.mod h1:WzaJpRSbwq++EIQHYIRTpbYKNA3gn9it1Ik++q4zyho=\ngithub.com/tdewolff/test v1.0.6/go.mod h1:6DAvZliBAAnD7rhVgwaM7DE5/d9NMOAJ09SqYqeK4QE=\ngithub.com/temoto/robotstxt v1.1.1 h1:Gh8RCs8ouX3hRSxxK7B1mO5RFByQ4CmJZDwgom++JaA=\ngithub.com/temoto/robotstxt v1.1.1/go.mod h1:+1AmkuG3IYkh1kv0d2qEB9Le88ehNO0zwOr3ujewlOo=\ngithub.com/theckman/yacspin v0.8.0 h1:9LA2kUol1/+eH5m/ptlbYCrnCEfLCaX4Xn+5tK/AprI=\ngithub.com/theckman/yacspin v0.8.0/go.mod h1:K1H1naXCpDytqETpvmlxWzAq8BbOMy3Wrd0iy0ZNzRI=\ngithub.com/tidwall/pretty v0.0.0-20190325153808-1166b9ac2b65/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk=\ngithub.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=\ngithub.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=\ngithub.com/uber-go/atomic v1.3.2/go.mod h1:/Ct5t2lcmbJ4OSe/waGBoaVvVqtO0bmtfVNex1PFV8g=\ngithub.com/uber/jaeger-client-go v2.15.0+incompatible/go.mod h1:WVhlPFC8FDjOFMMWRy2pZqQJSXxYSwNYOkTr/Z6d3Kk=\ngithub.com/uber/jaeger-lib v1.5.0/go.mod h1:ComeNDZlWwrWnDv8aPp0Ba6+uUTzImX/AauajbLI56U=\ngithub.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc=\ngithub.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0=\ngithub.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA=\ngithub.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=\ngithub.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=\ngithub.com/valyala/fasttemplate v1.0.1/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPUpymEIMZ47gx8=\ngithub.com/xdg/scram v0.0.0-20180814205039-7eeb5667e42c/go.mod h1:lB8K/P019DLNhemzwFU4jHLhdvlE6uDZjXFejJXr49I=\ngithub.com/xdg/stringprep v1.0.0/go.mod h1:Jhud4/sHMO4oL310DaZAKk9ZaJ08SJfe+sJh0HrGL1Y=\ngithub.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=\ngithub.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q=\ngithub.com/yuin/goldmark v1.1.22/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=\ngithub.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=\ngithub.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=\ngithub.com/yuin/goldmark v1.1.31/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=\ngithub.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=\ngithub.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=\ngithub.com/yuin/goldmark v1.3.3/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=\ngithub.com/yuin/goldmark v1.3.5 h1:dPmz1Snjq0kmkz159iL7S6WzdahUTHnHB5M56WFVifs=\ngithub.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=\ngithub.com/yuin/goldmark-emoji v1.0.1 h1:ctuWEyzGBwiucEqxzwe0SOYDXPAucOrE9NQC18Wa1os=\ngithub.com/yuin/goldmark-emoji v1.0.1/go.mod h1:2w1E6FEWLcDQkoTE+7HU6QF1F6SLlNGjRIBbIZQFqkQ=\ngithub.com/yuin/goldmark-highlighting v0.0.0-20200307114337-60d527fdb691/go.mod h1:YLF3kDffRfUH/bTxOxHhV6lxwIB3Vfj91rEwNMS9MXo=\ngo.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=\ngo.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=\ngo.etcd.io/etcd v0.0.0-20191023171146-3cf2f69b5738/go.mod h1:dnLIgRNXwCJa5e+c6mIZCrds/GIG4ncV9HhK5PX7jPg=\ngo.mongodb.org/mongo-driver v1.0.1/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM=\ngo.opencensus.io v0.15.0/go.mod h1:UffZAU+4sDEINUGP/B7UfBBkq4fqLu9zXAX7ke6CHW0=\ngo.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk=\ngo.opencensus.io v0.20.2/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk=\ngo.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=\ngo.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8=\ngo.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=\ngo.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=\ngo.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=\ngo.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=\ngo.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=\ngo.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=\ngo.uber.org/goleak v1.1.10/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A=\ngo.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=\ngo.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4=\ngo.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA=\ngo.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=\ngo.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM=\ngocloud.dev v0.15.0/go.mod h1:ShXCyJaGrJu9y/7a6+DSCyBb9MFGZ1P5wwPa0Wu6w34=\ngolang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=\ngolang.org/x/crypto v0.0.0-20181001203147-e3636079e1a4/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=\ngolang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=\ngolang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=\ngolang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=\ngolang.org/x/crypto v0.0.0-20190422183909-d864b10871cd/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=\ngolang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=\ngolang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=\ngolang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=\ngolang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=\ngolang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=\ngolang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=\ngolang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=\ngolang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=\ngolang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek=\ngolang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY=\ngolang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=\ngolang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=\ngolang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=\ngolang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM=\ngolang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU=\ngolang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=\ngolang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=\ngolang.org/x/image v0.0.0-20191214001246-9130b4cfad52/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=\ngolang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=\ngolang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=\ngolang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=\ngolang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=\ngolang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=\ngolang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=\ngolang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=\ngolang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs=\ngolang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=\ngolang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=\ngolang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE=\ngolang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o=\ngolang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=\ngolang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY=\ngolang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=\ngolang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=\ngolang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=\ngolang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=\ngolang.org/x/net v0.0.0-20180218175443-cbe0f9307d01/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=\ngolang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=\ngolang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=\ngolang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=\ngolang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=\ngolang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=\ngolang.org/x/net v0.0.0-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=\ngolang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=\ngolang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=\ngolang.org/x/net v0.0.0-20190125091013-d26f9f9a57f3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=\ngolang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=\ngolang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=\ngolang.org/x/net v0.0.0-20190320064053-1272bf9dcd53/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=\ngolang.org/x/net v0.0.0-20190322120337-addf6b3196f6/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=\ngolang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=\ngolang.org/x/net v0.0.0-20190420063019-afa5a82059c6/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=\ngolang.org/x/net v0.0.0-20190424112056-4829fb13d2c6/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=\ngolang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=\ngolang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=\ngolang.org/x/net v0.0.0-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=\ngolang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=\ngolang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=\ngolang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=\ngolang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=\ngolang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=\ngolang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=\ngolang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=\ngolang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=\ngolang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=\ngolang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=\ngolang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=\ngolang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=\ngolang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=\ngolang.org/x/net v0.0.0-20200421231249-e086a090c8fd/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=\ngolang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=\ngolang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=\ngolang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=\ngolang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=\ngolang.org/x/net v0.0.0-20200602114024-627f9648deb9/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=\ngolang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=\ngolang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=\ngolang.org/x/net v0.0.0-20200813134508-3edf25e44fcc/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=\ngolang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=\ngolang.org/x/net v0.0.0-20210331212208-0fccb6fa2b5c/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=\ngolang.org/x/net v0.0.0-20210525063256-abc453219eb5 h1:wjuX4b5yYQnEQHzd+CBcrcC6OVR2J1CN6mUy0oSxIPo=\ngolang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=\ngolang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=\ngolang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=\ngolang.org/x/oauth2 v0.0.0-20190319182350-c85d3e98c914/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=\ngolang.org/x/oauth2 v0.0.0-20190402181905-9f3314589c9a/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=\ngolang.org/x/oauth2 v0.0.0-20190523182746-aaccbc9213b0/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=\ngolang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=\ngolang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=\ngolang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=\ngolang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=\ngolang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=\ngolang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=\ngolang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=\ngolang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=\ngolang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=\ngolang.org/x/sys v0.0.0-20181031143558-9b800f95dbbc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=\ngolang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=\ngolang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=\ngolang.org/x/sys v0.0.0-20181122145206-62eef0e2fa9b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=\ngolang.org/x/sys v0.0.0-20181128092732-4ed8d59d0b35/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=\ngolang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=\ngolang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=\ngolang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20191220142924-d4481acd189f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200413165638-669c56c373c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200501145240-bc7a7d42d5c3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20210603081109-ebe580a85c40 h1:JWgyZ1qgdTaF3N3oxC+MdTV7qvEEgHo3otj+HB5CM7Q=\ngolang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=\ngolang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=\ngolang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=\ngolang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=\ngolang.org/x/text v0.3.1-0.20181227161524-e6919f6577db/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=\ngolang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=\ngolang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=\ngolang.org/x/text v0.3.6 h1:aRYxNxv6iGQlyVaZmk6ZgYEDa+Jg18DxebPSrd6bg1M=\ngolang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=\ngolang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=\ngolang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=\ngolang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=\ngolang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=\ngolang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=\ngolang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=\ngolang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=\ngolang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=\ngolang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=\ngolang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=\ngolang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=\ngolang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=\ngolang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=\ngolang.org/x/tools v0.0.0-20190422233926-fe54fb35175b/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=\ngolang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=\ngolang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=\ngolang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=\ngolang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=\ngolang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=\ngolang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=\ngolang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=\ngolang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=\ngolang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=\ngolang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=\ngolang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=\ngolang.org/x/tools v0.0.0-20191108193012-7d206e10da11/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=\ngolang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=\ngolang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=\ngolang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=\ngolang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=\ngolang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=\ngolang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=\ngolang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=\ngolang.org/x/tools v0.0.0-20200103221440-774c71fcf114/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=\ngolang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=\ngolang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=\ngolang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=\ngolang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=\ngolang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=\ngolang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=\ngolang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=\ngolang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=\ngolang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw=\ngolang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw=\ngolang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8=\ngolang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=\ngolang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=\ngolang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=\ngolang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=\ngolang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=\ngolang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=\ngolang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=\ngolang.org/x/tools v0.0.0-20201020161133-226fd2f889ca/go.mod h1:z6u4i615ZeAfBE4XtMziQW1fSVJXACjjbWkB/mvPzlU=\ngolang.org/x/xerrors v0.0.0-20190410155217-1f06c39b4373/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=\ngolang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=\ngolang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=\ngolang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=\ngolang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=\ngoogle.golang.org/api v0.3.1/go.mod h1:6wY9I6uQWHQ8EM57III9mq/AjF+i8G65rmVagqKMtkk=\ngoogle.golang.org/api v0.3.2/go.mod h1:6wY9I6uQWHQ8EM57III9mq/AjF+i8G65rmVagqKMtkk=\ngoogle.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE=\ngoogle.golang.org/api v0.5.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE=\ngoogle.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M=\ngoogle.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=\ngoogle.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=\ngoogle.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=\ngoogle.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=\ngoogle.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=\ngoogle.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=\ngoogle.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=\ngoogle.golang.org/api v0.19.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=\ngoogle.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=\ngoogle.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=\ngoogle.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE=\ngoogle.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE=\ngoogle.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM=\ngoogle.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc=\ngoogle.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=\ngoogle.golang.org/appengine v1.2.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=\ngoogle.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=\ngoogle.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=\ngoogle.golang.org/appengine v1.6.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=\ngoogle.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0=\ngoogle.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=\ngoogle.golang.org/appengine v1.6.6 h1:lMO5rYAqUxkmaj76jAkRUvt5JZgFymx/+Q5Mzfivuhc=\ngoogle.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=\ngoogle.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=\ngoogle.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=\ngoogle.golang.org/genproto v0.0.0-20190404172233-64821d5d2107/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=\ngoogle.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=\ngoogle.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=\ngoogle.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=\ngoogle.golang.org/genproto v0.0.0-20190508193815-b515fa19cec8/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=\ngoogle.golang.org/genproto v0.0.0-20190522204451-c2c4e71fbf69/go.mod h1:z3L6/3dTEVtUr6QSP8miRzeRqwQOioJ9I66odjN4I7s=\ngoogle.golang.org/genproto v0.0.0-20190530194941-fb225487d101/go.mod h1:z3L6/3dTEVtUr6QSP8miRzeRqwQOioJ9I66odjN4I7s=\ngoogle.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=\ngoogle.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=\ngoogle.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8=\ngoogle.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=\ngoogle.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=\ngoogle.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=\ngoogle.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=\ngoogle.golang.org/genproto v0.0.0-20200115191322-ca5a22157cba/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=\ngoogle.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=\ngoogle.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA=\ngoogle.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=\ngoogle.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=\ngoogle.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=\ngoogle.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=\ngoogle.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=\ngoogle.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=\ngoogle.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=\ngoogle.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=\ngoogle.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U=\ngoogle.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=\ngoogle.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA=\ngoogle.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=\ngoogle.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=\ngoogle.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=\ngoogle.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs=\ngoogle.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=\ngoogle.golang.org/grpc v1.19.1/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=\ngoogle.golang.org/grpc v1.20.0/go.mod h1:chYK+tFQF0nDUGJgXMSgLCQk3phJEuONr2DCgLDdAQM=\ngoogle.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=\ngoogle.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=\ngoogle.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=\ngoogle.golang.org/grpc v1.22.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=\ngoogle.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=\ngoogle.golang.org/grpc v1.23.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=\ngoogle.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=\ngoogle.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=\ngoogle.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=\ngoogle.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=\ngoogle.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60=\ngoogle.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk=\ngoogle.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=\ngoogle.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=\ngoogle.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=\ngoogle.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=\ngoogle.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=\ngoogle.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE=\ngoogle.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=\ngoogle.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=\ngoogle.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=\ngoogle.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=\ngoogle.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4=\ngoogle.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=\ngoogle.golang.org/protobuf v1.26.0-rc.1 h1:7QnIQpGRHE5RnLKnESfDoxm2dTapTZua5a0kS0A+VXQ=\ngoogle.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=\ngopkg.in/alecthomas/kingpin.v2 v2.2.6 h1:jMFz6MfLP0/4fUyZle81rXUoxOBFi19VUFKVDOQfozc=\ngopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=\ngopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=\ngopkg.in/check.v1 v1.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=\ngopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=\ngopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=\ngopkg.in/cheggaaa/pb.v1 v1.0.25/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw=\ngopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=\ngopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=\ngopkg.in/gcfg.v1 v1.2.3/go.mod h1:yesOnuUOFQAhST5vPY4nbZsb/huCgGGXlipJsBn0b3o=\ngopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=\ngopkg.in/ini.v1 v1.51.1/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=\ngopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo=\ngopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=\ngopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI=\ngopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74=\ngopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=\ngopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=\ngopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=\ngopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=\ngopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=\ngopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=\ngopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=\ngopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=\ngopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776 h1:tQIYjPdBoyREyB9XMu+nnTclpTYkz2zFM+lzLJFO4gQ=\ngopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=\nhonnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=\nhonnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=\nhonnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=\nhonnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=\nhonnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=\nhonnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=\nhonnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=\nhonnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=\npack.ag/amqp v0.8.0/go.mod h1:4/cbmt4EJXSKlG6LCfWHoqmN0uFdy5i/+YFz+fTfhV4=\npack.ag/amqp v0.11.0/go.mod h1:4/cbmt4EJXSKlG6LCfWHoqmN0uFdy5i/+YFz+fTfhV4=\nrsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=\nrsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=\nrsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=\nsigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o=\nsourcegraph.com/sourcegraph/appdash v0.0.0-20190731080439-ebfcffb1b5c0/go.mod h1:hI742Nqp5OhwiqlzhgfbWU4mW4yO10fP+LoT9WOswdU=\n"
  },
  {
    "path": ".bingo/misspell.mod",
    "content": "module _ // Auto generated by https://github.com/bwplotka/bingo. DO NOT EDIT\n\ngo 1.14\n\nrequire github.com/client9/misspell v0.3.4 // cmd/misspell\n"
  },
  {
    "path": ".bingo/misspell.sum",
    "content": "github.com/client9/misspell v0.3.4 h1:ta993UF76GwbvJcIo3Y68y/M3WxlpEHPWIGDkJYwzJI=\ngithub.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=\n"
  },
  {
    "path": ".bingo/protoc-gen-go-grpc.mod",
    "content": "module _ // Auto generated by https://github.com/bwplotka/bingo. DO NOT EDIT\n\ngo 1.21\n\nrequire google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.5.1\n"
  },
  {
    "path": ".bingo/protoc-gen-go-grpc.sum",
    "content": "cel.dev/expr v0.15.0/go.mod h1:TRSuuV7DlVCE/uwv5QbAiW/v8l5O8C4eEPHeu7gf7Sg=\ncloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=\ncloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=\ncloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU=\ncloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU=\ncloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY=\ncloud.google.com/go v0.44.3/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY=\ncloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc=\ncloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0=\ncloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To=\ncloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4=\ncloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M=\ncloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc=\ncloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk=\ncloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs=\ncloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc=\ncloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY=\ncloud.google.com/go v0.72.0/go.mod h1:M+5Vjvlc2wnp6tjzE102Dw08nGShTscUx2nZMufOKPI=\ncloud.google.com/go v0.74.0/go.mod h1:VV1xSbzvo+9QJOxLDaJfTjx5e+MePCpCWwvftOeQmWk=\ncloud.google.com/go v0.75.0/go.mod h1:VGuuCn7PG0dwsd5XPVm2Mm3wlh3EL55/79EKB6hlPTY=\ncloud.google.com/go v0.78.0/go.mod h1:QjdrLG0uq+YwhjoVOLsS1t7TW8fs36kLs4XO5R5ECHg=\ncloud.google.com/go v0.79.0/go.mod h1:3bzgcEeQlzbuEAYu4mrWhKqWjmpprinYgKJLgKHnbb8=\ncloud.google.com/go v0.81.0/go.mod h1:mk/AM35KwGk/Nm2YSeZbxXdrNK3KZOYHmLkOqC2V6E0=\ncloud.google.com/go v0.83.0/go.mod h1:Z7MJUsANfY0pYPdw0lbnivPx4/vhy/e2FEkSkF7vAVY=\ncloud.google.com/go v0.84.0/go.mod h1:RazrYuxIK6Kb7YrzzhPoLmCVzl7Sup4NrbKPg8KHSUM=\ncloud.google.com/go v0.87.0/go.mod h1:TpDYlFy7vuLzZMMZ+B6iRiELaY7z/gJPaqbMx6mlWcY=\ncloud.google.com/go v0.90.0/go.mod h1:kRX0mNRHe0e2rC6oNakvwQqzyDmg57xJ+SZU1eT2aDQ=\ncloud.google.com/go v0.93.3/go.mod h1:8utlLll2EF5XMAV15woO4lSbWQlk8rer9aLOfLh7+YI=\ncloud.google.com/go v0.94.1/go.mod h1:qAlAugsXlC+JWO+Bke5vCtc9ONxjQT3drlTTnAplMW4=\ncloud.google.com/go v0.97.0/go.mod h1:GF7l59pYBVlXQIBLx3a761cZ41F9bBH3JUlihCt2Udc=\ncloud.google.com/go v0.99.0/go.mod h1:w0Xx2nLzqWJPuozYQX+hFfCSI8WioryfRDzkoI/Y2ZA=\ncloud.google.com/go v0.100.2/go.mod h1:4Xra9TjzAeYHrl5+oeLlzbM2k3mjVhZh4UqTZ//w99A=\ncloud.google.com/go v0.112.1/go.mod h1:+Vbu+Y1UU+I1rjmzeMOb/8RfkKJK2Gyxi1X6jJCZLo4=\ncloud.google.com/go/accessapproval v1.7.5/go.mod h1:g88i1ok5dvQ9XJsxpUInWWvUBrIZhyPDPbk4T01OoJ0=\ncloud.google.com/go/accesscontextmanager v1.8.5/go.mod h1:TInEhcZ7V9jptGNqN3EzZ5XMhT6ijWxTGjzyETwmL0Q=\ncloud.google.com/go/aiplatform v1.60.0/go.mod h1:eTlGuHOahHprZw3Hio5VKmtThIOak5/qy6pzdsqcQnM=\ncloud.google.com/go/analytics v0.23.0/go.mod h1:YPd7Bvik3WS95KBok2gPXDqQPHy08TsCQG6CdUCb+u0=\ncloud.google.com/go/apigateway v1.6.5/go.mod h1:6wCwvYRckRQogyDDltpANi3zsCDl6kWi0b4Je+w2UiI=\ncloud.google.com/go/apigeeconnect v1.6.5/go.mod h1:MEKm3AiT7s11PqTfKE3KZluZA9O91FNysvd3E6SJ6Ow=\ncloud.google.com/go/apigeeregistry v0.8.3/go.mod h1:aInOWnqF4yMQx8kTjDqHNXjZGh/mxeNlAf52YqtASUs=\ncloud.google.com/go/apikeys v0.6.0/go.mod h1:kbpXu5upyiAlGkKrJgQl8A0rKNNJ7dQ377pdroRSSi8=\ncloud.google.com/go/appengine v1.8.5/go.mod h1:uHBgNoGLTS5di7BvU25NFDuKa82v0qQLjyMJLuPQrVo=\ncloud.google.com/go/area120 v0.8.5/go.mod h1:BcoFCbDLZjsfe4EkCnEq1LKvHSK0Ew/zk5UFu6GMyA0=\ncloud.google.com/go/artifactregistry v1.14.7/go.mod h1:0AUKhzWQzfmeTvT4SjfI4zjot72EMfrkvL9g9aRjnnM=\ncloud.google.com/go/asset v1.17.2/go.mod h1:SVbzde67ehddSoKf5uebOD1sYw8Ab/jD/9EIeWg99q4=\ncloud.google.com/go/assuredworkloads v1.11.5/go.mod h1:FKJ3g3ZvkL2D7qtqIGnDufFkHxwIpNM9vtmhvt+6wqk=\ncloud.google.com/go/automl v1.13.5/go.mod h1:MDw3vLem3yh+SvmSgeYUmUKqyls6NzSumDm9OJ3xJ1Y=\ncloud.google.com/go/baremetalsolution v1.2.4/go.mod h1:BHCmxgpevw9IEryE99HbYEfxXkAEA3hkMJbYYsHtIuY=\ncloud.google.com/go/batch v1.8.0/go.mod h1:k8V7f6VE2Suc0zUM4WtoibNrA6D3dqBpB+++e3vSGYc=\ncloud.google.com/go/beyondcorp v1.0.4/go.mod h1:Gx8/Rk2MxrvWfn4WIhHIG1NV7IBfg14pTKv1+EArVcc=\ncloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o=\ncloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE=\ncloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc=\ncloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg=\ncloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc=\ncloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ=\ncloud.google.com/go/bigquery v1.59.1/go.mod h1:VP1UJYgevyTwsV7desjzNzDND5p6hZB+Z8gZJN1GQUc=\ncloud.google.com/go/billing v1.18.2/go.mod h1:PPIwVsOOQ7xzbADCwNe8nvK776QpfrOAUkvKjCUcpSE=\ncloud.google.com/go/binaryauthorization v1.8.1/go.mod h1:1HVRyBerREA/nhI7yLang4Zn7vfNVA3okoAR9qYQJAQ=\ncloud.google.com/go/certificatemanager v1.7.5/go.mod h1:uX+v7kWqy0Y3NG/ZhNvffh0kuqkKZIXdvlZRO7z0VtM=\ncloud.google.com/go/channel v1.17.5/go.mod h1:FlpaOSINDAXgEext0KMaBq/vwpLMkkPAw9b2mApQeHc=\ncloud.google.com/go/cloudbuild v1.15.1/go.mod h1:gIofXZSu+XD2Uy+qkOrGKEx45zd7s28u/k8f99qKals=\ncloud.google.com/go/clouddms v1.7.4/go.mod h1:RdrVqoFG9RWI5AvZ81SxJ/xvxPdtcRhFotwdE79DieY=\ncloud.google.com/go/cloudtasks v1.12.6/go.mod h1:b7c7fe4+TJsFZfDyzO51F7cjq7HLUlRi/KZQLQjDsaY=\ncloud.google.com/go/compute v0.1.0/go.mod h1:GAesmwr110a34z04OlxYkATPBEfVhkymfTBXtfbBFow=\ncloud.google.com/go/compute v1.3.0/go.mod h1:cCZiE1NHEtai4wiufUhW8I8S1JKkAnhnQJWM7YD99wM=\ncloud.google.com/go/compute v1.5.0/go.mod h1:9SMHyhJlzhlkJqrPAc839t2BZFTSk6Jdj6mkzQJeu0M=\ncloud.google.com/go/compute v1.6.0/go.mod h1:T29tfhtVbq1wvAPo0E3+7vhgmkOYeXjhFvz/FMzPu0s=\ncloud.google.com/go/compute v1.25.1/go.mod h1:oopOIR53ly6viBYxaDhBfJwzUAxf1zE//uf3IB011ls=\ncloud.google.com/go/compute/metadata v0.3.0/go.mod h1:zFmK7XCadkQkj6TtorcaGlCW1hT1fIilQDwofLpJ20k=\ncloud.google.com/go/contactcenterinsights v1.13.0/go.mod h1:ieq5d5EtHsu8vhe2y3amtZ+BE+AQwX5qAy7cpo0POsI=\ncloud.google.com/go/container v1.31.0/go.mod h1:7yABn5s3Iv3lmw7oMmyGbeV6tQj86njcTijkkGuvdZA=\ncloud.google.com/go/containeranalysis v0.11.4/go.mod h1:cVZT7rXYBS9NG1rhQbWL9pWbXCKHWJPYraE8/FTSYPE=\ncloud.google.com/go/datacatalog v1.19.3/go.mod h1:ra8V3UAsciBpJKQ+z9Whkxzxv7jmQg1hfODr3N3YPJ4=\ncloud.google.com/go/dataflow v0.9.5/go.mod h1:udl6oi8pfUHnL0z6UN9Lf9chGqzDMVqcYTcZ1aPnCZQ=\ncloud.google.com/go/dataform v0.9.2/go.mod h1:S8cQUwPNWXo7m/g3DhWHsLBoufRNn9EgFrMgne2j7cI=\ncloud.google.com/go/datafusion v1.7.5/go.mod h1:bYH53Oa5UiqahfbNK9YuYKteeD4RbQSNMx7JF7peGHc=\ncloud.google.com/go/datalabeling v0.8.5/go.mod h1:IABB2lxQnkdUbMnQaOl2prCOfms20mcPxDBm36lps+s=\ncloud.google.com/go/dataplex v1.14.2/go.mod h1:0oGOSFlEKef1cQeAHXy4GZPB/Ife0fz/PxBf+ZymA2U=\ncloud.google.com/go/dataproc v1.12.0/go.mod h1:zrF3aX0uV3ikkMz6z4uBbIKyhRITnxvr4i3IjKsKrw4=\ncloud.google.com/go/dataproc/v2 v2.4.0/go.mod h1:3B1Ht2aRB8VZIteGxQS/iNSJGzt9+CA0WGnDVMEm7Z4=\ncloud.google.com/go/dataqna v0.8.5/go.mod h1:vgihg1mz6n7pb5q2YJF7KlXve6tCglInd6XO0JGOlWM=\ncloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE=\ncloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk=\ncloud.google.com/go/datastore v1.15.0/go.mod h1:GAeStMBIt9bPS7jMJA85kgkpsMkvseWWXiaHya9Jes8=\ncloud.google.com/go/datastream v1.10.4/go.mod h1:7kRxPdxZxhPg3MFeCSulmAJnil8NJGGvSNdn4p1sRZo=\ncloud.google.com/go/deploy v1.17.1/go.mod h1:SXQyfsXrk0fBmgBHRzBjQbZhMfKZ3hMQBw5ym7MN/50=\ncloud.google.com/go/dialogflow v1.49.0/go.mod h1:dhVrXKETtdPlpPhE7+2/k4Z8FRNUp6kMV3EW3oz/fe0=\ncloud.google.com/go/dlp v1.11.2/go.mod h1:9Czi+8Y/FegpWzgSfkRlyz+jwW6Te9Rv26P3UfU/h/w=\ncloud.google.com/go/documentai v1.25.0/go.mod h1:ftLnzw5VcXkLItp6pw1mFic91tMRyfv6hHEY5br4KzY=\ncloud.google.com/go/domains v0.9.5/go.mod h1:dBzlxgepazdFhvG7u23XMhmMKBjrkoUNaw0A8AQB55Y=\ncloud.google.com/go/edgecontainer v1.1.5/go.mod h1:rgcjrba3DEDEQAidT4yuzaKWTbkTI5zAMu3yy6ZWS0M=\ncloud.google.com/go/errorreporting v0.3.0/go.mod h1:xsP2yaAp+OAW4OIm60An2bbLpqIhKXdWR/tawvl7QzU=\ncloud.google.com/go/essentialcontacts v1.6.6/go.mod h1:XbqHJGaiH0v2UvtuucfOzFXN+rpL/aU5BCZLn4DYl1Q=\ncloud.google.com/go/eventarc v1.13.4/go.mod h1:zV5sFVoAa9orc/52Q+OuYUG9xL2IIZTbbuTHC6JSY8s=\ncloud.google.com/go/filestore v1.8.1/go.mod h1:MbN9KcaM47DRTIuLfQhJEsjaocVebNtNQhSLhKCF5GM=\ncloud.google.com/go/firestore v1.14.0/go.mod h1:96MVaHLsEhbvkBEdZgfN+AS/GIkco1LRpH9Xp9YZfzQ=\ncloud.google.com/go/functions v1.16.0/go.mod h1:nbNpfAG7SG7Duw/o1iZ6ohvL7mc6MapWQVpqtM29n8k=\ncloud.google.com/go/gaming v1.10.1/go.mod h1:XQQvtfP8Rb9Rxnxm5wFVpAp9zCQkJi2bLIb7iHGwB3s=\ncloud.google.com/go/gkebackup v1.3.5/go.mod h1:KJ77KkNN7Wm1LdMopOelV6OodM01pMuK2/5Zt1t4Tvc=\ncloud.google.com/go/gkeconnect v0.8.5/go.mod h1:LC/rS7+CuJ5fgIbXv8tCD/mdfnlAadTaUufgOkmijuk=\ncloud.google.com/go/gkehub v0.14.5/go.mod h1:6bzqxM+a+vEH/h8W8ec4OJl4r36laxTs3A/fMNHJ0wA=\ncloud.google.com/go/gkemulticloud v1.1.1/go.mod h1:C+a4vcHlWeEIf45IB5FFR5XGjTeYhF83+AYIpTy4i2Q=\ncloud.google.com/go/grafeas v0.3.4/go.mod h1:A5m316hcG+AulafjAbPKXBO/+I5itU4LOdKO2R/uDIc=\ncloud.google.com/go/gsuiteaddons v1.6.5/go.mod h1:Lo4P2IvO8uZ9W+RaC6s1JVxo42vgy+TX5a6hfBZ0ubs=\ncloud.google.com/go/iam v1.1.6/go.mod h1:O0zxdPeGBoFdWW3HWmBxJsk0pfvNM/p/qa82rWOGTwI=\ncloud.google.com/go/iap v1.9.4/go.mod h1:vO4mSq0xNf/Pu6E5paORLASBwEmphXEjgCFg7aeNu1w=\ncloud.google.com/go/ids v1.4.5/go.mod h1:p0ZnyzjMWxww6d2DvMGnFwCsSxDJM666Iir1bK1UuBo=\ncloud.google.com/go/iot v1.7.5/go.mod h1:nq3/sqTz3HGaWJi1xNiX7F41ThOzpud67vwk0YsSsqs=\ncloud.google.com/go/kms v1.15.7/go.mod h1:ub54lbsa6tDkUwnu4W7Yt1aAIFLnspgh0kPGToDukeI=\ncloud.google.com/go/language v1.12.3/go.mod h1:evFX9wECX6mksEva8RbRnr/4wi/vKGYnAJrTRXU8+f8=\ncloud.google.com/go/lifesciences v0.9.5/go.mod h1:OdBm0n7C0Osh5yZB7j9BXyrMnTRGBJIZonUMxo5CzPw=\ncloud.google.com/go/logging v1.9.0/go.mod h1:1Io0vnZv4onoUnsVUQY3HZ3Igb1nBchky0A0y7BBBhE=\ncloud.google.com/go/longrunning v0.5.5/go.mod h1:WV2LAxD8/rg5Z1cNW6FJ/ZpX4E4VnDnoTk0yawPBB7s=\ncloud.google.com/go/managedidentities v1.6.5/go.mod h1:fkFI2PwwyRQbjLxlm5bQ8SjtObFMW3ChBGNqaMcgZjI=\ncloud.google.com/go/maps v1.6.4/go.mod h1:rhjqRy8NWmDJ53saCfsXQ0LKwBHfi6OSh5wkq6BaMhI=\ncloud.google.com/go/mediatranslation v0.8.5/go.mod h1:y7kTHYIPCIfgyLbKncgqouXJtLsU+26hZhHEEy80fSs=\ncloud.google.com/go/memcache v1.10.5/go.mod h1:/FcblbNd0FdMsx4natdj+2GWzTq+cjZvMa1I+9QsuMA=\ncloud.google.com/go/metastore v1.13.4/go.mod h1:FMv9bvPInEfX9Ac1cVcRXp8EBBQnBcqH6gz3KvJ9BAE=\ncloud.google.com/go/monitoring v1.18.0/go.mod h1:c92vVBCeq/OB4Ioyo+NbN2U7tlg5ZH41PZcdvfc+Lcg=\ncloud.google.com/go/networkconnectivity v1.14.4/go.mod h1:PU12q++/IMnDJAB+3r+tJtuCXCfwfN+C6Niyj6ji1Po=\ncloud.google.com/go/networkmanagement v1.9.4/go.mod h1:daWJAl0KTFytFL7ar33I6R/oNBH8eEOX/rBNHrC/8TA=\ncloud.google.com/go/networksecurity v0.9.5/go.mod h1:KNkjH/RsylSGyyZ8wXpue8xpCEK+bTtvof8SBfIhMG8=\ncloud.google.com/go/notebooks v1.11.3/go.mod h1:0wQyI2dQC3AZyQqWnRsp+yA+kY4gC7ZIVP4Qg3AQcgo=\ncloud.google.com/go/optimization v1.6.3/go.mod h1:8ve3svp3W6NFcAEFr4SfJxrldzhUl4VMUJmhrqVKtYA=\ncloud.google.com/go/orchestration v1.8.5/go.mod h1:C1J7HesE96Ba8/hZ71ISTV2UAat0bwN+pi85ky38Yq8=\ncloud.google.com/go/orgpolicy v1.12.1/go.mod h1:aibX78RDl5pcK3jA8ysDQCFkVxLj3aOQqrbBaUL2V5I=\ncloud.google.com/go/osconfig v1.12.5/go.mod h1:D9QFdxzfjgw3h/+ZaAb5NypM8bhOMqBzgmbhzWViiW8=\ncloud.google.com/go/oslogin v1.13.1/go.mod h1:vS8Sr/jR7QvPWpCjNqy6LYZr5Zs1e8ZGW/KPn9gmhws=\ncloud.google.com/go/phishingprotection v0.8.5/go.mod h1:g1smd68F7mF1hgQPuYn3z8HDbNre8L6Z0b7XMYFmX7I=\ncloud.google.com/go/policytroubleshooter v1.10.3/go.mod h1:+ZqG3agHT7WPb4EBIRqUv4OyIwRTZvsVDHZ8GlZaoxk=\ncloud.google.com/go/privatecatalog v0.9.5/go.mod h1:fVWeBOVe7uj2n3kWRGlUQqR/pOd450J9yZoOECcQqJk=\ncloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I=\ncloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw=\ncloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA=\ncloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU=\ncloud.google.com/go/pubsub v1.36.1/go.mod h1:iYjCa9EzWOoBiTdd4ps7QoMtMln5NwaZQpK1hbRfBDE=\ncloud.google.com/go/pubsublite v1.8.1/go.mod h1:fOLdU4f5xldK4RGJrBMm+J7zMWNj/k4PxwEZXy39QS0=\ncloud.google.com/go/recaptchaenterprise v1.3.1/go.mod h1:OdD+q+y4XGeAlxRaMn1Y7/GveP6zmq76byL6tjPE7d4=\ncloud.google.com/go/recaptchaenterprise/v2 v2.9.2/go.mod h1:trwwGkfhCmp05Ll5MSJPXY7yvnO0p4v3orGANAFHAuU=\ncloud.google.com/go/recommendationengine v0.8.5/go.mod h1:A38rIXHGFvoPvmy6pZLozr0g59NRNREz4cx7F58HAsQ=\ncloud.google.com/go/recommender v1.12.1/go.mod h1:gf95SInWNND5aPas3yjwl0I572dtudMhMIG4ni8nr+0=\ncloud.google.com/go/redis v1.14.2/go.mod h1:g0Lu7RRRz46ENdFKQ2EcQZBAJ2PtJHJLuiiRuEXwyQw=\ncloud.google.com/go/resourcemanager v1.9.5/go.mod h1:hep6KjelHA+ToEjOfO3garMKi/CLYwTqeAw7YiEI9x8=\ncloud.google.com/go/resourcesettings v1.6.5/go.mod h1:WBOIWZraXZOGAgoR4ukNj0o0HiSMO62H9RpFi9WjP9I=\ncloud.google.com/go/retail v1.16.0/go.mod h1:LW7tllVveZo4ReWt68VnldZFWJRzsh9np+01J9dYWzE=\ncloud.google.com/go/run v1.3.4/go.mod h1:FGieuZvQ3tj1e9GnzXqrMABSuir38AJg5xhiYq+SF3o=\ncloud.google.com/go/scheduler v1.10.6/go.mod h1:pe2pNCtJ+R01E06XCDOJs1XvAMbv28ZsQEbqknxGOuE=\ncloud.google.com/go/secretmanager v1.11.5/go.mod h1:eAGv+DaCHkeVyQi0BeXgAHOU0RdrMeZIASKc+S7VqH4=\ncloud.google.com/go/security v1.15.5/go.mod h1:KS6X2eG3ynWjqcIX976fuToN5juVkF6Ra6c7MPnldtc=\ncloud.google.com/go/securitycenter v1.24.4/go.mod h1:PSccin+o1EMYKcFQzz9HMMnZ2r9+7jbc+LvPjXhpwcU=\ncloud.google.com/go/servicecontrol v1.11.1/go.mod h1:aSnNNlwEFBY+PWGQ2DoM0JJ/QUXqV5/ZD9DOLB7SnUk=\ncloud.google.com/go/servicedirectory v1.11.4/go.mod h1:Bz2T9t+/Ehg6x+Y7Ycq5xiShYLD96NfEsWNHyitj1qM=\ncloud.google.com/go/servicemanagement v1.8.0/go.mod h1:MSS2TDlIEQD/fzsSGfCdJItQveu9NXnUniTrq/L8LK4=\ncloud.google.com/go/serviceusage v1.6.0/go.mod h1:R5wwQcbOWsyuOfbP9tGdAnCAc6B9DRwPG1xtWMDeuPA=\ncloud.google.com/go/shell v1.7.5/go.mod h1:hL2++7F47/IfpfTO53KYf1EC+F56k3ThfNEXd4zcuiE=\ncloud.google.com/go/spanner v1.56.0/go.mod h1:DndqtUKQAt3VLuV2Le+9Y3WTnq5cNKrnLb/Piqcj+h0=\ncloud.google.com/go/speech v1.21.1/go.mod h1:E5GHZXYQlkqWQwY5xRSLHw2ci5NMQNG52FfMU1aZrIA=\ncloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw=\ncloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos=\ncloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk=\ncloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs=\ncloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0=\ncloud.google.com/go/storage v1.14.0/go.mod h1:GrKmX003DSIwi9o29oFT7YDnHYwZoctc3fOKtUw0Xmo=\ncloud.google.com/go/storage v1.38.0/go.mod h1:tlUADB0mAb9BgYls9lq+8MGkfzOXuLrnHXlpHmvFJoY=\ncloud.google.com/go/storagetransfer v1.10.4/go.mod h1:vef30rZKu5HSEf/x1tK3WfWrL0XVoUQN/EPDRGPzjZs=\ncloud.google.com/go/talent v1.6.6/go.mod h1:y/WQDKrhVz12WagoarpAIyKKMeKGKHWPoReZ0g8tseQ=\ncloud.google.com/go/texttospeech v1.7.5/go.mod h1:tzpCuNWPwrNJnEa4Pu5taALuZL4QRRLcb+K9pbhXT6M=\ncloud.google.com/go/tpu v1.6.5/go.mod h1:P9DFOEBIBhuEcZhXi+wPoVy/cji+0ICFi4TtTkMHSSs=\ncloud.google.com/go/trace v1.10.5/go.mod h1:9hjCV1nGBCtXbAE4YK7OqJ8pmPYSxPA0I67JwRd5s3M=\ncloud.google.com/go/translate v1.10.1/go.mod h1:adGZcQNom/3ogU65N9UXHOnnSvjPwA/jKQUMnsYXOyk=\ncloud.google.com/go/video v1.20.4/go.mod h1:LyUVjyW+Bwj7dh3UJnUGZfyqjEto9DnrvTe1f/+QrW0=\ncloud.google.com/go/videointelligence v1.11.5/go.mod h1:/PkeQjpRponmOerPeJxNPuxvi12HlW7Em0lJO14FC3I=\ncloud.google.com/go/vision v1.2.0/go.mod h1:SmNwgObm5DpFBme2xpyOyasvBc1aPdjvMk2bBk0tKD0=\ncloud.google.com/go/vision/v2 v2.8.0/go.mod h1:ocqDiA2j97pvgogdyhoxiQp2ZkDCyr0HWpicywGGRhU=\ncloud.google.com/go/vmmigration v1.7.5/go.mod h1:pkvO6huVnVWzkFioxSghZxIGcsstDvYiVCxQ9ZH3eYI=\ncloud.google.com/go/vmwareengine v1.1.1/go.mod h1:nMpdsIVkUrSaX8UvmnBhzVzG7PPvNYc5BszcvIVudYs=\ncloud.google.com/go/vpcaccess v1.7.5/go.mod h1:slc5ZRvvjP78c2dnL7m4l4R9GwL3wDLcpIWz6P/ziig=\ncloud.google.com/go/webrisk v1.9.5/go.mod h1:aako0Fzep1Q714cPEM5E+mtYX8/jsfegAuS8aivxy3U=\ncloud.google.com/go/websecurityscanner v1.6.5/go.mod h1:QR+DWaxAz2pWooylsBF854/Ijvuoa3FCyS1zBa1rAVQ=\ncloud.google.com/go/workflows v1.12.4/go.mod h1:yQ7HUqOkdJK4duVtMeBCAOPiN1ZF1E9pAMX51vpwB/w=\ndmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=\ngioui.org v0.0.0-20210308172011-57750fc8a0a6/go.mod h1:RSH6KIUZ0p2xy5zHDxgAM4zumjgTw83q2ge/PI+yyw8=\ngit.sr.ht/~sbinet/gg v0.3.1/go.mod h1:KGYtlADtqsqANL9ueOFkWymvzUvLMQllU5Ixo+8v3pc=\ngithub.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=\ngithub.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=\ngithub.com/JohnCGriffin/overflow v0.0.0-20211019200055-46fa312c352c/go.mod h1:X0CRv0ky0k6m906ixxpzmDRLvX58TFUKS2eePweuyxk=\ngithub.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=\ngithub.com/ajstarks/deck v0.0.0-20200831202436-30c9fc6549a9/go.mod h1:JynElWSGnm/4RlzPXRlREEwqTHAN3T56Bv2ITsFT3gY=\ngithub.com/ajstarks/deck/generate v0.0.0-20210309230005-c3f852c02e19/go.mod h1:T13YZdzov6OU0A1+RfKZiZN9ca6VeKdBdyDV+BY97Tk=\ngithub.com/ajstarks/svgo v0.0.0-20180226025133-644b8db467af/go.mod h1:K08gAheRH3/J6wwsYMMT4xOr94bZjxIelGM0+d/wbFw=\ngithub.com/ajstarks/svgo v0.0.0-20211024235047-1546f124cd8b/go.mod h1:1KcenG0jGWcpt8ov532z81sp/kMMUG485J2InIOyADM=\ngithub.com/alecthomas/assert/v2 v2.3.0/go.mod h1:pXcQ2Asjp247dahGEmsZ6ru0UVwnkhktn7S0bBDLxvQ=\ngithub.com/alecthomas/participle/v2 v2.1.0/go.mod h1:Y1+hAs8DHPmc3YUFzqllV+eSQ9ljPTk0ZkPMtEdAx2c=\ngithub.com/alecthomas/repr v0.2.0/go.mod h1:Fr0507jx4eOXV7AlPV6AVZLYrLIuIeSOWtW57eE/O/4=\ngithub.com/andybalholm/brotli v1.0.5/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig=\ngithub.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY=\ngithub.com/apache/arrow/go/v10 v10.0.1/go.mod h1:YvhnlEePVnBS4+0z3fhPfUy7W1Ikj0Ih0vcRo/gZ1M0=\ngithub.com/apache/arrow/go/v11 v11.0.0/go.mod h1:Eg5OsL5H+e299f7u5ssuXsuHQVEGC4xei5aX110hRiI=\ngithub.com/apache/arrow/go/v12 v12.0.1/go.mod h1:weuTY7JvTG/HDPtMQxEUp7pU73vkLWMLpY67QwZ/WWw=\ngithub.com/apache/arrow/go/v14 v14.0.2/go.mod h1:u3fgh3EdgN/YQ8cVQRguVW3R+seMybFg8QBQ5LU+eBY=\ngithub.com/apache/thrift v0.17.0/go.mod h1:OLxhMRJxomX+1I/KUw03qoV3mMz16BwaKI+d4fPBx7Q=\ngithub.com/boombuler/barcode v1.0.0/go.mod h1:paBWMcWSl3LHKBqUq+rly7CNSldXjb2rDl3JlRe0mD8=\ngithub.com/boombuler/barcode v1.0.1/go.mod h1:paBWMcWSl3LHKBqUq+rly7CNSldXjb2rDl3JlRe0mD8=\ngithub.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=\ngithub.com/census-instrumentation/opencensus-proto v0.4.1/go.mod h1:4T9NM4+4Vw91VeyqjLS6ao50K5bOcLKN6Q42XnYaRYw=\ngithub.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=\ngithub.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=\ngithub.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=\ngithub.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=\ngithub.com/chzyer/logex v1.2.0/go.mod h1:9+9sk7u7pGNWYMkh0hdiL++6OeibzJccyQU4p4MedaY=\ngithub.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=\ngithub.com/chzyer/readline v1.5.0/go.mod h1:x22KAscuvRqlLoK9CsoYsmxoXZMMFVyOl86cAH8qUic=\ngithub.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=\ngithub.com/chzyer/test v0.0.0-20210722231415-061457976a23/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=\ngithub.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=\ngithub.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=\ngithub.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=\ngithub.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=\ngithub.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4/go.mod h1:6pvJx4me5XPnfI9Z40ddWsdw2W/uZgQLFXToKeRcDiI=\ngithub.com/cncf/udpa/go v0.0.0-20220112060539-c52dc94e7fbe/go.mod h1:6pvJx4me5XPnfI9Z40ddWsdw2W/uZgQLFXToKeRcDiI=\ngithub.com/cncf/xds/go v0.0.0-20210312221358-fbca930ec8ed/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=\ngithub.com/cncf/xds/go v0.0.0-20210805033703-aa0b78936158/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=\ngithub.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=\ngithub.com/cncf/xds/go v0.0.0-20211001041855-01bcc9b48dfe/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=\ngithub.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=\ngithub.com/cncf/xds/go v0.0.0-20240423153145-555b57ec207b/go.mod h1:W+zGtBO5Y1IgJhy4+A9GOqVhqLpfZi+vwmdNXUehLA8=\ngithub.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=\ngithub.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=\ngithub.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=\ngithub.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3ebgob9U8Nd0kOddGdZWjyMGR8Wziv+TBNwSE=\ngithub.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto=\ngithub.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=\ngithub.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=\ngithub.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=\ngithub.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po=\ngithub.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=\ngithub.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=\ngithub.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.mod h1:hliV/p42l8fGbc6Y9bQ70uLwIvmJyVE5k4iMKlh8wCQ=\ngithub.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.mod h1:AFq3mo9L8Lqqiid3OhADV3RfLJnjiw63cSpi+fDTRC0=\ngithub.com/envoyproxy/go-control-plane v0.10.2-0.20220325020618-49ff273808a1/go.mod h1:KJwIaB5Mv44NWtYuAOFCVOjcI94vtpEz2JU/D2v6IjE=\ngithub.com/envoyproxy/go-control-plane v0.12.0/go.mod h1:ZBTaoJ23lqITozF0M6G4/IragXCQKCnYbmlmtHvwRG0=\ngithub.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=\ngithub.com/envoyproxy/protoc-gen-validate v1.0.4/go.mod h1:qys6tmnRsYrQqIhm2bvKZH4Blx/1gTIZ2UKVY1M+Yew=\ngithub.com/fatih/color v1.15.0/go.mod h1:0h5ZqXfHYED7Bhv2ZJamyIOUej9KtShiJESRwBDUSsw=\ngithub.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=\ngithub.com/fogleman/gg v1.2.1-0.20190220221249-0403632d5b90/go.mod h1:R/bRT+9gY/C5z7JzPU0zXsXHKM4/ayA+zqcVNZzPa1k=\ngithub.com/fogleman/gg v1.3.0/go.mod h1:R/bRT+9gY/C5z7JzPU0zXsXHKM4/ayA+zqcVNZzPa1k=\ngithub.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=\ngithub.com/go-fonts/dejavu v0.1.0/go.mod h1:4Wt4I4OU2Nq9asgDCteaAaWZOV24E+0/Pwo0gppep4g=\ngithub.com/go-fonts/latin-modern v0.2.0/go.mod h1:rQVLdDMK+mK1xscDwsqM5J8U2jrRa3T0ecnM9pNujks=\ngithub.com/go-fonts/liberation v0.1.1/go.mod h1:K6qoJYypsmfVjWg8KOVDQhLc8UDgIK2HYqyqAO9z7GY=\ngithub.com/go-fonts/liberation v0.2.0/go.mod h1:K6qoJYypsmfVjWg8KOVDQhLc8UDgIK2HYqyqAO9z7GY=\ngithub.com/go-fonts/stix v0.1.0/go.mod h1:w/c1f0ldAUlJmLBvlbkvVXLAD+tAMqobIIQpmnUIzUY=\ngithub.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=\ngithub.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=\ngithub.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=\ngithub.com/go-latex/latex v0.0.0-20210118124228-b3d85cf34e07/go.mod h1:CO1AlKB2CSIqUrmQPqA0gdRIlnLEY0gK5JGjh37zN5U=\ngithub.com/go-latex/latex v0.0.0-20210823091927-c0d11ff05a81/go.mod h1:SX0U8uGpxhq9o2S/CELCSUxEWWAuoCUcVCQWv7G2OCk=\ngithub.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=\ngithub.com/go-logr/logr v1.4.1/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=\ngithub.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=\ngithub.com/go-pdf/fpdf v0.5.0/go.mod h1:HzcnA+A23uwogo0tp9yU+l3V+KXhiESpt1PMayhOh5M=\ngithub.com/go-pdf/fpdf v0.6.0/go.mod h1:HzcnA+A23uwogo0tp9yU+l3V+KXhiESpt1PMayhOh5M=\ngithub.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=\ngithub.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8=\ngithub.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA=\ngithub.com/go-playground/validator/v10 v10.4.1/go.mod h1:nlOn6nFhuKACm19sB/8EGNn9GlaMV7XkbRSipzJ0Ii4=\ngithub.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=\ngithub.com/goccy/go-yaml v1.11.0/go.mod h1:H+mJrWtjPTJAHvRbV09MCK9xYwODM+wRTVFFTWckfng=\ngithub.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGwJL78qG/PmXZO1EjYhfJinVAhrmmHX6Z8B9k=\ngithub.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=\ngithub.com/golang/glog v1.2.1/go.mod h1:6AhwSGph0fcJtXVM/PEHPqZlFeoLxhs7/t5UDAwmO+w=\ngithub.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=\ngithub.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=\ngithub.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=\ngithub.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=\ngithub.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=\ngithub.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=\ngithub.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y=\ngithub.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=\ngithub.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=\ngithub.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=\ngithub.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4=\ngithub.com/golang/mock v1.5.0/go.mod h1:CWnOUgYIOo4TcNZ0wHX3YZCqsaM1I1Jvs6v3mP3KVu8=\ngithub.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs=\ngithub.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=\ngithub.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=\ngithub.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=\ngithub.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=\ngithub.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=\ngithub.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk=\ngithub.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=\ngithub.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=\ngithub.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs=\ngithub.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w=\ngithub.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=\ngithub.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8=\ngithub.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=\ngithub.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=\ngithub.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=\ngithub.com/golang/protobuf v1.5.1/go.mod h1:DopwsBzvsk0Fs44TXzsVbJyPhcCPeIwnvohx4u74HPM=\ngithub.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=\ngithub.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps=\ngithub.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=\ngithub.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=\ngithub.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=\ngithub.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=\ngithub.com/google/flatbuffers v23.5.26+incompatible/go.mod h1:1AeVuKshWv4vARoZatz6mlQ0JxURH0Kv5+zNeJKJCa8=\ngithub.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=\ngithub.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=\ngithub.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=\ngithub.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=\ngithub.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=\ngithub.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=\ngithub.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=\ngithub.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=\ngithub.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=\ngithub.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=\ngithub.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=\ngithub.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=\ngithub.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE=\ngithub.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=\ngithub.com/google/go-pkcs11 v0.2.1-0.20230907215043-c6f79328ddf9/go.mod h1:6eQoGcuNJpa7jnd5pMGdkSaQpNDYvPlXWMcjXXThLlY=\ngithub.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=\ngithub.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=\ngithub.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=\ngithub.com/google/martian/v3 v3.1.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=\ngithub.com/google/martian/v3 v3.2.1/go.mod h1:oBOf6HBosgwRXnUGWUB05QECsc6uvmMiJ3+6W4l/CUk=\ngithub.com/google/martian/v3 v3.3.2/go.mod h1:oBOf6HBosgwRXnUGWUB05QECsc6uvmMiJ3+6W4l/CUk=\ngithub.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=\ngithub.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=\ngithub.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=\ngithub.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=\ngithub.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=\ngithub.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=\ngithub.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=\ngithub.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=\ngithub.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=\ngithub.com/google/pprof v0.0.0-20201218002935-b9804c9f04c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=\ngithub.com/google/pprof v0.0.0-20210122040257-d980be63207e/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=\ngithub.com/google/pprof v0.0.0-20210226084205-cbba55b83ad5/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=\ngithub.com/google/pprof v0.0.0-20210601050228-01bbb1931b22/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=\ngithub.com/google/pprof v0.0.0-20210609004039-a478d1d731e9/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=\ngithub.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=\ngithub.com/google/pprof v0.0.0-20221118152302-e6195bd50e26/go.mod h1:dDKJzRmX4S37WGHujM7tX//fmj1uioxKzKxz3lo4HJo=\ngithub.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=\ngithub.com/google/s2a-go v0.1.7/go.mod h1:50CgR4k1jNlWBu4UfS4AcfhVe1r6pdZPygJ3R8F0Qdw=\ngithub.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=\ngithub.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=\ngithub.com/googleapis/enterprise-certificate-proxy v0.3.2/go.mod h1:VLSiSSBs/ksPL8kq3OBOQ6WRI2QnaFynd1DCjZ62+V0=\ngithub.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=\ngithub.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=\ngithub.com/googleapis/gax-go/v2 v2.1.0/go.mod h1:Q3nei7sK6ybPYH7twZdmQpAd1MKb7pfu6SK+H1/DsU0=\ngithub.com/googleapis/gax-go/v2 v2.1.1/go.mod h1:hddJymUZASv3XPyGkUpKj8pPO47Rmb0eJc8R6ouapiM=\ngithub.com/googleapis/gax-go/v2 v2.2.0/go.mod h1:as02EH8zWkzwUoLbBaFeQ+arQaj/OthfcblKl4IGNaM=\ngithub.com/googleapis/gax-go/v2 v2.3.0/go.mod h1:b8LNqSzNabLiUpXKkY7HAR5jr6bIT99EXz9pXxye9YM=\ngithub.com/googleapis/gax-go/v2 v2.12.2/go.mod h1:61M8vcyyXR2kqKFxKrfA22jaA8JGF7Dc8App1U3H6jc=\ngithub.com/googleapis/go-type-adapters v1.0.0/go.mod h1:zHW75FOG2aur7gAO2B+MLby+cLsWGBF62rFAi7WjWO4=\ngithub.com/googleapis/google-cloud-go-testing v0.0.0-20200911160855-bcd43fbb19e8/go.mod h1:dvDLG8qkwmyD9a/MJJN3XJcT3xFxOKAvTZGvuZmac9g=\ngithub.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw=\ngithub.com/grpc-ecosystem/grpc-gateway/v2 v2.16.0/go.mod h1:YN5jB8ie0yfIUg6VvR9Kz84aCaG7AsGZnLjhHbUqwPg=\ngithub.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=\ngithub.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=\ngithub.com/hexops/gotextdiff v1.0.3/go.mod h1:pSWU5MAI3yDq+fZBTazCSJysOMbxWL1BSow5/V2vxeg=\ngithub.com/iancoleman/strcase v0.3.0/go.mod h1:iwCmte+B7n89clKwxIoIXy/HfoL7AsD47ZCWhYzw7ho=\ngithub.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=\ngithub.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=\ngithub.com/ianlancetaylor/demangle v0.0.0-20220319035150-800ac71e25c2/go.mod h1:aYm2/VgdVmcIU8iMfdMvDMsRAQjcfZSKFby6HOFvi/w=\ngithub.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=\ngithub.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=\ngithub.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk=\ngithub.com/jung-kurt/gofpdf v1.0.0/go.mod h1:7Id9E/uU8ce6rXgefFLlgrJj/GYY22cpxn+r32jIOes=\ngithub.com/jung-kurt/gofpdf v1.0.3-0.20190309125859-24315acbbda5/go.mod h1:7Id9E/uU8ce6rXgefFLlgrJj/GYY22cpxn+r32jIOes=\ngithub.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51/go.mod h1:CzGEWj7cYgsdH8dAjBGEr58BoE7ScuLd+fwFZ44+/x8=\ngithub.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=\ngithub.com/klauspost/asmfmt v1.3.2/go.mod h1:AG8TuvYojzulgDAMCnYn50l/5QV3Bs/tp6j0HLHbNSE=\ngithub.com/klauspost/compress v1.16.7/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE=\ngithub.com/klauspost/cpuid/v2 v2.2.5/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws=\ngithub.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg=\ngithub.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=\ngithub.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=\ngithub.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=\ngithub.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=\ngithub.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=\ngithub.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=\ngithub.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII=\ngithub.com/lyft/protoc-gen-star v0.6.1/go.mod h1:TGAoBVkt8w7MPG72TrKIu85MIdXwDuzJYeZuUPFPNwA=\ngithub.com/lyft/protoc-gen-star/v2 v2.0.3/go.mod h1:amey7yeodaJhXSbf/TlLvWiqQfLOSpEk//mLlc+axEk=\ngithub.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=\ngithub.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=\ngithub.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=\ngithub.com/mattn/go-sqlite3 v1.14.16/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg=\ngithub.com/minio/asm2plan9s v0.0.0-20200509001527-cdd76441f9d8/go.mod h1:mC1jAcsrzbxHt8iiaC+zU4b1ylILSosueou12R++wfY=\ngithub.com/minio/c2goasm v0.0.0-20190812172519-36a3d3bbc4f3/go.mod h1:RagcQ7I8IeTMnF8JTXieKnO4Z6JCsikNEzj0DwauVzE=\ngithub.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=\ngithub.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=\ngithub.com/phpdave11/gofpdf v1.4.2/go.mod h1:zpO6xFn9yxo3YLyMvW8HcKWVdbNqgIfOOp2dXMnm1mY=\ngithub.com/phpdave11/gofpdi v1.0.12/go.mod h1:vBmVV0Do6hSBHC8uKUQ71JGW+ZGQq74llk/7bXwjDoI=\ngithub.com/phpdave11/gofpdi v1.0.13/go.mod h1:vBmVV0Do6hSBHC8uKUQ71JGW+ZGQq74llk/7bXwjDoI=\ngithub.com/pierrec/lz4/v4 v4.1.18/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4=\ngithub.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA=\ngithub.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=\ngithub.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=\ngithub.com/pkg/sftp v1.10.1/go.mod h1:lYOWFsE0bwd1+KfKJaKeuokY15vzFx25BLbzYYoAxZI=\ngithub.com/pkg/sftp v1.13.1/go.mod h1:3HaPG6Dq1ILlpPZRO0HVMrsydcdLt6HRDccSgb87qRg=\ngithub.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=\ngithub.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=\ngithub.com/prometheus/client_model v0.5.0/go.mod h1:dTiFglRmd66nLR9Pv9f0mZi7B7fk5Pm3gvsjB5tr+kI=\ngithub.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo=\ngithub.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo=\ngithub.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ=\ngithub.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=\ngithub.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs=\ngithub.com/ruudk/golang-pdf417 v0.0.0-20181029194003-1af4ab5afa58/go.mod h1:6lfFZQK844Gfx8o5WFuvpxWRwnSoipWe/p622j1v06w=\ngithub.com/ruudk/golang-pdf417 v0.0.0-20201230142125-a7e3863a1245/go.mod h1:pQAZKsJ8yyVxGRWYNEm9oFB8ieLgKFnamEyDmSA0BRk=\ngithub.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=\ngithub.com/spf13/afero v1.3.3/go.mod h1:5KUK8ByomD5Ti5Artl0RtHeI5pTF7MIDuXL3yY520V4=\ngithub.com/spf13/afero v1.10.0/go.mod h1:UBogFpq8E9Hx+xc5CNTTEpTnuHVmXDwZcZcE1eb/UhQ=\ngithub.com/stoewer/go-strcase v1.3.0/go.mod h1:fAH5hQ5pehh+j3nZfvwdk2RgEgQjAoM8wodgtPmh1xo=\ngithub.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=\ngithub.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=\ngithub.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=\ngithub.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=\ngithub.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=\ngithub.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=\ngithub.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=\ngithub.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=\ngithub.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=\ngithub.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=\ngithub.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=\ngithub.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=\ngithub.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=\ngithub.com/substrait-io/substrait-go v0.4.2/go.mod h1:qhpnLmrcvAnlZsUyPXZRqldiHapPTXC3t7xFgDi3aQg=\ngithub.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=\ngithub.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=\ngithub.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=\ngithub.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=\ngithub.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=\ngithub.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=\ngithub.com/zeebo/assert v1.3.0/go.mod h1:Pq9JiuJQpG8JLJdtkwrJESF0Foym2/D9XMU5ciN/wJ0=\ngithub.com/zeebo/xxh3 v1.0.2/go.mod h1:5NWz9Sef7zIDm2JHfFlcQvNekmcEl9ekUZQQKCYaDcA=\ngo.einride.tech/aip v0.66.0/go.mod h1:qAhMsfT7plxBX+Oy7Huol6YUvZ0ZzdUz26yZsQwfl1M=\ngo.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=\ngo.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8=\ngo.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=\ngo.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=\ngo.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=\ngo.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk=\ngo.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E=\ngo.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo=\ngo.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.49.0/go.mod h1:Mjt1i1INqiaoZOMGR1RIUJN+i3ChKoFRqzrRQhlkbs0=\ngo.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.49.0/go.mod h1:p8pYQP+m5XfbZm9fxtSKAbM6oIllS7s2AfxrChvc7iw=\ngo.opentelemetry.io/otel v1.24.0/go.mod h1:W7b9Ozg4nkF5tWI5zsXkaKKDjdVjpD4oAt9Qi/MArHo=\ngo.opentelemetry.io/otel/metric v1.24.0/go.mod h1:VYhLe1rFfxuTXLgj4CBiyz+9WYBA8pNGJgDcSFRKBco=\ngo.opentelemetry.io/otel/sdk v1.22.0/go.mod h1:iu7luyVGYovrRpe2fmj3CVKouQNdTOkxtLzPvPz1DOc=\ngo.opentelemetry.io/otel/trace v1.24.0/go.mod h1:HPc3Xr/cOApsBI154IU0OI0HJexz+aw5uPdbs3UCjNU=\ngo.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI=\ngo.opentelemetry.io/proto/otlp v1.0.0/go.mod h1:Sy6pihPLfYHkr3NkUbEhGHFhINUSI/v80hjKIs5JXpM=\ngolang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=\ngolang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=\ngolang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=\ngolang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=\ngolang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=\ngolang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=\ngolang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=\ngolang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=\ngolang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=\ngolang.org/x/crypto v0.24.0/go.mod h1:Z1PMYSOR5nyMcyAVAIQSKCDwalqy85Aqn1x3Ws4L5DM=\ngolang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=\ngolang.org/x/exp v0.0.0-20180807140117-3d87b88a115f/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=\ngolang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=\ngolang.org/x/exp v0.0.0-20190125153040-c74c464bbbf2/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=\ngolang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=\ngolang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=\ngolang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek=\ngolang.org/x/exp v0.0.0-20191002040644-a1355ae1e2c3/go.mod h1:NOZ3BPKG0ec/BKJQgnvsSFpcKLM5xXVWnvZS97DWHgE=\ngolang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY=\ngolang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=\ngolang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=\ngolang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=\ngolang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM=\ngolang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU=\ngolang.org/x/exp v0.0.0-20231006140011-7918f672742d/go.mod h1:ldy0pHrwJyGW56pPQzzkH36rKxoZW1tw7ZJpeKx+hdo=\ngolang.org/x/image v0.0.0-20180708004352-c73c2afc3b81/go.mod h1:ux5Hcp/YLpHSI86hEcLt0YII63i6oz57MZXIpbrjZUs=\ngolang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=\ngolang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=\ngolang.org/x/image v0.0.0-20190910094157-69e4b8554b2a/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=\ngolang.org/x/image v0.0.0-20200119044424-58c23975cae1/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=\ngolang.org/x/image v0.0.0-20200430140353-33d19683fad8/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=\ngolang.org/x/image v0.0.0-20200618115811-c13761719519/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=\ngolang.org/x/image v0.0.0-20201208152932-35266b937fa6/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=\ngolang.org/x/image v0.0.0-20210216034530-4410531fe030/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=\ngolang.org/x/image v0.0.0-20210607152325-775e3b0c77b9/go.mod h1:023OzeP/+EPmXeapQh35lcL3II3LrY8Ic+EFFKVhULM=\ngolang.org/x/image v0.0.0-20210628002857-a66eb6448b8d/go.mod h1:023OzeP/+EPmXeapQh35lcL3II3LrY8Ic+EFFKVhULM=\ngolang.org/x/image v0.0.0-20211028202545-6944b10bf410/go.mod h1:023OzeP/+EPmXeapQh35lcL3II3LrY8Ic+EFFKVhULM=\ngolang.org/x/image v0.0.0-20220302094943-723b81ca9867/go.mod h1:023OzeP/+EPmXeapQh35lcL3II3LrY8Ic+EFFKVhULM=\ngolang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=\ngolang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=\ngolang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=\ngolang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=\ngolang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=\ngolang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=\ngolang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=\ngolang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs=\ngolang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=\ngolang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=\ngolang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=\ngolang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=\ngolang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE=\ngolang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o=\ngolang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=\ngolang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY=\ngolang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=\ngolang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=\ngolang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=\ngolang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=\ngolang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=\ngolang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=\ngolang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=\ngolang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=\ngolang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=\ngolang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=\ngolang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=\ngolang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=\ngolang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=\ngolang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=\ngolang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=\ngolang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=\ngolang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=\ngolang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=\ngolang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=\ngolang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=\ngolang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=\ngolang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=\ngolang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=\ngolang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=\ngolang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=\ngolang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=\ngolang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=\ngolang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=\ngolang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=\ngolang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=\ngolang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=\ngolang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=\ngolang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=\ngolang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=\ngolang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=\ngolang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=\ngolang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=\ngolang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=\ngolang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=\ngolang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=\ngolang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=\ngolang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=\ngolang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc=\ngolang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=\ngolang.org/x/net v0.0.0-20210503060351-7fd8e65b6420/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=\ngolang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=\ngolang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=\ngolang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=\ngolang.org/x/net v0.0.0-20220325170049-de3da57026de/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=\ngolang.org/x/net v0.0.0-20220412020605-290c469a71a5/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=\ngolang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=\ngolang.org/x/net v0.26.0/go.mod h1:5YKkiSynbBIh3p6iOc/vibscux0x38BZDkn8sCUPxHE=\ngolang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=\ngolang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=\ngolang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=\ngolang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=\ngolang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=\ngolang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=\ngolang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=\ngolang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=\ngolang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=\ngolang.org/x/oauth2 v0.0.0-20210220000619-9bb904979d93/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=\ngolang.org/x/oauth2 v0.0.0-20210313182246-cd4f82c27b84/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=\ngolang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=\ngolang.org/x/oauth2 v0.0.0-20210628180205-a41e5a781914/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=\ngolang.org/x/oauth2 v0.0.0-20210805134026-6f1e6394065a/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=\ngolang.org/x/oauth2 v0.0.0-20210819190943-2bc19b11175f/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=\ngolang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=\ngolang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc=\ngolang.org/x/oauth2 v0.0.0-20220309155454-6242fa91716a/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc=\ngolang.org/x/oauth2 v0.0.0-20220411215720-9780585627b5/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc=\ngolang.org/x/oauth2 v0.20.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI=\ngolang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=\ngolang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=\ngolang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=\ngolang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20210220050731-9a76102bfb43/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20210225134936-a50acf3fe073/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20210304124612-50617c2ba197/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20210305230114-8fe3ee5dd75b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20210514084401-e8d321eab015/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20210603125802-9665404d3644/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20210823070655-63515b42dcdf/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20210908233432-aa78b53d3365/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20211124211545-fe61309f8881/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20211210111614-af8b64212486/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20220128215802-99c3d69c2c27/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20220209214540-3681064d5158/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20220227234510-4e6760a101f9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20220310020820-b874c991c1a5/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20220328115105-d36c6a25d886/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=\ngolang.org/x/telemetry v0.0.0-20240228155512-f48c80bd79b2/go.mod h1:TeRTkGYfJXctD9OcfyVLyj2J3IxLnKwHJR8f4D8a3YE=\ngolang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=\ngolang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=\ngolang.org/x/term v0.21.0/go.mod h1:ooXLefLobQVslOqselCNF4SxFAaoS6KujMbsGzSDmX0=\ngolang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=\ngolang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=\ngolang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=\ngolang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=\ngolang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=\ngolang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=\ngolang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=\ngolang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=\ngolang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=\ngolang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ=\ngolang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI=\ngolang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=\ngolang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=\ngolang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=\ngolang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=\ngolang.org/x/tools v0.0.0-20180525024113-a5b4c53f6e8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=\ngolang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=\ngolang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=\ngolang.org/x/tools v0.0.0-20190206041539-40960b6deb8e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=\ngolang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=\ngolang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=\ngolang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=\ngolang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=\ngolang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=\ngolang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=\ngolang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=\ngolang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=\ngolang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=\ngolang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=\ngolang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=\ngolang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=\ngolang.org/x/tools v0.0.0-20190927191325-030b2cf1153e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=\ngolang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=\ngolang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=\ngolang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=\ngolang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=\ngolang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=\ngolang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=\ngolang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=\ngolang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=\ngolang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=\ngolang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=\ngolang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=\ngolang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=\ngolang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=\ngolang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=\ngolang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=\ngolang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=\ngolang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw=\ngolang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw=\ngolang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8=\ngolang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=\ngolang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=\ngolang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=\ngolang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=\ngolang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=\ngolang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=\ngolang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=\ngolang.org/x/tools v0.0.0-20200904185747-39188db58858/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE=\ngolang.org/x/tools v0.0.0-20201110124207-079ba7bd75cd/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=\ngolang.org/x/tools v0.0.0-20201201161351-ac6f37ff4c2a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=\ngolang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=\ngolang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=\ngolang.org/x/tools v0.0.0-20210108195828-e2f9c7f1fc8e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=\ngolang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0=\ngolang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=\ngolang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=\ngolang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=\ngolang.org/x/tools v0.1.4/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=\ngolang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=\ngolang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=\ngolang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk=\ngolang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=\ngolang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=\ngolang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=\ngolang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=\ngolang.org/x/xerrors v0.0.0-20220411194840-2f41105eb62f/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=\ngolang.org/x/xerrors v0.0.0-20231012003039-104605ab7028/go.mod h1:NDW/Ps6MPRej6fsCIbMTohpP40sJ/P/vI1MoTEGwX90=\ngonum.org/v1/gonum v0.0.0-20180816165407-929014505bf4/go.mod h1:Y+Yx5eoAFn32cQvJDxZx5Dpnq+c3wtXuadVZAcxbbBo=\ngonum.org/v1/gonum v0.8.2/go.mod h1:oe/vMfY3deqTw+1EZJhuvEW2iwGF1bW9wwu7XCu0+v0=\ngonum.org/v1/gonum v0.9.3/go.mod h1:TZumC3NeyVQskjXqmyWt4S3bINhy7B4eYwW69EbyX+0=\ngonum.org/v1/gonum v0.12.0/go.mod h1:73TDxJfAAHeA8Mk9mf8NlIppyhQNo5GLTcYeqgo2lvY=\ngonum.org/v1/netlib v0.0.0-20190313105609-8cb42192e0e0/go.mod h1:wa6Ws7BG/ESfp6dHfk7C6KdzKA7wR7u/rKwOGE66zvw=\ngonum.org/v1/plot v0.0.0-20190515093506-e2840ee46a6b/go.mod h1:Wt8AAjI+ypCyYX3nZBvf6cAIx93T+c/OS2HFAYskSZc=\ngonum.org/v1/plot v0.9.0/go.mod h1:3Pcqqmp6RHvJI72kgb8fThyUnav364FOsdDo2aGW5lY=\ngonum.org/v1/plot v0.10.1/go.mod h1:VZW5OlhkL1mysU9vaqNHnsy86inf6Ot+jB3r+BczCEo=\ngoogle.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE=\ngoogle.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M=\ngoogle.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=\ngoogle.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=\ngoogle.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=\ngoogle.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=\ngoogle.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=\ngoogle.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=\ngoogle.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=\ngoogle.golang.org/api v0.19.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=\ngoogle.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=\ngoogle.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=\ngoogle.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE=\ngoogle.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE=\ngoogle.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM=\ngoogle.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc=\ngoogle.golang.org/api v0.35.0/go.mod h1:/XrVsuzM0rZmrsbjJutiuftIzeuTQcEeaYcSk/mQ1dg=\ngoogle.golang.org/api v0.36.0/go.mod h1:+z5ficQTmoYpPn8LCUNVpK5I7hwkpjbcgqA7I34qYtE=\ngoogle.golang.org/api v0.40.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjRCQ8=\ngoogle.golang.org/api v0.41.0/go.mod h1:RkxM5lITDfTzmyKFPt+wGrCJbVfniCr2ool8kTBzRTU=\ngoogle.golang.org/api v0.43.0/go.mod h1:nQsDGjRXMo4lvh5hP0TKqF244gqhGcr/YSIykhUk/94=\ngoogle.golang.org/api v0.47.0/go.mod h1:Wbvgpq1HddcWVtzsVLyfLp8lDg6AA241LmgIL59tHXo=\ngoogle.golang.org/api v0.48.0/go.mod h1:71Pr1vy+TAZRPkPs/xlCf5SsU8WjuAWv1Pfjbtukyy4=\ngoogle.golang.org/api v0.50.0/go.mod h1:4bNT5pAuq5ji4SRZm+5QIkjny9JAyVD/3gaSihNefaw=\ngoogle.golang.org/api v0.51.0/go.mod h1:t4HdrdoNgyN5cbEfm7Lum0lcLDLiise1F8qDKX00sOU=\ngoogle.golang.org/api v0.54.0/go.mod h1:7C4bFFOvVDGXjfDTAsgGwDgAxRDeQ4X8NvUedIt6z3k=\ngoogle.golang.org/api v0.55.0/go.mod h1:38yMfeP1kfjsl8isn0tliTjIb1rJXcQi4UXlbqivdVE=\ngoogle.golang.org/api v0.56.0/go.mod h1:38yMfeP1kfjsl8isn0tliTjIb1rJXcQi4UXlbqivdVE=\ngoogle.golang.org/api v0.57.0/go.mod h1:dVPlbZyBo2/OjBpmvNdpn2GRm6rPy75jyU7bmhdrMgI=\ngoogle.golang.org/api v0.61.0/go.mod h1:xQRti5UdCmoCEqFxcz93fTl338AVqDgyaDRuOZ3hg9I=\ngoogle.golang.org/api v0.63.0/go.mod h1:gs4ij2ffTRXwuzzgJl/56BdwJaA194ijkfn++9tDuPo=\ngoogle.golang.org/api v0.67.0/go.mod h1:ShHKP8E60yPsKNw/w8w+VYaj9H6buA5UqDp8dhbQZ6g=\ngoogle.golang.org/api v0.70.0/go.mod h1:Bs4ZM2HGifEvXwd50TtW70ovgJffJYw2oRCOFU/SkfA=\ngoogle.golang.org/api v0.71.0/go.mod h1:4PyU6e6JogV1f9eA4voyrTY2batOLdgZ5qZ5HOCc4j8=\ngoogle.golang.org/api v0.74.0/go.mod h1:ZpfMZOVRMywNyvJFeqL9HRWBgAuRfSjJFpe9QtRRyDs=\ngoogle.golang.org/api v0.77.0/go.mod h1:pU9QmyHLnzlpar1Mjt4IbapUCy8J+6HD6GeELN69ljA=\ngoogle.golang.org/api v0.169.0/go.mod h1:gpNOiMA2tZ4mf5R9Iwf4rK/Dcz0fbdIgWYWVoxmsyLg=\ngoogle.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=\ngoogle.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=\ngoogle.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=\ngoogle.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0=\ngoogle.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=\ngoogle.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=\ngoogle.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=\ngoogle.golang.org/appengine v1.6.8/go.mod h1:1jJ3jBArFh5pcgW8gCtRJnepW8FzD1V44FJffLiz/Ds=\ngoogle.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=\ngoogle.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=\ngoogle.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=\ngoogle.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=\ngoogle.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=\ngoogle.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=\ngoogle.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=\ngoogle.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8=\ngoogle.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=\ngoogle.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=\ngoogle.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=\ngoogle.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=\ngoogle.golang.org/genproto v0.0.0-20200115191322-ca5a22157cba/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=\ngoogle.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=\ngoogle.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA=\ngoogle.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=\ngoogle.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=\ngoogle.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=\ngoogle.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=\ngoogle.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=\ngoogle.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=\ngoogle.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=\ngoogle.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=\ngoogle.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=\ngoogle.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U=\ngoogle.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=\ngoogle.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA=\ngoogle.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=\ngoogle.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=\ngoogle.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=\ngoogle.golang.org/genproto v0.0.0-20200904004341-0bd0a958aa1d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=\ngoogle.golang.org/genproto v0.0.0-20201109203340-2640f1f9cdfb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=\ngoogle.golang.org/genproto v0.0.0-20201201144952-b05cb90ed32e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=\ngoogle.golang.org/genproto v0.0.0-20201210142538-e3217bee35cc/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=\ngoogle.golang.org/genproto v0.0.0-20201214200347-8c77b98c765d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=\ngoogle.golang.org/genproto v0.0.0-20210108203827-ffc7fda8c3d7/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=\ngoogle.golang.org/genproto v0.0.0-20210222152913-aa3ee6e6a81c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=\ngoogle.golang.org/genproto v0.0.0-20210226172003-ab064af71705/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=\ngoogle.golang.org/genproto v0.0.0-20210303154014-9728d6b83eeb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=\ngoogle.golang.org/genproto v0.0.0-20210310155132-4ce2db91004e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=\ngoogle.golang.org/genproto v0.0.0-20210319143718-93e7006c17a6/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=\ngoogle.golang.org/genproto v0.0.0-20210329143202-679c6ae281ee/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A=\ngoogle.golang.org/genproto v0.0.0-20210402141018-6c239bbf2bb1/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A=\ngoogle.golang.org/genproto v0.0.0-20210513213006-bf773b8c8384/go.mod h1:P3QM42oQyzQSnHPnZ/vqoCdDmzH28fzWByN9asMeM8A=\ngoogle.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0=\ngoogle.golang.org/genproto v0.0.0-20210604141403-392c879c8b08/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0=\ngoogle.golang.org/genproto v0.0.0-20210608205507-b6d2f5bf0d7d/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0=\ngoogle.golang.org/genproto v0.0.0-20210624195500-8bfb893ecb84/go.mod h1:SzzZ/N+nwJDaO1kznhnlzqS8ocJICar6hYhVyhi++24=\ngoogle.golang.org/genproto v0.0.0-20210713002101-d411969a0d9a/go.mod h1:AxrInvYm1dci+enl5hChSFPOmmUF1+uAa/UsgNRWd7k=\ngoogle.golang.org/genproto v0.0.0-20210716133855-ce7ef5c701ea/go.mod h1:AxrInvYm1dci+enl5hChSFPOmmUF1+uAa/UsgNRWd7k=\ngoogle.golang.org/genproto v0.0.0-20210728212813-7823e685a01f/go.mod h1:ob2IJxKrgPT52GcgX759i1sleT07tiKowYBGbczaW48=\ngoogle.golang.org/genproto v0.0.0-20210805201207-89edb61ffb67/go.mod h1:ob2IJxKrgPT52GcgX759i1sleT07tiKowYBGbczaW48=\ngoogle.golang.org/genproto v0.0.0-20210813162853-db860fec028c/go.mod h1:cFeNkxwySK631ADgubI+/XFU/xp8FD5KIVV4rj8UC5w=\ngoogle.golang.org/genproto v0.0.0-20210821163610-241b8fcbd6c8/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY=\ngoogle.golang.org/genproto v0.0.0-20210828152312-66f60bf46e71/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY=\ngoogle.golang.org/genproto v0.0.0-20210831024726-fe130286e0e2/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY=\ngoogle.golang.org/genproto v0.0.0-20210903162649-d08c68adba83/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY=\ngoogle.golang.org/genproto v0.0.0-20210909211513-a8c4777a87af/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY=\ngoogle.golang.org/genproto v0.0.0-20210924002016-3dee208752a0/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=\ngoogle.golang.org/genproto v0.0.0-20211118181313-81c1377c94b1/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=\ngoogle.golang.org/genproto v0.0.0-20211206160659-862468c7d6e0/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=\ngoogle.golang.org/genproto v0.0.0-20211208223120-3a66f561d7aa/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=\ngoogle.golang.org/genproto v0.0.0-20211221195035-429b39de9b1c/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=\ngoogle.golang.org/genproto v0.0.0-20220126215142-9970aeb2e350/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=\ngoogle.golang.org/genproto v0.0.0-20220207164111-0872dc986b00/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=\ngoogle.golang.org/genproto v0.0.0-20220218161850-94dd64e39d7c/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI=\ngoogle.golang.org/genproto v0.0.0-20220222213610-43724f9ea8cf/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI=\ngoogle.golang.org/genproto v0.0.0-20220304144024-325a89244dc8/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI=\ngoogle.golang.org/genproto v0.0.0-20220310185008-1973136f34c6/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI=\ngoogle.golang.org/genproto v0.0.0-20220324131243-acbaeb5b85eb/go.mod h1:hAL49I2IFola2sVEjAn7MEwsja0xp51I0tlGAf9hz4E=\ngoogle.golang.org/genproto v0.0.0-20220407144326-9054f6ed7bac/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo=\ngoogle.golang.org/genproto v0.0.0-20220413183235-5e96e2839df9/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo=\ngoogle.golang.org/genproto v0.0.0-20220414192740-2d67ff6cf2b4/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo=\ngoogle.golang.org/genproto v0.0.0-20220502173005-c8bf987b8c21/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4=\ngoogle.golang.org/genproto v0.0.0-20240213162025-012b6fc9bca9/go.mod h1:mqHbVIp48Muh7Ywss/AD6I5kNVKZMmAa/QEW58Gxp2s=\ngoogle.golang.org/genproto/googleapis/api v0.0.0-20240528184218-531527333157/go.mod h1:99sLkeliLXfdj2J75X3Ho+rrVCaJze0uwN7zDDkjPVU=\ngoogle.golang.org/genproto/googleapis/bytestream v0.0.0-20240304161311-37d4d3c04a78/go.mod h1:vh/N7795ftP0AkN1w8XKqN4w1OdUKXW5Eummda+ofv8=\ngoogle.golang.org/genproto/googleapis/rpc v0.0.0-20240604185151-ef581f913117/go.mod h1:EfXuqaE1J41VCDicxHzUDm+8rk+7ZdXzHV0IhO/I6s0=\ngoogle.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=\ngoogle.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=\ngoogle.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=\ngoogle.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=\ngoogle.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=\ngoogle.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=\ngoogle.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=\ngoogle.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=\ngoogle.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60=\ngoogle.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk=\ngoogle.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=\ngoogle.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=\ngoogle.golang.org/grpc v1.31.1/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=\ngoogle.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0=\ngoogle.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc=\ngoogle.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA51WJ8=\ngoogle.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=\ngoogle.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=\ngoogle.golang.org/grpc v1.36.1/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=\ngoogle.golang.org/grpc v1.37.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM=\ngoogle.golang.org/grpc v1.37.1/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM=\ngoogle.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM=\ngoogle.golang.org/grpc v1.39.0/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnDzfrE=\ngoogle.golang.org/grpc v1.39.1/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnDzfrE=\ngoogle.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34=\ngoogle.golang.org/grpc v1.40.1/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34=\ngoogle.golang.org/grpc v1.44.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU=\ngoogle.golang.org/grpc v1.45.0/go.mod h1:lN7owxKUQEqMfSyQikvvk5tf/6zMPsrK+ONuO11+0rQ=\ngoogle.golang.org/grpc v1.46.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk=\ngoogle.golang.org/grpc v1.65.0 h1:bs/cUb4lp1G5iImFFd3u5ixQzweKizoZJAwBNLR42lc=\ngoogle.golang.org/grpc v1.65.0/go.mod h1:WgYC2ypjlB0EiQi6wdKixMqukr6lBc0Vo+oOgjrM5ZQ=\ngoogle.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw=\ngoogle.golang.org/grpc/cmd/protoc-gen-go-grpc v1.5.1 h1:F29+wU6Ee6qgu9TddPgooOdaqsxTMunOoj8KA5yuS5A=\ngoogle.golang.org/grpc/cmd/protoc-gen-go-grpc v1.5.1/go.mod h1:5KF+wpkbTSbGcR9zteSqZV6fqFOWBl4Yde8En8MryZA=\ngoogle.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=\ngoogle.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=\ngoogle.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=\ngoogle.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE=\ngoogle.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=\ngoogle.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=\ngoogle.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=\ngoogle.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=\ngoogle.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4=\ngoogle.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=\ngoogle.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=\ngoogle.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=\ngoogle.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=\ngoogle.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=\ngoogle.golang.org/protobuf v1.34.1 h1:9ddQBjfCyZPOHPUiPxpYESBLc+T8P3E+Vo4IbKZgFWg=\ngoogle.golang.org/protobuf v1.34.1/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos=\ngopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=\ngopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=\ngopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=\ngopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=\ngopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=\ngopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=\ngopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=\ngopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=\ngotest.tools/v3 v3.5.1/go.mod h1:isy3WKz7GK6uNw/sbHzfKBLvlvXwUyV06n6brMxxopU=\nhonnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=\nhonnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=\nhonnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=\nhonnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=\nhonnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=\nhonnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=\nhonnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=\nhonnef.co/go/tools v0.1.3/go.mod h1:NgwopIslSNH47DimFoV78dnkksY2EFtX0ajyb3K/las=\nlukechampine.com/uint128 v1.3.0/go.mod h1:c4eWIwlEGaxC/+H1VguhU4PHXNWDCDMUlWdIWl2j1gk=\nmodernc.org/cc/v3 v3.40.0/go.mod h1:/bTg4dnWkSXowUO6ssQKnOV0yMVxDYNIsIrzqTFDGH0=\nmodernc.org/ccgo/v3 v3.16.13/go.mod h1:2Quk+5YgpImhPjv2Qsob1DnZ/4som1lJTodubIcoUkY=\nmodernc.org/ccorpus v1.11.6/go.mod h1:2gEUTrWqdpH2pXsmTM1ZkjeSrUWDpjMu2T6m29L/ErQ=\nmodernc.org/httpfs v1.0.6/go.mod h1:7dosgurJGp0sPaRanU53W4xZYKh14wfzX420oZADeHM=\nmodernc.org/libc v1.22.4/go.mod h1:jj+Z7dTNX8fBScMVNRAYZ/jF91K8fdT2hYMThc3YjBY=\nmodernc.org/mathutil v1.5.0/go.mod h1:mZW8CKdRPY1v87qxC/wUdX5O1qDzXMP5TH3wjfpga6E=\nmodernc.org/memory v1.5.0/go.mod h1:PkUhL0Mugw21sHPeskwZW4D6VscE/GQJOnIpCnW6pSU=\nmodernc.org/opt v0.1.3/go.mod h1:WdSiB5evDcignE70guQKxYUl14mgWtbClRi5wmkkTX0=\nmodernc.org/sqlite v1.21.2/go.mod h1:cxbLkB5WS32DnQqeH4h4o1B0eMr8W/y8/RGuxQ3JsC0=\nmodernc.org/strutil v1.1.3/go.mod h1:MEHNA7PdEnEwLvspRMtWTNnp2nnyvMfkimT1NKNAGbw=\nmodernc.org/tcl v1.15.1/go.mod h1:aEjeGJX2gz1oWKOLDVZ2tnEWLUrIn8H+GFu+akoDhqs=\nmodernc.org/token v1.1.0/go.mod h1:UGzOrNV1mAFSEB63lOFHIpNRUVMvYTc6yu1SMY/XTDM=\nmodernc.org/z v1.7.0/go.mod h1:hVdgNMh8ggTuRG1rGU8x+xGRFfiQUIAw0ZqlPy8+HyQ=\nrsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=\nrsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4=\nrsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=\nrsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=\n"
  },
  {
    "path": ".bingo/protoc-gen-go.mod",
    "content": "module _ // Auto generated by https://github.com/bwplotka/bingo. DO NOT EDIT\n\ngo 1.22\n\nrequire google.golang.org/protobuf v1.36.6 // cmd/protoc-gen-go\n"
  },
  {
    "path": ".bingo/protoc-gen-go.sum",
    "content": "github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=\ngithub.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=\ngolang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=\ngoogle.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=\ngoogle.golang.org/protobuf v1.36.6 h1:z1NpPI8ku2WgiWnf+t9wTPsn6eP1L7ksHUlkfLvd9xY=\ngoogle.golang.org/protobuf v1.36.6/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY=\n"
  },
  {
    "path": ".bingo/variables.env",
    "content": "# Auto generated binary variables helper managed by https://github.com/bwplotka/bingo v0.9. DO NOT EDIT.\n# All tools are designed to be build inside $GOBIN.\n# Those variables will work only until 'bingo get' was invoked, or if tools were installed via Makefile's Variables.mk.\nGOBIN=${GOBIN:=$(go env GOBIN)}\n\nif [ -z \"$GOBIN\" ]; then\n\tGOBIN=\"$(go env GOPATH)/bin\"\nfi\n\n\nBINGO=\"${GOBIN}/bingo-v0.9.0\"\n\nBUF=\"${GOBIN}/buf-v1.55.1\"\n\nCOPYRIGHT=\"${GOBIN}/copyright-v0.0.0-20210326193628-425a09c04e05\"\n\nGOIMPORTS=\"${GOBIN}/goimports-v0.7.0\"\n\nGOLANGCI_LINT=\"${GOBIN}/golangci-lint-v2.3.0\"\n\nMDOX=\"${GOBIN}/mdox-v0.9.0\"\n\nMISSPELL=\"${GOBIN}/misspell-v0.3.4\"\n\nPROTOC_GEN_GO_GRPC=\"${GOBIN}/protoc-gen-go-grpc-v1.5.1\"\n\nPROTOC_GEN_GO=\"${GOBIN}/protoc-gen-go-v1.36.6\"\n\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE.md",
    "content": "<!--\nTemplate relevant to bug reports only!\n\nKeep issue title verbose enough.\n-->\n\n**Go version used**:\n\n**What happened**:\n\n**What you expected to happen**:\n\n**How to reproduce it (as minimally and precisely as possible)**:\n\n-->\n"
  },
  {
    "path": ".github/PULL_REQUEST_TEMPLATE.md",
    "content": "<!--\n    Keep PR title verbose enough.\n-->\n\n## Changes\n\n<!-- Enumerate changes you made -->\n\n## Verification\n\n<!-- How you tested it? How do you know it works? -->\n"
  },
  {
    "path": ".github/dependabot.yml",
    "content": "# See https://docs.github.com/en/github/administering-a-repository/configuration-options-for-dependency-updates#package-ecosystem\nversion: 2\nupdates:\n  - package-ecosystem: github-actions\n    directory: /\n    schedule:\n      interval: weekly\n    groups:\n      actions:\n        patterns:\n          - \"*\"\n  - package-ecosystem: gomod\n    directories:\n      - /\n      - /interceptors/logging/examples\n      - /providers/prometheus\n      - /examples\n    schedule:\n      interval: weekly\n    groups:\n      go:\n        patterns:\n          - \"*\"\n        applies-to: \"version-updates\"\n      go-security:\n        patterns:\n          - \"*\"\n        applies-to: \"security-updates\"\n"
  },
  {
    "path": ".github/stale.yml",
    "content": "# Configuration for probot-stale - https://github.com/probot/stale\n\n# Only issues or pull requests with all of these labels are check if stale. Defaults to `[]` (disabled)\nonlyLabels: []\n\n# Issues or Pull Requests with these labels will never be considered stale. Set to `[]` to disable.\n# We want stale bot to notify us that something is stale so we can revisit it.\n# If one issue is marked as 'reminder' by the reminder bot, we don't mark it as 'stale' again.\nexemptLabels:\n  # This label is hardcoded on remind bot (https://probot.github.io/apps/reminders/) and is used by remind bot when\n  # issue is being reminded.\n  - reminder\n\n# Set to true to ignore issues in a project (defaults to false)\nexemptProjects: false\n# Set to true to ignore issues in a milestone (defaults to false)\nexemptMilestones: false\n# Set to true to ignore issues with an assignee (defaults to false)\nexemptAssignees: false\n# Label to use when marking as stale\nstaleLabel: stale\n\npull:\n  daysUntilClose: 14\n  daysUntilStale: 30\n  markComment: >\n    Hello 👋 Looks like there was no activity on this amazing PR for the last month.\n\n    **Do you mind updating us on the status?** Is there anything we can help with? If you plan to still work on it, just comment on this PR or push a commit. Thanks! 🤗\n\n    If there is no activity for the next 2 weeks, this PR will be closed (we can always reopen a PR if you get back to this!).\n  #unmarkComment: No need for unmark comment.\n  closeComment: >\n    Closing for now as promised, let us know if you need this to be reopened! 🤗\n\nissues:\n  daysUntilClose: 14\n  daysUntilStale: 60\n  markComment: >\n    Hello 👋 Looks like there was no activity on this issue for the last 2 months.\n\n    **Do you mind updating us on the status?** Is this still reproducible or needed? If yes, just comment on this PR or push a commit. Thanks! 🤗\n\n    If there is no activity for the next 2 weeks, this issue will be closed (we can always reopen an issue if requested!).\n  #unmarkComment: No need for unmark comment.\n  closeComment: >\n    Closing for now as promised, let us know if you need this to be reopened! 🤗\n\n# Limit the number of actions per hour, from 1-30. Default is 30\nlimitPerRun: 30\n"
  },
  {
    "path": ".github/workflows/go.yaml",
    "content": "name: go\n\non:\n  push:\n    branches:\n      - v2\n  pull_request:\n\njobs:\n  lint:\n    runs-on: ubuntu-latest\n    name: Linters (Static Analysis) for Go\n    steps:\n      - name: Checkout code into the Go module directory.\n        uses: actions/checkout@v5\n\n      - name: Install Go\n        uses: actions/setup-go@v6\n        with:\n          go-version: stable\n          cache-dependency-path: \"**/go.sum\"\n\n      - name: Linting & vetting.\n        run: make lint\n\n  tests:\n    runs-on: ${{ matrix.platform }}\n    name: Unit tests on Go ${{ matrix.go }} / ${{ matrix.platform }}\n    strategy:\n      fail-fast: false\n      matrix:\n        go: [\"oldstable\", \"stable\"]\n        platform: [ubuntu-latest, macos-latest]\n    steps:\n      - name: Checkout code into the Go module directory.\n        uses: actions/checkout@v5\n\n      - name: Install Go\n        uses: actions/setup-go@v6\n        with:\n          go-version: ${{ matrix.go }}\n          cache-dependency-path: \"**/go.sum\"\n\n      - name: Run unit tests.\n        run: make test\n"
  },
  {
    "path": ".gitignore",
    "content": "# Created by .ignore support plugin (hsz.mobi)\n### Go template\n# Compiled Object files, Static and Dynamic libs (Shared Objects)\n*.o\n*.a\n*.so\n\n# Folders\n_obj\n_test\n\n# Architecture specific extensions/prefixes\n*.[568vq]\n[568vq].out\n\n*.cgo1.go\n*.cgo2.c\n_cgo_defun.c\n_cgo_gotypes.go\n_cgo_export.*\n\n_testmain.go\n\n*.exe\n*.test\n*.prof\n### Windows template\n# Windows image file caches\nThumbs.db\nehthumbs.db\n\n# Folder config file\nDesktop.ini\n\n# Recycle Bin used on file shares\n$RECYCLE.BIN/\n\n# Windows Installer files\n*.cab\n*.msi\n*.msm\n*.msp\n\n# Windows shortcuts\n*.lnk\n### Kate template\n# Swap Files #\n.*.kate-swp\n.swp.*\n### SublimeText template\n# cache files for sublime text\n*.tmlanguage.cache\n*.tmPreferences.cache\n*.stTheme.cache\n\n# workspace files are user-specific\n*.sublime-workspace\n\n# project files should be checked into the repository, unless a significant\n# proportion of contributors will probably not be using SublimeText\n# *.sublime-project\n\n# sftp configuration file\nsftp-config.json\n### Linux template\n*~\n\n# temporary files which can be created if a process still has a handle open of a deleted file\n.fuse_hidden*\n\n# KDE directory preferences\n.directory\n\n# Linux trash folder which might appear on any partition or disk\n.Trash-*\n### JetBrains template\n# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and Webstorm\n# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839\n\n# User-specific stuff:\n.idea\n.idea/tasks.xml\n.idea/dictionaries\n.idea/vcs.xml\n.idea/jsLibraryMappings.xml\n\n# Sensitive or high-churn files:\n.idea/dataSources.ids\n.idea/dataSources.xml\n.idea/dataSources.local.xml\n.idea/sqlDataSources.xml\n.idea/dynamic.xml\n.idea/uiDesigner.xml\n\n# Gradle:\n.idea/gradle.xml\n.idea/libraries\n\n# Mongo Explorer plugin:\n.idea/mongoSettings.xml\n\n## File-based project format:\n*.iws\n\n## Plugin-specific files:\n\n# IntelliJ\n/out/\n\n# mpeltonen/sbt-idea plugin\n.idea_modules/\n\n# JIRA plugin\natlassian-ide-plugin.xml\n\n# Crashlytics plugin (for Android Studio and IntelliJ)\ncom_crashlytics_export_strings.xml\ncrashlytics.properties\ncrashlytics-build.properties\nfabric.properties\n### Xcode template\n# Xcode\n#\n# gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore\n\n## Build generated\nbuild/\nDerivedData/\n\n## Various settings\n*.pbxuser\n!default.pbxuser\n*.mode1v3\n!default.mode1v3\n*.mode2v3\n!default.mode2v3\n*.perspectivev3\n!default.perspectivev3\nxcuserdata/\n\n## Other\n*.moved-aside\n*.xccheckout\n*.xcscmblueprint\n### Eclipse template\n\n.metadata\nbin/\ntmp/\n*.tmp\n*.bak\n*.swp\n*~.nib\nlocal.properties\n.settings/\n.loadpath\n.recommenders\n\n# Eclipse Core\n.project\n\n# External tool builders\n.externalToolBuilders/\n\n# Locally stored \"Eclipse launch configurations\"\n*.launch\n\n# PyDev specific (Python IDE for Eclipse)\n*.pydevproject\n\n# CDT-specific (C/C++ Development Tooling)\n.cproject\n\n# JDT-specific (Eclipse Java Development Tools)\n.classpath\n\n# Java annotation processor (APT)\n.factorypath\n\n# PDT-specific (PHP Development Tools)\n.buildpath\n\n# sbteclipse plugin\n.target\n\n# Tern plugin\n.tern-project\n\n# TeXlipse plugin\n.texlipse\n\n# STS (Spring Tool Suite)\n.springBeans\n\n# Code Recommenders\n.recommenders/\n\n\ncoverage.txt\n\n#vendor\nvendor/\n\n.envrc\n.bin"
  },
  {
    "path": ".golangci.yml",
    "content": "---\nversion: \"2\"\n\nrun:\n  timeout: 5m\n\nlinters:\n  enable:\n    - contextcheck\n    - errcheck\n    - errorlint\n    - fatcontext\n    - gocritic\n    - govet\n    - misspell\n    - promlinter\n    - testifylint\n    - usestdlibvars\n    - usetesting\n\n  settings:\n    errcheck:\n      exclude-functions:\n        - (github.com/go-kit/log.Logger).Log\n\n    gocritic:\n      disabled-checks:\n        - appendAssign\n        - builtinShadow\n        - deferInLoop\n        - exitAfterDefer\n        - importShadow\n        - unnamedResult\n      enable-all: true\n\n    govet:\n      disable:\n        - fieldalignment\n      enable-all: true\n\n    promlinter:\n      strict: true\n\n    testifylint:\n      disable:\n        - go-require\n      enable-all: true\n      suite-extra-assert-call:\n        mode: \"require\"\n\n  exclusions:\n    presets:\n      - comments\n      - common-false-positives\n      - legacy\n      - std-error-handling\n\nformatters:\n  enable:\n    - gofumpt\n    - goimports\n\n  settings:\n    gofumpt:\n      extra-rules: true\n\nissues:\n  # Maximum issues count per one linter.\n  max-issues-per-linter: 0\n  # Maximum count of issues with the same text.\n  max-same-issues: 0\n"
  },
  {
    "path": "CONTRIBUTING.md",
    "content": "# Contributing\n\nWe would love to have people submit pull requests and help make `grpc-ecosystem/go-grpc-middleware` even better 👍.\n\nFork, then clone the repo:\n\n```bash\ngit clone git@github.com:your-username/go-grpc-middleware.git\n```\n\nBefore submitting a patch, please make sure to run the following make commands to execute the formatting check, regenerate the proto files, and run the tests and linters:\n\n```powershell\nmake fmt : Run formatting across all go files\n\nmake proto : Generate proto files\n\nmake test : Run all the tests\n\nmake lint : Run linting across all go files\n```\n\nOne command to rule them all:\n\n```bash\nmake all\n```\n\nThis will `lint`, `fmt`, regenerate proto files and documentation and run all tests.\n\nPush to your fork and open a pull request.\n"
  },
  {
    "path": "COPYRIGHT",
    "content": "Copyright (c) The go-grpc-middleware Authors.\nLicensed under the Apache License 2.0.\n"
  },
  {
    "path": "LICENSE",
    "content": "                 Apache License\n                           Version 2.0, January 2004\n                        http://www.apache.org/licenses/\n\n   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n   1. Definitions.\n\n      \"License\" shall mean the terms and conditions for use, reproduction,\n      and distribution as defined by Sections 1 through 9 of this document.\n\n      \"Licensor\" shall mean the copyright owner or entity authorized by\n      the copyright owner that is granting the License.\n\n      \"Legal Entity\" shall mean the union of the acting entity and all\n      other entities that control, are controlled by, or are under common\n      control with that entity. For the purposes of this definition,\n      \"control\" means (i) the power, direct or indirect, to cause the\n      direction or management of such entity, whether by contract or\n      otherwise, or (ii) ownership of fifty percent (50%) or more of the\n      outstanding shares, or (iii) beneficial ownership of such entity.\n\n      \"You\" (or \"Your\") shall mean an individual or Legal Entity\n      exercising permissions granted by this License.\n\n      \"Source\" form shall mean the preferred form for making modifications,\n      including but not limited to software source code, documentation\n      source, and configuration files.\n\n      \"Object\" form shall mean any form resulting from mechanical\n      transformation or translation of a Source form, including but\n      not limited to compiled object code, generated documentation,\n      and conversions to other media types.\n\n      \"Work\" shall mean the work of authorship, whether in Source or\n      Object form, made available under the License, as indicated by a\n      copyright notice that is included in or attached to the work\n      (an example is provided in the Appendix below).\n\n      \"Derivative Works\" shall mean any work, whether in Source or Object\n      form, that is based on (or derived from) the Work and for which the\n      editorial revisions, annotations, elaborations, or other modifications\n      represent, as a whole, an original work of authorship. For the purposes\n      of this License, Derivative Works shall not include works that remain\n      separable from, or merely link (or bind by name) to the interfaces of,\n      the Work and Derivative Works thereof.\n\n      \"Contribution\" shall mean any work of authorship, including\n      the original version of the Work and any modifications or additions\n      to that Work or Derivative Works thereof, that is intentionally\n      submitted to Licensor for inclusion in the Work by the copyright owner\n      or by an individual or Legal Entity authorized to submit on behalf of\n      the copyright owner. For the purposes of this definition, \"submitted\"\n      means any form of electronic, verbal, or written communication sent\n      to the Licensor or its representatives, including but not limited to\n      communication on electronic mailing lists, source code control systems,\n      and issue tracking systems that are managed by, or on behalf of, the\n      Licensor for the purpose of discussing and improving the Work, but\n      excluding communication that is conspicuously marked or otherwise\n      designated in writing by the copyright owner as \"Not a Contribution.\"\n\n      \"Contributor\" shall mean Licensor and any individual or Legal Entity\n      on behalf of whom a Contribution has been received by Licensor and\n      subsequently incorporated within the Work.\n\n   2. Grant of Copyright License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      copyright license to reproduce, prepare Derivative Works of,\n      publicly display, publicly perform, sublicense, and distribute the\n      Work and such Derivative Works in Source or Object form.\n\n   3. Grant of Patent License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      (except as stated in this section) patent license to make, have made,\n      use, offer to sell, sell, import, and otherwise transfer the Work,\n      where such license applies only to those patent claims licensable\n      by such Contributor that are necessarily infringed by their\n      Contribution(s) alone or by combination of their Contribution(s)\n      with the Work to which such Contribution(s) was submitted. If You\n      institute patent litigation against any entity (including a\n      cross-claim or counterclaim in a lawsuit) alleging that the Work\n      or a Contribution incorporated within the Work constitutes direct\n      or contributory patent infringement, then any patent licenses\n      granted to You under this License for that Work shall terminate\n      as of the date such litigation is filed.\n\n   4. Redistribution. You may reproduce and distribute copies of the\n      Work or Derivative Works thereof in any medium, with or without\n      modifications, and in Source or Object form, provided that You\n      meet the following conditions:\n\n      (a) You must give any other recipients of the Work or\n          Derivative Works a copy of this License; and\n\n      (b) You must cause any modified files to carry prominent notices\n          stating that You changed the files; and\n\n      (c) You must retain, in the Source form of any Derivative Works\n          that You distribute, all copyright, patent, trademark, and\n          attribution notices from the Source form of the Work,\n          excluding those notices that do not pertain to any part of\n          the Derivative Works; and\n\n      (d) If the Work includes a \"NOTICE\" text file as part of its\n          distribution, then any Derivative Works that You distribute must\n          include a readable copy of the attribution notices contained\n          within such NOTICE file, excluding those notices that do not\n          pertain to any part of the Derivative Works, in at least one\n          of the following places: within a NOTICE text file distributed\n          as part of the Derivative Works; within the Source form or\n          documentation, if provided along with the Derivative Works; or,\n          within a display generated by the Derivative Works, if and\n          wherever such third-party notices normally appear. The contents\n          of the NOTICE file are for informational purposes only and\n          do not modify the License. You may add Your own attribution\n          notices within Derivative Works that You distribute, alongside\n          or as an addendum to the NOTICE text from the Work, provided\n          that such additional attribution notices cannot be construed\n          as modifying the License.\n\n      You may add Your own copyright statement to Your modifications and\n      may provide additional or different license terms and conditions\n      for use, reproduction, or distribution of Your modifications, or\n      for any such Derivative Works as a whole, provided Your use,\n      reproduction, and distribution of the Work otherwise complies with\n      the conditions stated in this License.\n\n   5. Submission of Contributions. Unless You explicitly state otherwise,\n      any Contribution intentionally submitted for inclusion in the Work\n      by You to the Licensor shall be under the terms and conditions of\n      this License, without any additional terms or conditions.\n      Notwithstanding the above, nothing herein shall supersede or modify\n      the terms of any separate license agreement you may have executed\n      with Licensor regarding such Contributions.\n\n   6. Trademarks. This License does not grant permission to use the trade\n      names, trademarks, service marks, or product names of the Licensor,\n      except as required for reasonable and customary use in describing the\n      origin of the Work and reproducing the content of the NOTICE file.\n\n   7. Disclaimer of Warranty. Unless required by applicable law or\n      agreed to in writing, Licensor provides the Work (and each\n      Contributor provides its Contributions) on an \"AS IS\" BASIS,\n      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n      implied, including, without limitation, any warranties or conditions\n      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n      PARTICULAR PURPOSE. You are solely responsible for determining the\n      appropriateness of using or redistributing the Work and assume any\n      risks associated with Your exercise of permissions under this License.\n\n   8. Limitation of Liability. In no event and under no legal theory,\n      whether in tort (including negligence), contract, or otherwise,\n      unless required by applicable law (such as deliberate and grossly\n      negligent acts) or agreed to in writing, shall any Contributor be\n      liable to You for damages, including any direct, indirect, special,\n      incidental, or consequential damages of any character arising as a\n      result of this License or out of the use or inability to use the\n      Work (including but not limited to damages for loss of goodwill,\n      work stoppage, computer failure or malfunction, or any and all\n      other commercial damages or losses), even if such Contributor\n      has been advised of the possibility of such damages.\n\n   9. Accepting Warranty or Additional Liability. While redistributing\n      the Work or Derivative Works thereof, You may choose to offer,\n      and charge a fee for, acceptance of support, warranty, indemnity,\n      or other liability obligations and/or rights consistent with this\n      License. However, in accepting such obligations, You may act only\n      on Your own behalf and on Your sole responsibility, not on behalf\n      of any other Contributor, and only if You agree to indemnify,\n      defend, and hold each Contributor harmless for any liability\n      incurred by, or claims asserted against, such Contributor by reason\n      of your accepting any such warranty or additional liability.\n\n   END OF TERMS AND CONDITIONS\n\n   APPENDIX: How to apply the Apache License to your work.\n\n      To apply the Apache License to your work, attach the following\n      boilerplate notice, with the fields enclosed by brackets \"[]\"\n      replaced with your own identifying information. (Don't include\n      the brackets!)  The text should be enclosed in the appropriate\n      comment syntax for the file format. We also recommend that a\n      file or class name and description of purpose be included on the\n      same \"printed page\" as the copyright notice for easier\n      identification within third-party archives.\n\n   Copyright [yyyy] [name of copyright owner]\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at\n\n       http://www.apache.org/licenses/LICENSE-2.0\n\n   Unless required by applicable law or agreed to in writing, software\n   distributed under the License is distributed on an \"AS IS\" BASIS,\n   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n   See the License for the specific language governing permissions and\n   limitations under the License."
  },
  {
    "path": "Makefile",
    "content": "include .bingo/Variables.mk\n\nSHELL=/usr/bin/env bash\n\nPROVIDER_MODULES ?= $(shell find $(PWD)/providers/  -name \"go.mod\" | grep -v \".bingo\" | xargs dirname)\nMODULES          ?= $(PROVIDER_MODULES) $(PWD) $(PWD)/examples\nGO_FILES_TO_FMT  ?= $(shell find . -path -prune -o -name '*.go' -print)\n\nGOBIN             ?= $(firstword $(subst :, ,${GOPATH}))/bin\n\nTMP_GOPATH        ?= /tmp/gopath\n\nGO111MODULE       ?= on\nexport GO111MODULE\nGOPROXY           ?= https://proxy.golang.org\nexport GOPROXY\n\ndefine require_clean_work_tree\n\t@git update-index -q --ignore-submodules --refresh\n\n    @if ! git diff-files --quiet --ignore-submodules --; then \\\n        echo >&2 \"cannot $1: you have unstaged changes.\"; \\\n        git diff-files --name-status -r --ignore-submodules -- >&2; \\\n        echo >&2 \"Please commit or stash them.\"; \\\n        exit 1; \\\n    fi\n\n    @if ! git diff-index --cached --quiet HEAD --ignore-submodules --; then \\\n        echo >&2 \"cannot $1: your index contains uncommitted changes.\"; \\\n        git diff-index --cached --name-status -r --ignore-submodules HEAD -- >&2; \\\n        echo >&2 \"Please commit or stash them.\"; \\\n        exit 1; \\\n    fi\n\nendef\n\nall: fmt proto lint test\n\n.PHONY: fmt\nfmt: $(GOIMPORTS)\n\t@echo \">> formatting go code\"\n\t@gofmt -s -w $(GO_FILES_TO_FMT)\n\t@for file in $(GO_FILES_TO_FMT) ; do \\\n\t\t./goimports.sh \"$${file}\"; \\\n\tdone\n\t@$(GOIMPORTS) -w $(GO_FILES_TO_FMT)\n\n.PHONY: test\ntest:\n\tgo test ./...\n\n.PHONY: deps\ndeps:\n\t@echo \"Running deps tidy for all modules: $(MODULES)\"\n\tfor dir in $(MODULES) ; do \\\n\t\techo \"$${dir}\"; \\\n\t\tcd $${dir} && go mod tidy; \\\n\tdone\n\n.PHONY: docs\ndocs: $(MDOX) ## Generates code snippets, doc formatting and check links.\n\t@echo \">> generating docs $(PATH)\"\n\t@$(MDOX) fmt -l --links.validate.config-file=$(MDOX_VALIDATE_CONFIG) *.md\n\n.PHONY: check-docs\ncheck-docs: $(MDOX) ## Generates code snippets and doc formatting and checks links.\n\t@echo \">> checking docs $(PATH)\"\n\t@$(MDOX) fmt --check -l --links.validate.config-file=$(MDOX_VALIDATE_CONFIG) *.md\n\n.PHONY: tidy_module_%\ntidy_module_%:\n\t@echo \">> running go mod tidy in $*\"\n\t@cd $* && go mod tidy\n\t@$(call require_clean_work_tree,\"tidy go.mod in $*\")\n\n.PHONY: lint\n# PROTIP:\n# Add\n#      --cpu-profile-path string   Path to CPU profile output file\n#      --mem-profile-path string   Path to memory profile output file\n# to debug big allocations during linting.\nlint: ## Runs various static analysis tools against our code.\nlint: $(BUF) $(COPYRIGHT) fmt docs\n\t@echo \">> lint proto files\"\n\t@$(BUF) lint\n\n\t@echo \">> ensuring copyright headers\"\n\t@$(COPYRIGHT) $(shell go list -f \"{{.Dir}}\" ./... | xargs -i find \"{}\" -name \"*.go\")\n\t@$(call require_clean_work_tree,\"set copyright headers\")\n\t@echo \">> ensured all .go files have copyright headers\"\n\n\t@echo \"Running lint for all modules: $(MODULES)\"\n\t@$(call require_clean_work_tree,\"before lint\")\n\t$(MAKE) $(MODULES:%=lint_module_%)\n\t@$(call require_clean_work_tree,\"lint and format files\")\n\n.PHONY: lint_module_%\n# PROTIP:\n# Add\n#      --cpu-profile-path string   Path to CPU profile output file\n#      --mem-profile-path string   Path to memory profile output file\n# to debug big allocations during linting.\nlint_module_%: tidy_module_% ## Runs various static analysis against our code.\n$(MODULES:%=lint_module_%): lint_module_%: $(GOLANGCI_LINT) $(MISSPELL)\n\n\t@echo \">> examining all of the Go files\"\n\t@cd $* && go vet -stdmethods=false ./...\n\n\t@echo \">> linting all of the Go files GOGC=${GOGC}\"\n\t@cd $* && $(GOLANGCI_LINT) run\n\t@$(call require_clean_work_tree,\"golangci lint\")\n\n\n# For protoc naming matters.\nPROTOC_GEN_GO_CURRENT := $(TMP_GOPATH)/protoc-gen-go\nPROTOC_GEN_GO_GRPC_CURRENT := $(TMP_GOPATH)/protoc-gen-go-grpc\nPROTO_TEST_DIR := testing/testpb/v1\n\n.PHONY: proto\nproto: ## Generate testing protobufs\nproto: $(BUF) $(PROTOC_GEN_GO) $(PROTOC_GEN_GO_GRPC) $(PROTO_TEST_DIR)/test.proto\n\t@mkdir -p $(TMP_GOPATH)\n\t@cp $(PROTOC_GEN_GO) $(PROTOC_GEN_GO_CURRENT)\n\t@cp $(PROTOC_GEN_GO_GRPC) $(PROTOC_GEN_GO_GRPC_CURRENT)\n\t@echo \">> generating $(PROTO_TEST_DIR)\"\n\t@PATH=$(GOBIN):$(TMP_GOPATH) $(BUF) alpha protoc \\\n\t\t-I $(PROTO_TEST_DIR) \\\n\t\t--go_out=$(PROTO_TEST_DIR)/../ \\\n\t\t--go-grpc_out=$(PROTO_TEST_DIR)/../ \\\n\t    $(PROTO_TEST_DIR)/*.proto\n\n.PHONY: buf.gen\nbuf.gen:\n\t@$(BUF) generate \\\n           --template ./testing/testvalidate/testvalidate.buf.gen.yaml \\\n           --path ./testing/testvalidate/v1\n"
  },
  {
    "path": "README.md",
    "content": "# Go gRPC Middleware\n\n[![go](https://github.com/grpc-ecosystem/go-grpc-middleware/workflows/go/badge.svg?branch=v2)](https://github.com/grpc-ecosystem/go-grpc-middleware/actions?query=branch%3Av2) [![Go Report Card](https://goreportcard.com/badge/github.com/grpc-ecosystem/go-grpc-middleware)](https://goreportcard.com/report/github.com/grpc-ecosystem/go-grpc-middleware) [![GoDoc](http://img.shields.io/badge/GoDoc-Reference-blue.svg)](https://godoc.org/github.com/grpc-ecosystem/go-grpc-middleware/v2) [![Apache 2.0 License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](LICENSE) [![Slack](https://img.shields.io/badge/slack-%23grpc--middleware-brightgreen)](https://gophers.slack.com/archives/CNJL30P4P)\n\nThis repository holds [gRPC Go](https://github.com/grpc/grpc-go) Middlewares: interceptors, helpers and utilities.\n\n## Middleware\n\n[gRPC Go](https://github.com/grpc/grpc-go) has support for \"interceptors\", i.e. [middleware](https://medium.com/@matryer/writing-middleware-in-golang-and-how-go-makes-it-so-much-fun-4375c1246e81#.gv7tdlghs) that is executed either on the gRPC Server before the request is passed onto the user's application logic, or on the gRPC client either around the user call. It is a perfect way to implement common patterns: auth, logging, tracing, metrics, validation, retries, rate limiting and more, which can be a great generic building blocks that make it easy to build multiple microservices easily.\n\nEspecially for observability signals (logging, tracing, metrics) interceptors offers semi-auto-instrumentation that improves consistency of your observability and allows great correlation techniques (e.g. exemplars and trace ID in logs). Demo-ed in [examples](examples).\n\nThis repository offers ready-to-use middlewares that implements gRPC interceptors with examples. In some cases dedicated projects offer great interceptors, so this repository skips those, and we link them in the [interceptors](#interceptors) list.\n\n> NOTE: Some middlewares are quite simple to write, so feel free to use this repo as template if you need. It's ok to copy some simpler interceptors if you need more flexibility. This repo can't support all the edge cases you might have.\n\nAdditional great feature of interceptors is the fact we can chain those. For example below you can find example server side chain of interceptors with full observabiliy correlation, auth and panic recovery:\n\n```go mdox-exec=\"sed -n '143,163p' examples/server/main.go\"\n\tgrpcSrv := grpc.NewServer(\n\t\tgrpc.StatsHandler(otelgrpc.NewServerHandler()),\n\t\tgrpc.ChainUnaryInterceptor(\n\t\t\tsrvMetrics.UnaryServerInterceptor(\n\t\t\t\tgrpcprom.WithExemplarFromContext(exemplarFromContext),\n\t\t\t\tgrpcprom.WithLabelsFromContext(labelsFromContext),\n\t\t\t),\n\t\t\tlogging.UnaryServerInterceptor(interceptorLogger(rpcLogger), logging.WithFieldsFromContext(logTraceID)),\n\t\t\tselector.UnaryServerInterceptor(auth.UnaryServerInterceptor(authFn), selector.MatchFunc(allButHealthZ)),\n\t\t\trecovery.UnaryServerInterceptor(recovery.WithRecoveryHandler(grpcPanicRecoveryHandler)),\n\t\t),\n\t\tgrpc.ChainStreamInterceptor(\n\t\t\tsrvMetrics.StreamServerInterceptor(\n\t\t\t\tgrpcprom.WithExemplarFromContext(exemplarFromContext),\n\t\t\t\tgrpcprom.WithLabelsFromContext(labelsFromContext),\n\t\t\t),\n\t\t\tlogging.StreamServerInterceptor(interceptorLogger(rpcLogger), logging.WithFieldsFromContext(logTraceID)),\n\t\t\tselector.StreamServerInterceptor(auth.StreamServerInterceptor(authFn), selector.MatchFunc(allButHealthZ)),\n\t\t\trecovery.StreamServerInterceptor(recovery.WithRecoveryHandler(grpcPanicRecoveryHandler)),\n\t\t),\n\t)\n```\n\nThis pattern offers clean and explicit shared functionality for all your gRPC methods. Full, buildable examples can be found in [examples](examples) directory.\n\n## Interceptors\n\nThis list covers known interceptors that users use for their Go microservices (both in this repo and external). Click on each to see extended examples in `examples_test.go` (also available in [pkg.go.dev](https://godoc.org/github.com/grpc-ecosystem/go-grpc-middleware/v2))\n\nAll paths should work with `go get <path>`.\n\n#### Auth\n\n- [`github.com/grpc-ecosystem/go-grpc-middleware/v2/interceptors/auth`](interceptors/auth) - a customizable via `AuthFunc` piece of auth middleware.\n- (external) [`google.golang.org/grpc/authz`](https://github.com/grpc/grpc-go/blob/master/authz/grpc_authz_server_interceptors.go) - more complex, customizable via auth polices (RBAC like), piece of auth middleware.\n\n#### Observability\n\n- Metrics:\n  - [`github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus`⚡](providers/prometheus) - Prometheus client-side and server-side monitoring middleware. Supports exemplars. Moved from deprecated now [`go-grpc-prometheus`](https://github.com/grpc-ecosystem/go-grpc-prometheus).\n  - (external) [`go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc`](https://go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc) - official OpenTelemetry interceptors (metric and tracing).\n- Logging with [`github.com/grpc-ecosystem/go-grpc-middleware/v2/interceptors/logging`](interceptors/logging) - a customizable logging middleware offering extended per request logging. It requires logging adapter, see examples in [`interceptors/logging/examples`](interceptors/logging/examples) for `go-kit`, `log`, `logr`, `logrus`, `slog`, `zap` and `zerolog`.\n  - NOTE: Interceptors with [context](https://pkg.go.dev/context) field injections need to be chained before the adapter function.\n- Tracing:\n  - (external) [`go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc`](https://go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc) - official OpenTelemetry interceptors (metric and tracing) as used in [example](examples).\n  - (external) [`github.com/grpc-ecosystem/go-grpc-middleware/tracing/opentracing`](https://pkg.go.dev/github.com/grpc-ecosystem/go-grpc-middleware@v1.4.0/tracing/opentracing) - deprecated [OpenTracing](http://opentracing.io/) client-side and server-side interceptors if you still need it!\n\n#### Client\n\n- [`github.com/grpc-ecosystem/go-grpc-middleware/v2/interceptors/retry`](interceptors/retry) - a generic gRPC response code retry mechanism, client-side middleware.\n  - NOTE: grpc-go has native retries too with advanced policies (https://github.com/grpc/grpc-go/blob/v1.54.0/examples/features/retry/client/main.go)\n- [`github.com/grpc-ecosystem/go-grpc-middleware/v2/interceptors/timeout`](interceptors/timeout) - a generic gRPC request timeout, client-side middleware.\n\n#### Server\n\n- [`github.com/grpc-ecosystem/go-grpc-middleware/v2/interceptors/validator`](interceptors/validator) - codegen inbound message validation from `.proto` options.\n- [`github.com/grpc-ecosystem/go-grpc-middleware/v2/interceptors/recovery`](interceptors/recovery) - turn panics into gRPC errors (make sure to use those as \"last\" interceptor, so panic does not skip other interceptors).\n- [`github.com/grpc-ecosystem/go-grpc-middleware/v2/interceptors/ratelimit`](interceptors/ratelimit) - grpc rate limiting by your own limiter.\n- [`github.com/grpc-ecosystem/go-grpc-middleware/v2/interceptors/protovalidate`](interceptors/protovalidate) - message validation from `.proto` options via [protovalidate-go](https://github.com/bufbuild/protovalidate)\n\n#### Filtering Interceptor\n\n- [`github.com/grpc-ecosystem/go-grpc-middleware/v2/interceptors/selector`](interceptors/selector) - allow users to select given one or more interceptors in certain condition like matching service method.\n\n## Prerequisites\n\n- **[Go](https://golang.org)**: Any one of the **three latest major** [releases](https://golang.org/doc/devel/release.html) are supported.\n\n## Structure of this repository\n\nThe main interceptors are available in the subdirectories of the [`interceptors` directory](interceptors) e.g. [`interceptors/validator`](interceptors/validator), [`interceptors/auth`](interceptors/auth) or [`interceptors/logging`](interceptors/logging).\n\nSome interceptors or utilities of interceptors requires opinionated code that depends on larger amount of dependencies. Those are places in `providers` directory as separate Go module, with separate versioning. For example [`providers/prometheus`](providers/prometheus) offer metrics middleware (there is no \"interceptor/metrics\" at the moment). The separate module, might be a little bit harder to discover and version in your `go.mod`, but it allows core interceptors to be ultra slim in terms of dependencies.\n\nThe [`interceptors` directory](interceptors) also holds generic interceptors that accepts [`Reporter`](interceptors/reporter.go) interface which allows creating your own middlewares with ease.\n\nAs you might notice this repository contains multiple modules with different versions ([Go Module specifics](https://github.com/golang/go/wiki/Modules#faqs--multi-module-repositories)). Refer to [versions.yaml](versions.yaml) for current modules. We have main module of version 2.x.y and providers modules of lower versions. Since main module is v2, it's module path ends with `v2`:\n\n```\ngo get github.com/grpc-ecosystem/go-grpc-middleware/v2/<package>\n```\n\nFor providers modules and packages, since they are v1, no version is added to the path e.g.\n\n```\ngo get github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus\n```\n\n## Changes compared to v1\n\n[go-grpc-middleware v1](https://pkg.go.dev/github.com/grpc-ecosystem/go-grpc-middleware) was created near 2015 and became a popular choice for gRPC users. However, many have changed since then. The main changes of v2 compared to v1:\n\n- Path for separate, multiple Go modules in \"providers\". This allows to add in future specific providers for certain middlewares if needed. This allows interceptors to be extended without the dependency hell to the core framework (e.g. if use some other metric provider, do you want to import prometheus?). This allows greater extensibility.\n- Loggers are removed. The [`interceptors/logging`](interceptors/logging) got simplified and writing adapter for each logger is straightforward. For convenience, we will maintain examples for popular providers in [`interceptors/logging/examples`](interceptors/logging/examples), but those are meant to be copied, not imported.\n- `grpc_opentracing` interceptor was removed. This is because tracing instrumentation evolved. OpenTracing is deprecated and OpenTelemetry has now a [superior tracing interceptor](https://go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc).\n- `grpc_ctxtags` interceptor was removed. Custom tags can be added to logging fields using `logging.InjectFields`. Proto option to add logging field was clunky in practice and we don't see any use of it nowadays, so it's removed.\n- One of the most powerful interceptor was imported from https://github.com/grpc-ecosystem/go-grpc-prometheus (repo is now deprecated). This consolidation allows easier maintenance, easier use and consistent API.\n- Chain interceptors was removed, because `grpc` implemented one.\n- Moved to the new proto API (google.golang.org/protobuf).\n- All \"deciders\", so functions that decide what to do based on gRPC service name and method (aka \"fullMethodName\") are removed (!). Use [`github.com/grpc-ecosystem/go-grpc-middleware/v2/interceptors/selector`](interceptors/selector) interceptor to select what method, type or service should use what interceptor.\n- No more snake case package names. We have now single word meaningful package names. If you have collision in package names we recommend adding grpc prefix e.g. `grpcprom \"github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus\"`.\n- All the options (if any) are in the form of `<package_name>.With<Option Name>`, with extensibility to add more of them.\n- `v2` is the main (default) development branch.\n\n## For Maintainers: Release Process\n\nThis assumes we want to release minor version of any module:\n\n1. Understand what has been change and what groups within [versions](versions.yaml) has to be updated.\n2. Update group version on v2 branch accordingly.\n3. Create new tag for *each module* that has to be released. For the main module `github.com/grpc-ecosystem/go-grpc-middleware/v2` the tag has no prefix (e.g. v2.20.1). For providers (sub modules), the tag version has to have form e.g. `providers/<provider/v1.2.3`. See https://github.com/golang/go/wiki/Modules#faqs--multi-module-repositories for details.\n4. Once all tags are pushed, draft and create release on GitHub page, mentioning all changed tags in the title. Use auto-generation of notes and remove those that are not relevant for users (e.g. fixing docs).\n\n## License\n\n`go-grpc-middleware` is released under the Apache 2.0 license. See the [LICENSE](LICENSE) file for details.\n"
  },
  {
    "path": "buf.yaml",
    "content": "version: v2\ndeps:\n  - buf.build/bufbuild/protovalidate:v0.14.2\nlint:\n  use:\n    - STANDARD\n  except:\n    - ENUM_FIRST_VALUE_ZERO\n    - FIELD_NOT_REQUIRED\n    - IMPORT_USED\n    - PACKAGE_NO_IMPORT_CYCLE\n    - PROTOVALIDATE\n    - SYNTAX_SPECIFIED\n  disallow_comment_ignores: true\nbreaking:\n  except:\n    - EXTENSION_NO_DELETE\n    - FIELD_SAME_DEFAULT\n"
  },
  {
    "path": "doc.go",
    "content": "// Copyright (c) The go-grpc-middleware Authors.\n// Licensed under the Apache License 2.0.\n\n/*\nPackage middleware\n\n`middleware` is a collection of gRPC middleware packages: interceptors, helpers and tools.\n\n# Middleware\n\ngRPC is a fantastic RPC middleware, which sees a lot of adoption in the Golang world. However, the\nupstream gRPC codebase is relatively bare bones.\n\nThis package, and most of its child packages provides commonly needed middleware for gRPC:\nclient-side interceptors for retires, server-side interceptors for input validation and auth,\nfunctions for chaining said interceptors, metadata convenience methods and more.\n\n# Chaining\n\nSimple way of turning a multiple interceptors into a single interceptor. Here's an example for\nserver chaining:\n\n\tmyServer := grpc.NewServer(\n\t    grpc.ChainStreamInterceptor(loggingStream, monitoringStream, authStream),\n\t    grpc.ChainUnaryInterceptor(loggingUnary, monitoringUnary, authUnary),\n\t)\n\nThese interceptors will be executed from left to right: logging, monitoring and auth.\n\nHere's an example for client side chaining:\n\n\tclientConn, err = grpc.Dial(\n\t    address,\n\t        grpc.WithChainUnaryInterceptor(monitoringClientUnary, retryUnary),\n\t        grpc.WithChainStreamInterceptor(monitoringClientStream, retryStream),\n\t)\n\tclient = testpb.NewTestServiceClient(clientConn)\n\tresp, err := client.PingEmpty(s.ctx, &myservice.Request{Msg: \"hello\"})\n\nThese interceptors will be executed from left to right: monitoring and then retry logic.\n\nThe retry interceptor will call every interceptor that follows it whenever when a retry happens.\n\n# Writing Your Own\n\nImplementing your own interceptor is pretty trivial: there are interfaces for that. But the interesting\nbit exposing common data to handlers (and other middleware), similarly to HTTP Middleware design.\nFor example, you may want to pass the identity of the caller from the auth interceptor all the way\nto the handling function.\n\nFor example, a client side interceptor example for auth looks like:\n\n\tfunc FakeAuthUnaryInterceptor(ctx context.Context, req any, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (any, error) {\n\t   newCtx := context.WithValue(ctx, \"user_id\", \"john@example.com\")\n\t   return handler(newCtx, req)\n\t}\n\nUnfortunately, it's not as easy for streaming RPCs. These have the `context.Context` embedded within\nthe `grpc.ServerStream` object. To pass values through context, a wrapper (`WrappedServerStream`) is\nneeded. For example:\n\n\tfunc FakeAuthStreamingInterceptor(srv any, stream grpc.ServerStream, info *grpc.StreamServerInfo, handler grpc.StreamHandler) error {\n\t   newStream := middleware.WrapServerStream(stream)\n\t   newStream.WrappedContext = context.WithValue(ctx, \"user_id\", \"john@example.com\")\n\t   return handler(srv, newStream)\n\t}\n*/\npackage middleware\n"
  },
  {
    "path": "examples/README.md",
    "content": "# Example Go app instrumented with go-grpc-middleware\n\nThis directory has server and client application communicating using [testpb.PingService](../testing/testpb/v1/test.proto) gRPC service.\nBoth are instrumented with example interceptors for auth, observability correlation, timeouts and more.\n\nFeel free to copy and play with it.\n\n## Usage\n\n1. Run server in one terminal:\n\n    ```\n    go run server/main.go\n    ```\n\n2. Run client in second terminal:\n    \n    ```\n    go run client/main.go\n    ```\n   \n3. You should see logs and tracing in the output of both terminals thanks to logging and otlpgrpc interceptors. To check metrics instrumented with prometheus interceptor you can curl OpenMetrics (so exemplars are included):\n\n    For server metrics:\n    ```\n    curl http://localhost:8081/metrics -H 'Accept: application/openmetrics-text; version=0.0.1'\n    ```\n   \n    For client metrics:\n    ```\n    curl http://localhost:8082/metrics -H 'Accept: application/openmetrics-text; version=0.0.1'\n    ```\n"
  },
  {
    "path": "examples/client/main.go",
    "content": "// Copyright (c) The go-grpc-middleware Authors.\n// Licensed under the Apache License 2.0.\n\npackage main\n\nimport (\n\t\"context\"\n\t\"log/slog\"\n\t\"net/http\"\n\t\"os\"\n\t\"syscall\"\n\t\"time\"\n\n\tgrpcprom \"github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus\"\n\t\"github.com/grpc-ecosystem/go-grpc-middleware/v2/interceptors/logging\"\n\t\"github.com/grpc-ecosystem/go-grpc-middleware/v2/interceptors/timeout\"\n\t\"github.com/grpc-ecosystem/go-grpc-middleware/v2/metadata\"\n\t\"github.com/grpc-ecosystem/go-grpc-middleware/v2/testing/testpb\"\n\t\"github.com/oklog/run\"\n\t\"github.com/prometheus/client_golang/prometheus\"\n\t\"github.com/prometheus/client_golang/prometheus/promhttp\"\n\t\"go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc\"\n\t\"go.opentelemetry.io/otel\"\n\tstdout \"go.opentelemetry.io/otel/exporters/stdout/stdouttrace\"\n\t\"go.opentelemetry.io/otel/propagation\"\n\tsdktrace \"go.opentelemetry.io/otel/sdk/trace\"\n\t\"go.opentelemetry.io/otel/trace\"\n\t\"google.golang.org/grpc\"\n\t\"google.golang.org/grpc/credentials/insecure\"\n\tgrpcMetadata \"google.golang.org/grpc/metadata\"\n)\n\nconst (\n\tcomponent      = \"grpc-example\"\n\thttpAddr       = \":8082\"\n\ttargetGRPCAddr = \"localhost:8080\"\n)\n\n// interceptorLogger adapts slog logger to interceptor logger.\n// This code is simple enough to be copied and not imported.\nfunc interceptorLogger(l *slog.Logger) logging.Logger {\n\treturn logging.LoggerFunc(func(ctx context.Context, lvl logging.Level, msg string, fields ...any) {\n\t\tl.Log(ctx, slog.Level(lvl), msg, fields...)\n\t})\n}\n\nfunc main() {\n\t// Setup logging.\n\tlogger := slog.New(slog.NewTextHandler(os.Stderr, &slog.HandlerOptions{}))\n\trpcLogger := logger.With(\"service\", \"gRPC/client\", \"component\", component)\n\tlogTraceID := func(ctx context.Context) logging.Fields {\n\t\tif span := trace.SpanContextFromContext(ctx); span.IsSampled() {\n\t\t\treturn logging.Fields{\"traceID\", span.TraceID().String()}\n\t\t}\n\t\treturn nil\n\t}\n\n\t// Setup metrics.\n\treg := prometheus.NewRegistry()\n\tclMetrics := grpcprom.NewClientMetrics(\n\t\tgrpcprom.WithClientHandlingTimeHistogram(\n\t\t\tgrpcprom.WithHistogramBuckets([]float64{0.001, 0.01, 0.1, 0.3, 0.6, 1, 3, 6, 9, 20, 30, 60, 90, 120}),\n\t\t),\n\t\t// Add user_id as a context label. This user option is necessary\n\t\t// to initialize the metrics with the labels that will be provided\n\t\t// dynamically from the context. This should be used in tandem with\n\t\t// WithLabelsFromContext in the interceptor options.\n\t\tgrpcprom.WithClientContextLabels(\"user_id\"),\n\t)\n\treg.MustRegister(clMetrics)\n\texemplarFromContext := func(ctx context.Context) prometheus.Labels {\n\t\tif span := trace.SpanContextFromContext(ctx); span.IsSampled() {\n\t\t\treturn prometheus.Labels{\"traceID\": span.TraceID().String()}\n\t\t}\n\t\treturn nil\n\t}\n\n\t// Extract the user id value from gRPC metadata\n\t// and use it as a label on our metrics.\n\tlabelsFromContext := func(ctx context.Context) prometheus.Labels {\n\t\tlabels := prometheus.Labels{}\n\n\t\tmd := metadata.ExtractOutgoing(ctx)\n\t\tuserID := md.Get(\"user-id\")\n\t\tif userID == \"\" {\n\t\t\tuserID = \"unknown\"\n\t\t}\n\t\tlabels[\"user_id\"] = userID\n\n\t\treturn labels\n\t}\n\n\t// Set up OTLP tracing (stdout for debug).\n\texporter, err := stdout.New(stdout.WithPrettyPrint())\n\tif err != nil {\n\t\tlogger.Error(\"failed to init exporter\", \"err\", err)\n\t\tos.Exit(1)\n\t}\n\ttp := sdktrace.NewTracerProvider(\n\t\tsdktrace.WithSampler(sdktrace.AlwaysSample()),\n\t\tsdktrace.WithBatcher(exporter),\n\t)\n\totel.SetTracerProvider(tp)\n\totel.SetTextMapPropagator(propagation.NewCompositeTextMapPropagator(propagation.TraceContext{}, propagation.Baggage{}))\n\tdefer func() { _ = exporter.Shutdown(context.Background()) }()\n\n\tcc, err := grpc.NewClient(\n\t\ttargetGRPCAddr,\n\t\tgrpc.WithTransportCredentials(insecure.NewCredentials()),\n\t\tgrpc.WithStatsHandler(otelgrpc.NewClientHandler()),\n\t\tgrpc.WithChainUnaryInterceptor(\n\t\t\ttimeout.UnaryClientInterceptor(500*time.Millisecond),\n\t\t\tclMetrics.UnaryClientInterceptor(\n\t\t\t\tgrpcprom.WithExemplarFromContext(exemplarFromContext),\n\t\t\t\tgrpcprom.WithLabelsFromContext(labelsFromContext),\n\t\t\t),\n\t\t\tlogging.UnaryClientInterceptor(interceptorLogger(rpcLogger), logging.WithFieldsFromContext(logTraceID))),\n\t\tgrpc.WithChainStreamInterceptor(\n\t\t\tclMetrics.StreamClientInterceptor(\n\t\t\t\tgrpcprom.WithExemplarFromContext(exemplarFromContext),\n\t\t\t\tgrpcprom.WithLabelsFromContext(labelsFromContext),\n\t\t\t),\n\t\t\tlogging.StreamClientInterceptor(interceptorLogger(rpcLogger), logging.WithFieldsFromContext(logTraceID))),\n\t)\n\tif err != nil {\n\t\tlogger.Error(\"failed to init gRPC client\", \"err\", err)\n\t\tos.Exit(1)\n\t}\n\n\tcl := testpb.NewTestServiceClient(cc)\n\n\tg := &run.Group{}\n\tctx, cancel := context.WithCancel(context.Background())\n\tg.Add(func() error {\n\t\tfor {\n\t\t\tselect {\n\t\t\tcase <-ctx.Done():\n\t\t\t\treturn nil\n\t\t\tcase <-time.After(1 * time.Second):\n\t\t\t}\n\n\t\t\tmd := grpcMetadata.Pairs(\n\t\t\t\t\"authorization\", \"bearer yolo\",\n\t\t\t\t\"user-id\", \"admin\",\n\t\t\t)\n\t\t\tif _, err := cl.Ping(metadata.MD(md).ToOutgoing(ctx), &testpb.PingRequest{Value: \"example\"}); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t}\n\t}, func(err error) {\n\t\tcancel()\n\t})\n\n\thttpSrv := &http.Server{Addr: httpAddr}\n\tg.Add(func() error {\n\t\tm := http.NewServeMux()\n\t\t// Create HTTP handler for Prometheus metrics.\n\t\tm.Handle(\"/metrics\", promhttp.HandlerFor(\n\t\t\treg,\n\t\t\tpromhttp.HandlerOpts{\n\t\t\t\t// Opt into OpenMetrics e.g. to support exemplars.\n\t\t\t\tEnableOpenMetrics: true,\n\t\t\t},\n\t\t))\n\t\thttpSrv.Handler = m\n\t\tlogger.Info(\"starting HTTP server\", \"addr\", httpSrv.Addr)\n\t\treturn httpSrv.ListenAndServe()\n\t}, func(error) {\n\t\tif err := httpSrv.Close(); err != nil {\n\t\t\tlogger.Error(\"failed to stop web server\", \"err\", err)\n\t\t}\n\t})\n\n\tg.Add(run.SignalHandler(context.Background(), syscall.SIGINT, syscall.SIGTERM))\n\n\tif err := g.Run(); err != nil {\n\t\tlogger.Error(\"program interrupted\", \"err\", err)\n\t\tos.Exit(1)\n\t}\n}\n"
  },
  {
    "path": "examples/go.mod",
    "content": "module github.com/grpc-ecosystem/go-grpc-middleware/examples/v2\n\ngo 1.24.0\n\nrequire (\n\tgithub.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus v1.0.0\n\tgithub.com/grpc-ecosystem/go-grpc-middleware/v2 v2.1.0\n\tgithub.com/oklog/run v1.2.0\n\tgithub.com/prometheus/client_golang v1.20.5\n\tgo.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.56.0\n\tgo.opentelemetry.io/otel v1.36.0\n\tgo.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.31.0\n\tgo.opentelemetry.io/otel/sdk v1.36.0\n\tgo.opentelemetry.io/otel/trace v1.36.0\n\tgoogle.golang.org/grpc v1.74.2\n)\n\nrequire (\n\tgithub.com/beorn7/perks v1.0.1 // indirect\n\tgithub.com/cespare/xxhash/v2 v2.3.0 // indirect\n\tgithub.com/davecgh/go-spew v1.1.1 // indirect\n\tgithub.com/go-logr/logr v1.4.3 // indirect\n\tgithub.com/go-logr/stdr v1.2.2 // indirect\n\tgithub.com/google/uuid v1.6.0 // indirect\n\tgithub.com/klauspost/compress v1.17.9 // indirect\n\tgithub.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect\n\tgithub.com/pmezard/go-difflib v1.0.0 // indirect\n\tgithub.com/prometheus/client_model v0.6.1 // indirect\n\tgithub.com/prometheus/common v0.55.0 // indirect\n\tgithub.com/prometheus/procfs v0.15.1 // indirect\n\tgithub.com/stretchr/testify v1.11.1 // indirect\n\tgo.opentelemetry.io/auto/sdk v1.1.0 // indirect\n\tgo.opentelemetry.io/otel/metric v1.36.0 // indirect\n\tgolang.org/x/net v0.47.0 // indirect\n\tgolang.org/x/sys v0.38.0 // indirect\n\tgolang.org/x/text v0.31.0 // indirect\n\tgoogle.golang.org/genproto/googleapis/rpc v0.0.0-20250603155806-513f23925822 // indirect\n\tgoogle.golang.org/protobuf v1.36.10 // indirect\n\tgopkg.in/yaml.v3 v3.0.1 // indirect\n)\n\nreplace (\n\tgithub.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus => ../providers/prometheus\n\tgithub.com/grpc-ecosystem/go-grpc-middleware/v2 => ../\n)\n"
  },
  {
    "path": "examples/go.sum",
    "content": "cloud.google.com/go/compute/metadata v0.7.0 h1:PBWF+iiAerVNe8UCHxdOt6eHLVc3ydFeOCw78U8ytSU=\ncloud.google.com/go/compute/metadata v0.7.0/go.mod h1:j5MvL9PprKL39t166CoB1uVHfQMs4tFQZZcKwksXUjo=\ngithub.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=\ngithub.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=\ngithub.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=\ngithub.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=\ngithub.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=\ngithub.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=\ngithub.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=\ngithub.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI=\ngithub.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=\ngithub.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=\ngithub.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=\ngithub.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek=\ngithub.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps=\ngithub.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=\ngithub.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=\ngithub.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=\ngithub.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=\ngithub.com/klauspost/compress v1.17.9 h1:6KIumPrER1LHsvBVuDa0r5xaG0Es51mhhB9BQB2qeMA=\ngithub.com/klauspost/compress v1.17.9/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw=\ngithub.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=\ngithub.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=\ngithub.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=\ngithub.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=\ngithub.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc=\ngithub.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw=\ngithub.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA=\ngithub.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=\ngithub.com/oklog/run v1.2.0 h1:O8x3yXwah4A73hJdlrwo/2X6J62gE5qTMusH0dvz60E=\ngithub.com/oklog/run v1.2.0/go.mod h1:mgDbKRSwPhJfesJ4PntqFUbKQRZ50NgmZTSPlFA0YFk=\ngithub.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=\ngithub.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=\ngithub.com/prometheus/client_golang v1.20.5 h1:cxppBPuYhUnsO6yo/aoRol4L7q7UFfdm+bR9r+8l63Y=\ngithub.com/prometheus/client_golang v1.20.5/go.mod h1:PIEt8X02hGcP8JWbeHyeZ53Y/jReSnHgO035n//V5WE=\ngithub.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E=\ngithub.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY=\ngithub.com/prometheus/common v0.55.0 h1:KEi6DK7lXW/m7Ig5i47x0vRzuBsHuvJdi5ee6Y3G1dc=\ngithub.com/prometheus/common v0.55.0/go.mod h1:2SECS4xJG1kd8XF9IcM1gMX6510RAEL65zxzNImwdc8=\ngithub.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0learggepc=\ngithub.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk=\ngithub.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII=\ngithub.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o=\ngithub.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U=\ngithub.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=\ngo.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA=\ngo.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A=\ngo.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.56.0 h1:yMkBS9yViCc7U7yeLzJPM2XizlfdVvBRSmsQDWu6qc0=\ngo.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.56.0/go.mod h1:n8MR6/liuGB5EmTETUBeU5ZgqMOlqKRxUaqPQBOANZ8=\ngo.opentelemetry.io/otel v1.36.0 h1:UumtzIklRBY6cI/lllNZlALOF5nNIzJVb16APdvgTXg=\ngo.opentelemetry.io/otel v1.36.0/go.mod h1:/TcFMXYjyRNh8khOAO9ybYkqaDBb/70aVwkNML4pP8E=\ngo.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.31.0 h1:UGZ1QwZWY67Z6BmckTU+9Rxn04m2bD3gD6Mk0OIOCPk=\ngo.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.31.0/go.mod h1:fcwWuDuaObkkChiDlhEpSq9+X1C0omv+s5mBtToAQ64=\ngo.opentelemetry.io/otel/metric v1.36.0 h1:MoWPKVhQvJ+eeXWHFBOPoBOi20jh6Iq2CcCREuTYufE=\ngo.opentelemetry.io/otel/metric v1.36.0/go.mod h1:zC7Ks+yeyJt4xig9DEw9kuUFe5C3zLbVjV2PzT6qzbs=\ngo.opentelemetry.io/otel/sdk v1.36.0 h1:b6SYIuLRs88ztox4EyrvRti80uXIFy+Sqzoh9kFULbs=\ngo.opentelemetry.io/otel/sdk v1.36.0/go.mod h1:+lC+mTgD+MUWfjJubi2vvXWcVxyr9rmlshZni72pXeY=\ngo.opentelemetry.io/otel/sdk/metric v1.36.0 h1:r0ntwwGosWGaa0CrSt8cuNuTcccMXERFwHX4dThiPis=\ngo.opentelemetry.io/otel/sdk/metric v1.36.0/go.mod h1:qTNOhFDfKRwX0yXOqJYegL5WRaW376QbB7P4Pb0qva4=\ngo.opentelemetry.io/otel/trace v1.36.0 h1:ahxWNuqZjpdiFAyrIoQ4GIiAIhxAunQR6MUoKrsNd4w=\ngo.opentelemetry.io/otel/trace v1.36.0/go.mod h1:gQ+OnDZzrybY4k4seLzPAWNwVBBVlF2szhehOBB/tGA=\ngo.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=\ngo.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=\ngolang.org/x/net v0.47.0 h1:Mx+4dIFzqraBXUugkia1OOvlD6LemFo1ALMHjrXDOhY=\ngolang.org/x/net v0.47.0/go.mod h1:/jNxtkgq5yWUGYkaZGqo27cfGZ1c5Nen03aYrrKpVRU=\ngolang.org/x/oauth2 v0.30.0 h1:dnDm7JmhM45NNpd8FDDeLhK6FwqbOf4MLCM9zb1BOHI=\ngolang.org/x/oauth2 v0.30.0/go.mod h1:B++QgG3ZKulg6sRPGD/mqlHQs5rB3Ml9erfeDY7xKlU=\ngolang.org/x/sys v0.38.0 h1:3yZWxaJjBmCWXqhN1qh02AkOnCQ1poK6oF+a7xWL6Gc=\ngolang.org/x/sys v0.38.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=\ngolang.org/x/text v0.31.0 h1:aC8ghyu4JhP8VojJ2lEHBnochRno1sgL6nEi9WGFGMM=\ngolang.org/x/text v0.31.0/go.mod h1:tKRAlv61yKIjGGHX/4tP1LTbc13YSec1pxVEWXzfoeM=\ngoogle.golang.org/genproto/googleapis/rpc v0.0.0-20250603155806-513f23925822 h1:fc6jSaCT0vBduLYZHYrBBNY4dsWuvgyff9noRNDdBeE=\ngoogle.golang.org/genproto/googleapis/rpc v0.0.0-20250603155806-513f23925822/go.mod h1:qQ0YXyHHx3XkvlzUtpXDkS29lDSafHMZBAZDc03LQ3A=\ngoogle.golang.org/grpc v1.74.2 h1:WoosgB65DlWVC9FqI82dGsZhWFNBSLjQ84bjROOpMu4=\ngoogle.golang.org/grpc v1.74.2/go.mod h1:CtQ+BGjaAIXHs/5YS3i473GqwBBa1zGQNevxdeBEXrM=\ngoogle.golang.org/protobuf v1.36.10 h1:AYd7cD/uASjIL6Q9LiTjz8JLcrh/88q5UObnmY3aOOE=\ngoogle.golang.org/protobuf v1.36.10/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco=\ngopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=\ngopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=\ngopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=\ngopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=\ngopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=\n"
  },
  {
    "path": "examples/server/main.go",
    "content": "// Copyright (c) The go-grpc-middleware Authors.\n// Licensed under the Apache License 2.0.\n\npackage main\n\nimport (\n\t\"context\"\n\t\"log/slog\"\n\t\"net\"\n\t\"net/http\"\n\t\"os\"\n\t\"runtime/debug\"\n\t\"syscall\"\n\n\tgrpcprom \"github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus\"\n\t\"github.com/grpc-ecosystem/go-grpc-middleware/v2/interceptors\"\n\t\"github.com/grpc-ecosystem/go-grpc-middleware/v2/interceptors/auth\"\n\t\"github.com/grpc-ecosystem/go-grpc-middleware/v2/interceptors/logging\"\n\t\"github.com/grpc-ecosystem/go-grpc-middleware/v2/interceptors/recovery\"\n\t\"github.com/grpc-ecosystem/go-grpc-middleware/v2/interceptors/selector\"\n\t\"github.com/grpc-ecosystem/go-grpc-middleware/v2/metadata\"\n\t\"github.com/grpc-ecosystem/go-grpc-middleware/v2/testing/testpb\"\n\t\"github.com/oklog/run\"\n\t\"github.com/prometheus/client_golang/prometheus\"\n\t\"github.com/prometheus/client_golang/prometheus/promauto\"\n\t\"github.com/prometheus/client_golang/prometheus/promhttp\"\n\t\"go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc\"\n\t\"go.opentelemetry.io/otel\"\n\tstdout \"go.opentelemetry.io/otel/exporters/stdout/stdouttrace\"\n\t\"go.opentelemetry.io/otel/propagation\"\n\tsdktrace \"go.opentelemetry.io/otel/sdk/trace\"\n\t\"go.opentelemetry.io/otel/trace\"\n\t\"google.golang.org/grpc\"\n\t\"google.golang.org/grpc/codes\"\n\thealthpb \"google.golang.org/grpc/health/grpc_health_v1\"\n\t\"google.golang.org/grpc/status\"\n)\n\nconst (\n\tcomponent = \"grpc-example\"\n\tgrpcAddr  = \":8080\"\n\thttpAddr  = \":8081\"\n)\n\n// interceptorLogger adapts slog logger to interceptor logger.\n// This code is simple enough to be copied and not imported.\nfunc interceptorLogger(l *slog.Logger) logging.Logger {\n\treturn logging.LoggerFunc(func(ctx context.Context, lvl logging.Level, msg string, fields ...any) {\n\t\tl.Log(ctx, slog.Level(lvl), msg, fields...)\n\t})\n}\n\nfunc main() {\n\t// Setup logging.\n\tlogger := slog.New(slog.NewTextHandler(os.Stderr, &slog.HandlerOptions{}))\n\trpcLogger := logger.With(\"service\", \"gRPC/server\", \"component\", component)\n\tlogTraceID := func(ctx context.Context) logging.Fields {\n\t\tif span := trace.SpanContextFromContext(ctx); span.IsSampled() {\n\t\t\treturn logging.Fields{\"traceID\", span.TraceID().String()}\n\t\t}\n\t\treturn nil\n\t}\n\n\t// Setup metrics.\n\tsrvMetrics := grpcprom.NewServerMetrics(\n\t\tgrpcprom.WithServerHandlingTimeHistogram(\n\t\t\tgrpcprom.WithHistogramBuckets([]float64{0.001, 0.01, 0.1, 0.3, 0.6, 1, 3, 6, 9, 20, 30, 60, 90, 120}),\n\t\t),\n\t\t// Add tenant_name as a context label. This server option is necessary\n\t\t// to initialize the metrics with the labels that will be provided\n\t\t// dynamically from the context. This should be used in tandem with\n\t\t// WithLabelsFromContext in the interceptor options.\n\t\tgrpcprom.WithContextLabels(\"tenant_name\"),\n\t)\n\treg := prometheus.NewRegistry()\n\treg.MustRegister(srvMetrics)\n\texemplarFromContext := func(ctx context.Context) prometheus.Labels {\n\t\tif span := trace.SpanContextFromContext(ctx); span.IsSampled() {\n\t\t\treturn prometheus.Labels{\"traceID\": span.TraceID().String()}\n\t\t}\n\t\treturn nil\n\t}\n\n\t// Extract the tenant name value from gRPC metadata\n\t// and use it as a label on our metrics.\n\tlabelsFromContext := func(ctx context.Context) prometheus.Labels {\n\t\tlabels := prometheus.Labels{}\n\n\t\tmd := metadata.ExtractIncoming(ctx)\n\t\ttenantName := md.Get(\"tenant-name\")\n\t\tif tenantName == \"\" {\n\t\t\ttenantName = \"unknown\"\n\t\t}\n\t\tlabels[\"tenant_name\"] = tenantName\n\n\t\treturn labels\n\t}\n\n\t// Set up OTLP tracing (stdout for debug).\n\texporter, err := stdout.New(stdout.WithPrettyPrint())\n\tif err != nil {\n\t\tlogger.Error(\"failed to init exporter\", \"err\", err)\n\t\tos.Exit(1)\n\t}\n\ttp := sdktrace.NewTracerProvider(\n\t\tsdktrace.WithSampler(sdktrace.AlwaysSample()),\n\t\tsdktrace.WithBatcher(exporter),\n\t)\n\totel.SetTracerProvider(tp)\n\totel.SetTextMapPropagator(propagation.NewCompositeTextMapPropagator(propagation.TraceContext{}, propagation.Baggage{}))\n\tdefer func() { _ = exporter.Shutdown(context.Background()) }()\n\n\t// Setup custom auth.\n\tauthFn := func(ctx context.Context) (context.Context, error) {\n\t\ttoken, err := auth.AuthFromMD(ctx, \"bearer\")\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\t// TODO: This is example only, perform proper Oauth/OIDC verification!\n\t\tif token != \"yolo\" {\n\t\t\treturn nil, status.Error(codes.Unauthenticated, \"invalid auth token\")\n\t\t}\n\t\t// NOTE: You can also pass the token in the context for further interceptors or gRPC service code.\n\t\treturn ctx, nil\n\t}\n\n\t// Setup auth matcher.\n\tallButHealthZ := func(ctx context.Context, callMeta interceptors.CallMeta) bool {\n\t\treturn healthpb.Health_ServiceDesc.ServiceName != callMeta.Service\n\t}\n\n\t// Setup metric for panic recoveries.\n\tpanicsTotal := promauto.With(reg).NewCounter(prometheus.CounterOpts{\n\t\tName: \"grpc_req_panics_recovered_total\",\n\t\tHelp: \"Total number of gRPC requests recovered from internal panic.\",\n\t})\n\tgrpcPanicRecoveryHandler := func(p any) (err error) {\n\t\tpanicsTotal.Inc()\n\t\trpcLogger.Error(\"recovered from panic\", \"panic\", p, \"stack\", debug.Stack())\n\t\treturn status.Errorf(codes.Internal, \"%s\", p)\n\t}\n\n\tgrpcSrv := grpc.NewServer(\n\t\tgrpc.StatsHandler(otelgrpc.NewServerHandler()),\n\t\tgrpc.ChainUnaryInterceptor(\n\t\t\tsrvMetrics.UnaryServerInterceptor(\n\t\t\t\tgrpcprom.WithExemplarFromContext(exemplarFromContext),\n\t\t\t\tgrpcprom.WithLabelsFromContext(labelsFromContext),\n\t\t\t),\n\t\t\tlogging.UnaryServerInterceptor(interceptorLogger(rpcLogger), logging.WithFieldsFromContext(logTraceID)),\n\t\t\tselector.UnaryServerInterceptor(auth.UnaryServerInterceptor(authFn), selector.MatchFunc(allButHealthZ)),\n\t\t\trecovery.UnaryServerInterceptor(recovery.WithRecoveryHandler(grpcPanicRecoveryHandler)),\n\t\t),\n\t\tgrpc.ChainStreamInterceptor(\n\t\t\tsrvMetrics.StreamServerInterceptor(\n\t\t\t\tgrpcprom.WithExemplarFromContext(exemplarFromContext),\n\t\t\t\tgrpcprom.WithLabelsFromContext(labelsFromContext),\n\t\t\t),\n\t\t\tlogging.StreamServerInterceptor(interceptorLogger(rpcLogger), logging.WithFieldsFromContext(logTraceID)),\n\t\t\tselector.StreamServerInterceptor(auth.StreamServerInterceptor(authFn), selector.MatchFunc(allButHealthZ)),\n\t\t\trecovery.StreamServerInterceptor(recovery.WithRecoveryHandler(grpcPanicRecoveryHandler)),\n\t\t),\n\t)\n\tt := &testpb.TestPingService{}\n\ttestpb.RegisterTestServiceServer(grpcSrv, t)\n\tsrvMetrics.InitializeMetrics(grpcSrv)\n\n\tg := &run.Group{}\n\tg.Add(func() error {\n\t\tl, err := net.Listen(\"tcp\", grpcAddr)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tlogger.Info(\"starting gRPC server\", \"addr\", l.Addr().String())\n\t\treturn grpcSrv.Serve(l)\n\t}, func(err error) {\n\t\tgrpcSrv.GracefulStop()\n\t\tgrpcSrv.Stop()\n\t})\n\n\thttpSrv := &http.Server{Addr: httpAddr}\n\tg.Add(func() error {\n\t\tm := http.NewServeMux()\n\t\t// Create HTTP handler for Prometheus metrics.\n\t\tm.Handle(\"/metrics\", promhttp.HandlerFor(\n\t\t\treg,\n\t\t\tpromhttp.HandlerOpts{\n\t\t\t\t// Opt into OpenMetrics e.g. to support exemplars.\n\t\t\t\tEnableOpenMetrics: true,\n\t\t\t},\n\t\t))\n\t\thttpSrv.Handler = m\n\t\tlogger.Info(\"starting HTTP server\", \"addr\", httpSrv.Addr)\n\t\treturn httpSrv.ListenAndServe()\n\t}, func(error) {\n\t\tif err := httpSrv.Close(); err != nil {\n\t\t\tlogger.Error(\"failed to stop web server\", \"err\", err)\n\t\t}\n\t})\n\n\tg.Add(run.SignalHandler(context.Background(), syscall.SIGINT, syscall.SIGTERM))\n\n\tif err := g.Run(); err != nil {\n\t\tlogger.Error(\"program interrupted\", \"err\", err)\n\t\tos.Exit(1)\n\t}\n}\n"
  },
  {
    "path": "go.mod",
    "content": "module github.com/grpc-ecosystem/go-grpc-middleware/v2\n\ngo 1.24.0\n\nrequire (\n\tbuf.build/gen/go/bufbuild/protovalidate/protocolbuffers/go v1.36.10-20250912141014-52f32327d4b0.1\n\tbuf.build/go/protovalidate v1.0.0\n\tgithub.com/stretchr/testify v1.11.1\n\tgolang.org/x/net v0.47.0\n\tgolang.org/x/oauth2 v0.30.0\n\tgoogle.golang.org/grpc v1.74.2\n\tgoogle.golang.org/protobuf v1.36.10\n)\n\nrequire (\n\tcel.dev/expr v0.24.0 // indirect\n\tcloud.google.com/go/compute/metadata v0.7.0 // indirect\n\tgithub.com/antlr4-go/antlr/v4 v4.13.1 // indirect\n\tgithub.com/davecgh/go-spew v1.1.1 // indirect\n\tgithub.com/google/cel-go v0.26.1 // indirect\n\tgithub.com/pmezard/go-difflib v1.0.0 // indirect\n\tgithub.com/stoewer/go-strcase v1.3.1 // indirect\n\tgolang.org/x/exp v0.0.0-20250620022241-b7579e27df2b // indirect\n\tgolang.org/x/sys v0.38.0 // indirect\n\tgolang.org/x/text v0.31.0 // indirect\n\tgoogle.golang.org/genproto/googleapis/api v0.0.0-20250603155806-513f23925822 // indirect\n\tgoogle.golang.org/genproto/googleapis/rpc v0.0.0-20250603155806-513f23925822 // indirect\n\tgopkg.in/yaml.v3 v3.0.1 // indirect\n)\n"
  },
  {
    "path": "go.sum",
    "content": "buf.build/gen/go/bufbuild/protovalidate/protocolbuffers/go v1.36.10-20250912141014-52f32327d4b0.1 h1:31on4W/yPcV4nZHL4+UCiCvLPsMqe/vJcNg8Rci0scc=\nbuf.build/gen/go/bufbuild/protovalidate/protocolbuffers/go v1.36.10-20250912141014-52f32327d4b0.1/go.mod h1:fUl8CEN/6ZAMk6bP8ahBJPUJw7rbp+j4x+wCcYi2IG4=\nbuf.build/go/protovalidate v1.0.0 h1:IAG1etULddAy93fiBsFVhpj7es5zL53AfB/79CVGtyY=\nbuf.build/go/protovalidate v1.0.0/go.mod h1:KQmEUrcQuC99hAw+juzOEAmILScQiKBP1Oc36vvCLW8=\ncel.dev/expr v0.24.0 h1:56OvJKSH3hDGL0ml5uSxZmz3/3Pq4tJ+fb1unVLAFcY=\ncel.dev/expr v0.24.0/go.mod h1:hLPLo1W4QUmuYdA72RBX06QTs6MXw941piREPl3Yfiw=\ncloud.google.com/go/compute/metadata v0.7.0 h1:PBWF+iiAerVNe8UCHxdOt6eHLVc3ydFeOCw78U8ytSU=\ncloud.google.com/go/compute/metadata v0.7.0/go.mod h1:j5MvL9PprKL39t166CoB1uVHfQMs4tFQZZcKwksXUjo=\ngithub.com/antlr4-go/antlr/v4 v4.13.1 h1:SqQKkuVZ+zWkMMNkjy5FZe5mr5WURWnlpmOuzYWrPrQ=\ngithub.com/antlr4-go/antlr/v4 v4.13.1/go.mod h1:GKmUxMtwp6ZgGwZSva4eWPC5mS6vUAmOABFgjdkM7Nw=\ngithub.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=\ngithub.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=\ngithub.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=\ngithub.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI=\ngithub.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=\ngithub.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=\ngithub.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=\ngithub.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek=\ngithub.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps=\ngithub.com/google/cel-go v0.26.1 h1:iPbVVEdkhTX++hpe3lzSk7D3G3QSYqLGoHOcEio+UXQ=\ngithub.com/google/cel-go v0.26.1/go.mod h1:A9O8OU9rdvrK5MQyrqfIxo1a0u4g3sF8KB6PUIaryMM=\ngithub.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=\ngithub.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=\ngithub.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=\ngithub.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=\ngithub.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=\ngithub.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=\ngithub.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=\ngithub.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=\ngithub.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=\ngithub.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=\ngithub.com/stoewer/go-strcase v1.3.1 h1:iS0MdW+kVTxgMoE1LAZyMiYJFKlOzLooE4MxjirtkAs=\ngithub.com/stoewer/go-strcase v1.3.1/go.mod h1:fAH5hQ5pehh+j3nZfvwdk2RgEgQjAoM8wodgtPmh1xo=\ngithub.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=\ngithub.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=\ngithub.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=\ngithub.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=\ngithub.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=\ngithub.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=\ngithub.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U=\ngithub.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=\ngo.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA=\ngo.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A=\ngo.opentelemetry.io/otel v1.36.0 h1:UumtzIklRBY6cI/lllNZlALOF5nNIzJVb16APdvgTXg=\ngo.opentelemetry.io/otel v1.36.0/go.mod h1:/TcFMXYjyRNh8khOAO9ybYkqaDBb/70aVwkNML4pP8E=\ngo.opentelemetry.io/otel/metric v1.36.0 h1:MoWPKVhQvJ+eeXWHFBOPoBOi20jh6Iq2CcCREuTYufE=\ngo.opentelemetry.io/otel/metric v1.36.0/go.mod h1:zC7Ks+yeyJt4xig9DEw9kuUFe5C3zLbVjV2PzT6qzbs=\ngo.opentelemetry.io/otel/sdk v1.36.0 h1:b6SYIuLRs88ztox4EyrvRti80uXIFy+Sqzoh9kFULbs=\ngo.opentelemetry.io/otel/sdk v1.36.0/go.mod h1:+lC+mTgD+MUWfjJubi2vvXWcVxyr9rmlshZni72pXeY=\ngo.opentelemetry.io/otel/sdk/metric v1.36.0 h1:r0ntwwGosWGaa0CrSt8cuNuTcccMXERFwHX4dThiPis=\ngo.opentelemetry.io/otel/sdk/metric v1.36.0/go.mod h1:qTNOhFDfKRwX0yXOqJYegL5WRaW376QbB7P4Pb0qva4=\ngo.opentelemetry.io/otel/trace v1.36.0 h1:ahxWNuqZjpdiFAyrIoQ4GIiAIhxAunQR6MUoKrsNd4w=\ngo.opentelemetry.io/otel/trace v1.36.0/go.mod h1:gQ+OnDZzrybY4k4seLzPAWNwVBBVlF2szhehOBB/tGA=\ngolang.org/x/exp v0.0.0-20250620022241-b7579e27df2b h1:M2rDM6z3Fhozi9O7NWsxAkg/yqS/lQJ6PmkyIV3YP+o=\ngolang.org/x/exp v0.0.0-20250620022241-b7579e27df2b/go.mod h1:3//PLf8L/X+8b4vuAfHzxeRUl04Adcb341+IGKfnqS8=\ngolang.org/x/net v0.47.0 h1:Mx+4dIFzqraBXUugkia1OOvlD6LemFo1ALMHjrXDOhY=\ngolang.org/x/net v0.47.0/go.mod h1:/jNxtkgq5yWUGYkaZGqo27cfGZ1c5Nen03aYrrKpVRU=\ngolang.org/x/oauth2 v0.30.0 h1:dnDm7JmhM45NNpd8FDDeLhK6FwqbOf4MLCM9zb1BOHI=\ngolang.org/x/oauth2 v0.30.0/go.mod h1:B++QgG3ZKulg6sRPGD/mqlHQs5rB3Ml9erfeDY7xKlU=\ngolang.org/x/sys v0.38.0 h1:3yZWxaJjBmCWXqhN1qh02AkOnCQ1poK6oF+a7xWL6Gc=\ngolang.org/x/sys v0.38.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=\ngolang.org/x/text v0.31.0 h1:aC8ghyu4JhP8VojJ2lEHBnochRno1sgL6nEi9WGFGMM=\ngolang.org/x/text v0.31.0/go.mod h1:tKRAlv61yKIjGGHX/4tP1LTbc13YSec1pxVEWXzfoeM=\ngoogle.golang.org/genproto/googleapis/api v0.0.0-20250603155806-513f23925822 h1:oWVWY3NzT7KJppx2UKhKmzPq4SRe0LdCijVRwvGeikY=\ngoogle.golang.org/genproto/googleapis/api v0.0.0-20250603155806-513f23925822/go.mod h1:h3c4v36UTKzUiuaOKQ6gr3S+0hovBtUrXzTG/i3+XEc=\ngoogle.golang.org/genproto/googleapis/rpc v0.0.0-20250603155806-513f23925822 h1:fc6jSaCT0vBduLYZHYrBBNY4dsWuvgyff9noRNDdBeE=\ngoogle.golang.org/genproto/googleapis/rpc v0.0.0-20250603155806-513f23925822/go.mod h1:qQ0YXyHHx3XkvlzUtpXDkS29lDSafHMZBAZDc03LQ3A=\ngoogle.golang.org/grpc v1.74.2 h1:WoosgB65DlWVC9FqI82dGsZhWFNBSLjQ84bjROOpMu4=\ngoogle.golang.org/grpc v1.74.2/go.mod h1:CtQ+BGjaAIXHs/5YS3i473GqwBBa1zGQNevxdeBEXrM=\ngoogle.golang.org/protobuf v1.36.10 h1:AYd7cD/uASjIL6Q9LiTjz8JLcrh/88q5UObnmY3aOOE=\ngoogle.golang.org/protobuf v1.36.10/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco=\ngopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=\ngopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo=\ngopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=\ngopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=\ngopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=\ngopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=\n"
  },
  {
    "path": "goimports.sh",
    "content": "#!/usr/bin/env bash\n\n# Taken from https://gist.github.com/soniah/c11633551c6dd84dab66cad20453cfa8\n# remove all blank lines in go 'imports' statements, as goimports doesn't do it.\n\nif [ $# != 1 ] ; then\n  echo \"usage: $0 <filename>\"\n  exit 1\nfi\n\nsed -i '\n  /^import/,/)/ {\n    /^$/ d\n  }\n' $1\n"
  },
  {
    "path": "interceptors/auth/auth.go",
    "content": "// Copyright (c) The go-grpc-middleware Authors.\n// Licensed under the Apache License 2.0.\n\npackage auth\n\nimport (\n\t\"context\"\n\n\tmiddleware \"github.com/grpc-ecosystem/go-grpc-middleware/v2\"\n\t\"google.golang.org/grpc\"\n)\n\n// AuthFunc is the pluggable function that performs authentication.\n//\n// The passed in `Context` will contain the gRPC metadata.MD object (for header-based authentication) and\n// the peer.Peer information that can contain transport-based credentials (e.g. `credentials.AuthInfo`).\n//\n// The returned context will be propagated to handlers, allowing user changes to `Context`. However,\n// please make sure that the `Context` returned is a child `Context` of the one passed in.\n//\n// If error is returned, its `grpc.Code()` will be returned to the user as well as the verbatim message.\n// Please make sure you use `codes.Unauthenticated` (lacking auth) and `codes.PermissionDenied`\n// (authed, but lacking perms) appropriately.\ntype AuthFunc func(ctx context.Context) (context.Context, error)\n\n// ServiceAuthFuncOverride allows a given gRPC service implementation to override the global `AuthFunc`.\n//\n// If a service implements the AuthFuncOverride method, it takes precedence over the `AuthFunc` method,\n// and will be called instead of AuthFunc for all method invocations within that service.\ntype ServiceAuthFuncOverride interface {\n\tAuthFuncOverride(ctx context.Context, fullMethodName string) (context.Context, error)\n}\n\n// UnaryServerInterceptor returns a new unary server interceptors that performs per-request auth.\n// NOTE(bwplotka): For more complex auth interceptor see https://github.com/grpc/grpc-go/blob/master/authz/grpc_authz_server_interceptors.go.\nfunc UnaryServerInterceptor(authFunc AuthFunc) grpc.UnaryServerInterceptor {\n\treturn func(ctx context.Context, req any, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (any, error) {\n\t\tvar newCtx context.Context\n\t\tvar err error\n\t\tif overrideSrv, ok := info.Server.(ServiceAuthFuncOverride); ok {\n\t\t\tnewCtx, err = overrideSrv.AuthFuncOverride(ctx, info.FullMethod)\n\t\t} else {\n\t\t\tnewCtx, err = authFunc(ctx)\n\t\t}\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\treturn handler(newCtx, req)\n\t}\n}\n\n// StreamServerInterceptor returns a new stream server interceptors that performs per-request auth.\n// NOTE(bwplotka): For more complex auth interceptor see https://github.com/grpc/grpc-go/blob/master/authz/grpc_authz_server_interceptors.go.\nfunc StreamServerInterceptor(authFunc AuthFunc) grpc.StreamServerInterceptor {\n\treturn func(srv any, stream grpc.ServerStream, info *grpc.StreamServerInfo, handler grpc.StreamHandler) error {\n\t\tvar newCtx context.Context\n\t\tvar err error\n\t\tif overrideSrv, ok := srv.(ServiceAuthFuncOverride); ok {\n\t\t\tnewCtx, err = overrideSrv.AuthFuncOverride(stream.Context(), info.FullMethod)\n\t\t} else {\n\t\t\tnewCtx, err = authFunc(stream.Context())\n\t\t}\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\twrapped := middleware.WrapServerStream(stream)\n\t\twrapped.WrappedContext = newCtx\n\t\treturn handler(srv, wrapped)\n\t}\n}\n"
  },
  {
    "path": "interceptors/auth/auth_test.go",
    "content": "// Copyright (c) The go-grpc-middleware Authors.\n// Licensed under the Apache License 2.0.\n\npackage auth_test\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/grpc-ecosystem/go-grpc-middleware/v2/interceptors/auth\"\n\t\"github.com/grpc-ecosystem/go-grpc-middleware/v2/metadata\"\n\t\"github.com/grpc-ecosystem/go-grpc-middleware/v2/testing/testpb\"\n\t\"github.com/stretchr/testify/assert\"\n\t\"github.com/stretchr/testify/suite\"\n\t\"golang.org/x/oauth2\"\n\t\"google.golang.org/grpc\"\n\t\"google.golang.org/grpc/codes\"\n\t\"google.golang.org/grpc/credentials/oauth\"\n\tgrpcMetadata \"google.golang.org/grpc/metadata\"\n\t\"google.golang.org/grpc/status\"\n)\n\ntype authedMarker struct{}\n\nvar (\n\tcommonAuthToken   = \"some_good_token\"\n\toverrideAuthToken = \"override_token\"\n)\n\n// TODO(mwitkow): Add auth from metadata client dialer, which requires TLS.\n\nfunc buildDummyAuthFunction(expectedScheme, expectedToken string) func(ctx context.Context) (context.Context, error) {\n\treturn func(ctx context.Context) (context.Context, error) {\n\t\ttoken, err := auth.AuthFromMD(ctx, expectedScheme)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tif token != expectedToken {\n\t\t\treturn nil, status.Error(codes.PermissionDenied, \"buildDummyAuthFunction bad token\")\n\t\t}\n\t\treturn context.WithValue(ctx, authedMarker{}, \"marker_exists\"), nil\n\t}\n}\n\nfunc assertAuthMarkerExists(t *testing.T, ctx context.Context) {\n\tassert.Equal(t, \"marker_exists\", ctx.Value(authedMarker{}).(string), \"auth marker from buildDummyAuthFunction must be passed around\")\n}\n\ntype assertingPingService struct {\n\ttestpb.TestServiceServer\n\tT *testing.T\n}\n\nfunc (s *assertingPingService) PingError(ctx context.Context, ping *testpb.PingErrorRequest) (*testpb.PingErrorResponse, error) {\n\tassertAuthMarkerExists(s.T, ctx)\n\treturn s.TestServiceServer.PingError(ctx, ping)\n}\n\nfunc (s *assertingPingService) PingList(ping *testpb.PingListRequest, stream testpb.TestService_PingListServer) error {\n\tassertAuthMarkerExists(s.T, stream.Context())\n\treturn s.TestServiceServer.PingList(ping, stream)\n}\n\nfunc ctxWithToken(ctx context.Context, scheme, token string) context.Context {\n\tmd := grpcMetadata.Pairs(\"authorization\", fmt.Sprintf(\"%s %v\", scheme, token))\n\treturn metadata.MD(md).ToOutgoing(ctx)\n}\n\nfunc TestAuthTestSuite(t *testing.T) {\n\tauthFunc := buildDummyAuthFunction(\"bearer\", commonAuthToken)\n\ts := &AuthTestSuite{\n\t\tInterceptorTestSuite: &testpb.InterceptorTestSuite{\n\t\t\tTestService: &assertingPingService{&testpb.TestPingService{}, t},\n\t\t\tServerOpts: []grpc.ServerOption{\n\t\t\t\tgrpc.StreamInterceptor(auth.StreamServerInterceptor(authFunc)),\n\t\t\t\tgrpc.UnaryInterceptor(auth.UnaryServerInterceptor(authFunc)),\n\t\t\t},\n\t\t},\n\t}\n\tsuite.Run(t, s)\n}\n\ntype AuthTestSuite struct {\n\t*testpb.InterceptorTestSuite\n}\n\nfunc (s *AuthTestSuite) TestUnary_NoAuth() {\n\t_, err := s.Client.Ping(s.SimpleCtx(), testpb.GoodPing)\n\ts.Require().Error(err, \"there must be an error\")\n\ts.Assert().Equal(codes.Unauthenticated, status.Code(err), \"must error with unauthenticated\")\n}\n\nfunc (s *AuthTestSuite) TestUnary_BadAuth() {\n\t_, err := s.Client.Ping(ctxWithToken(s.SimpleCtx(), \"bearer\", \"bad_token\"), testpb.GoodPing)\n\ts.Require().Error(err, \"there must be an error\")\n\ts.Assert().Equal(codes.PermissionDenied, status.Code(err), \"must error with permission denied\")\n}\n\nfunc (s *AuthTestSuite) TestUnary_PassesAuth() {\n\t_, err := s.Client.Ping(ctxWithToken(s.SimpleCtx(), \"bearer\", commonAuthToken), testpb.GoodPing)\n\ts.Require().NoError(err, \"no error must occur\")\n}\n\nfunc (s *AuthTestSuite) TestUnary_PassesWithPerRpcCredentials() {\n\tgrpcCreds := oauth.TokenSource{TokenSource: &fakeOAuth2TokenSource{accessToken: commonAuthToken}}\n\tclient := s.NewClient(grpc.WithPerRPCCredentials(grpcCreds))\n\t_, err := client.Ping(s.SimpleCtx(), testpb.GoodPing)\n\ts.Require().NoError(err, \"no error must occur\")\n}\n\nfunc (s *AuthTestSuite) TestStream_NoAuth() {\n\tstream, err := s.Client.PingList(s.SimpleCtx(), testpb.GoodPingList)\n\ts.Require().NoError(err, \"should not fail on establishing the stream\")\n\t_, err = stream.Recv()\n\ts.Require().Error(err, \"there must be an error\")\n\ts.Assert().Equal(codes.Unauthenticated, status.Code(err), \"must error with unauthenticated\")\n}\n\nfunc (s *AuthTestSuite) TestStream_BadAuth() {\n\tstream, err := s.Client.PingList(ctxWithToken(s.SimpleCtx(), \"bearer\", \"bad_token\"), testpb.GoodPingList)\n\ts.Require().NoError(err, \"should not fail on establishing the stream\")\n\t_, err = stream.Recv()\n\ts.Require().Error(err, \"there must be an error\")\n\ts.Assert().Equal(codes.PermissionDenied, status.Code(err), \"must error with permission denied\")\n}\n\nfunc (s *AuthTestSuite) TestStream_PassesAuth() {\n\tstream, err := s.Client.PingList(ctxWithToken(s.SimpleCtx(), \"Bearer\", commonAuthToken), testpb.GoodPingList)\n\ts.Require().NoError(err, \"should not fail on establishing the stream\")\n\tpong, err := stream.Recv()\n\ts.Require().NoError(err, \"no error must occur\")\n\ts.Require().NotNil(pong, \"pong must not be nil\")\n}\n\nfunc (s *AuthTestSuite) TestStream_PassesWithPerRpcCredentials() {\n\tgrpcCreds := oauth.TokenSource{TokenSource: &fakeOAuth2TokenSource{accessToken: commonAuthToken}}\n\tclient := s.NewClient(grpc.WithPerRPCCredentials(grpcCreds))\n\tstream, err := client.PingList(s.SimpleCtx(), testpb.GoodPingList)\n\ts.Require().NoError(err, \"should not fail on establishing the stream\")\n\tpong, err := stream.Recv()\n\ts.Require().NoError(err, \"no error must occur\")\n\ts.Require().NotNil(pong, \"pong must not be nil\")\n}\n\ntype authOverrideTestService struct {\n\ttestpb.TestServiceServer\n\tT *testing.T\n}\n\nfunc (s *authOverrideTestService) AuthFuncOverride(ctx context.Context, fullMethodName string) (context.Context, error) {\n\tassert.NotEmpty(s.T, fullMethodName, \"method name of caller is passed around\")\n\treturn buildDummyAuthFunction(\"bearer\", overrideAuthToken)(ctx)\n}\n\nfunc TestAuthOverrideTestSuite(t *testing.T) {\n\tauthFunc := buildDummyAuthFunction(\"bearer\", commonAuthToken)\n\ts := &AuthOverrideTestSuite{\n\t\tInterceptorTestSuite: &testpb.InterceptorTestSuite{\n\t\t\tTestService: &authOverrideTestService{&assertingPingService{&testpb.TestPingService{}, t}, t},\n\t\t\tServerOpts: []grpc.ServerOption{\n\t\t\t\tgrpc.StreamInterceptor(auth.StreamServerInterceptor(authFunc)),\n\t\t\t\tgrpc.UnaryInterceptor(auth.UnaryServerInterceptor(authFunc)),\n\t\t\t},\n\t\t},\n\t}\n\tsuite.Run(t, s)\n}\n\ntype AuthOverrideTestSuite struct {\n\t*testpb.InterceptorTestSuite\n}\n\nfunc (s *AuthOverrideTestSuite) TestUnary_PassesAuth() {\n\t_, err := s.Client.Ping(ctxWithToken(s.SimpleCtx(), \"bearer\", overrideAuthToken), testpb.GoodPing)\n\ts.Require().NoError(err, \"no error must occur\")\n}\n\nfunc (s *AuthOverrideTestSuite) TestStream_PassesAuth() {\n\tstream, err := s.Client.PingList(ctxWithToken(s.SimpleCtx(), \"Bearer\", overrideAuthToken), testpb.GoodPingList)\n\ts.Require().NoError(err, \"should not fail on establishing the stream\")\n\tpong, err := stream.Recv()\n\ts.Require().NoError(err, \"no error must occur\")\n\ts.Require().NotNil(pong, \"pong must not be nil\")\n}\n\n// fakeOAuth2TokenSource implements a fake oauth2.TokenSource for the purpose of credentials test.\ntype fakeOAuth2TokenSource struct {\n\taccessToken string\n}\n\nfunc (ts *fakeOAuth2TokenSource) Token() (*oauth2.Token, error) {\n\tt := &oauth2.Token{\n\t\tAccessToken: ts.accessToken,\n\t\tExpiry:      time.Now().Add(1 * time.Minute),\n\t\tTokenType:   \"bearer\",\n\t}\n\treturn t, nil\n}\n"
  },
  {
    "path": "interceptors/auth/doc.go",
    "content": "// Copyright (c) The go-grpc-middleware Authors.\n// Licensed under the Apache License 2.0.\n\n/*\nPackage auth is a middleware that authenticates incoming gRPC requests.\n\n`auth` a generic server-side auth middleware for gRPC.\n\n# Server Side Auth Middleware\n\nIt allows for easy assertion of `:authorization` headers in gRPC calls, be it HTTP Basic auth, or\nOAuth2 Bearer tokens.\n\nThe middleware takes a user-customizable `AuthFunc`, which can be customized to verify and extract\nauth information from the request. The extracted information can be put in the `context.Context` of\nhandlers downstream for retrieval.\n\nIt also allows for per-service implementation overrides of `AuthFunc`. See `ServiceAuthFuncOverride`.\n\nPlease see examples for simple examples of use.\n*/\npackage auth\n"
  },
  {
    "path": "interceptors/auth/examples_test.go",
    "content": "// Copyright (c) The go-grpc-middleware Authors.\n// Licensed under the Apache License 2.0.\n\npackage auth_test\n\nimport (\n\t\"context\"\n\t\"log\"\n\n\t\"github.com/grpc-ecosystem/go-grpc-middleware/v2/interceptors/auth\"\n\t\"github.com/grpc-ecosystem/go-grpc-middleware/v2/interceptors/logging\"\n\t\"github.com/grpc-ecosystem/go-grpc-middleware/v2/testing/testpb\"\n\t\"google.golang.org/grpc\"\n\t\"google.golang.org/grpc/codes\"\n\t\"google.golang.org/grpc/status\"\n)\n\ntype tokenInfoKey struct{}\n\nfunc parseToken(token string) (struct{}, error) {\n\treturn struct{}{}, nil\n}\n\nfunc userClaimFromToken(struct{}) string {\n\treturn \"foobar\"\n}\n\n// exampleAuthFunc is used by a middleware to authenticate requests\nfunc exampleAuthFunc(ctx context.Context) (context.Context, error) {\n\ttoken, err := auth.AuthFromMD(ctx, \"bearer\")\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\ttokenInfo, err := parseToken(token)\n\tif err != nil {\n\t\treturn nil, status.Errorf(codes.Unauthenticated, \"invalid auth token: %v\", err)\n\t}\n\n\tctx = logging.InjectFields(ctx, logging.Fields{\"auth.sub\", userClaimFromToken(tokenInfo)})\n\n\t// WARNING: In production define your own type to avoid context collisions.\n\treturn context.WithValue(ctx, tokenInfoKey{}, tokenInfo), nil\n}\n\n// Simple example of server initialization code.\nfunc Example_serverConfig() {\n\t_ = grpc.NewServer(\n\t\tgrpc.StreamInterceptor(auth.StreamServerInterceptor(exampleAuthFunc)),\n\t\tgrpc.UnaryInterceptor(auth.UnaryServerInterceptor(exampleAuthFunc)),\n\t)\n}\n\ntype gRPCServerAuthenticated struct {\n\ttestpb.UnimplementedTestServiceServer\n}\n\n// Ping only can be called by client when authenticated by exampleAuthFunc.\nfunc (s *gRPCServerAuthenticated) Ping(_ context.Context, ping *testpb.PingRequest) (*testpb.PingResponse, error) {\n\treturn &testpb.PingResponse{Value: ping.Value, Counter: 0}, nil\n}\n\ntype gRPCServerUnauthenticated struct {\n\ttestpb.UnimplementedTestServiceServer\n}\n\n// Ping can be called by client without being authenticated by exampleAuthFunc as AuthFuncOverride is called instead.\nfunc (s *gRPCServerUnauthenticated) Ping(_ context.Context, _ *testpb.PingRequest) (*testpb.PingResponse, error) {\n\treturn nil, status.Error(codes.Unauthenticated, \"no access\")\n}\n\n// AuthFuncOverride is called instead of exampleAuthFunc.\nfunc (s *gRPCServerUnauthenticated) AuthFuncOverride(ctx context.Context, fullMethodName string) (context.Context, error) {\n\tlog.Println(\"client is calling method:\", fullMethodName)\n\treturn ctx, nil\n}\n\n// Simple example of server initialization code with AuthFuncOverride method.\nfunc Example_serverConfigWithAuthOverride() {\n\tserver := grpc.NewServer(\n\t\tgrpc.StreamInterceptor(auth.StreamServerInterceptor(exampleAuthFunc)),\n\t\tgrpc.UnaryInterceptor(auth.UnaryServerInterceptor(exampleAuthFunc)),\n\t)\n\n\toverrideActive := true\n\n\tif overrideActive {\n\t\ttestpb.RegisterTestServiceServer(server, &gRPCServerUnauthenticated{})\n\t} else {\n\t\ttestpb.RegisterTestServiceServer(server, &gRPCServerAuthenticated{})\n\t}\n}\n"
  },
  {
    "path": "interceptors/auth/metadata.go",
    "content": "// Copyright (c) The go-grpc-middleware Authors.\n// Licensed under the Apache License 2.0.\n\npackage auth\n\nimport (\n\t\"context\"\n\t\"strings\"\n\n\t\"google.golang.org/grpc/codes\"\n\t\"google.golang.org/grpc/metadata\"\n\t\"google.golang.org/grpc/status\"\n)\n\nconst (\n\theaderAuthorize = \"authorization\"\n)\n\n// AuthFromMD is a helper function for extracting the :authorization header from the gRPC metadata of the request.\n//\n// It expects the `:authorization` header to be of a certain scheme (e.g. `basic`, `bearer`), in a\n// case-insensitive format (see rfc2617, sec 1.2). If no such authorization is found, or the token\n// is of wrong scheme, an error with gRPC status `Unauthenticated` is returned.\nfunc AuthFromMD(ctx context.Context, expectedScheme string) (string, error) {\n\tvals := metadata.ValueFromIncomingContext(ctx, headerAuthorize)\n\tif len(vals) == 0 {\n\t\treturn \"\", status.Error(codes.Unauthenticated, \"Request unauthenticated with \"+expectedScheme)\n\t}\n\tscheme, token, found := strings.Cut(vals[0], \" \")\n\tif !found {\n\t\treturn \"\", status.Error(codes.Unauthenticated, \"Bad authorization string\")\n\t}\n\tif !strings.EqualFold(scheme, expectedScheme) {\n\t\treturn \"\", status.Error(codes.Unauthenticated, \"Request unauthenticated with \"+expectedScheme)\n\t}\n\treturn token, nil\n}\n"
  },
  {
    "path": "interceptors/auth/metadata_test.go",
    "content": "// Copyright (c) The go-grpc-middleware Authors.\n// Licensed under the Apache License 2.0.\n\npackage auth\n\nimport (\n\t\"context\"\n\t\"testing\"\n\n\t\"github.com/grpc-ecosystem/go-grpc-middleware/v2/metadata\"\n\t\"github.com/stretchr/testify/assert\"\n\t\"github.com/stretchr/testify/require\"\n\t\"google.golang.org/grpc/codes\"\n\tgrpcMetadata \"google.golang.org/grpc/metadata\"\n\t\"google.golang.org/grpc/status\"\n)\n\nfunc TestAuthFromMD(t *testing.T) {\n\tfor _, run := range []struct {\n\t\tmd      grpcMetadata.MD\n\t\tvalue   string\n\t\terrCode codes.Code\n\t\tmsg     string\n\t}{\n\t\t{\n\t\t\tmd:    grpcMetadata.Pairs(\"authorization\", \"bearer some_token\"),\n\t\t\tvalue: \"some_token\",\n\t\t\tmsg:   \"must extract simple bearer tokens without case checking\",\n\t\t},\n\t\t{\n\t\t\tmd:    grpcMetadata.Pairs(\"authorization\", \"Bearer some_token\"),\n\t\t\tvalue: \"some_token\",\n\t\t\tmsg:   \"must extract simple bearer tokens with case checking\",\n\t\t},\n\t\t{\n\t\t\tmd:    grpcMetadata.Pairs(\"authorization\", \"Bearer some multi string bearer\"),\n\t\t\tvalue: \"some multi string bearer\",\n\t\t\tmsg:   \"must handle string based bearers\",\n\t\t},\n\t\t{\n\t\t\tmd:      grpcMetadata.Pairs(\"authorization\", \"Basic login:passwd\"),\n\t\t\tvalue:   \"\",\n\t\t\terrCode: codes.Unauthenticated,\n\t\t\tmsg:     \"must check authentication type\",\n\t\t},\n\t\t{\n\t\t\tmd:      grpcMetadata.Pairs(\"authorization\", \"Basic login:passwd\", \"authorization\", \"bearer some_token\"),\n\t\t\tvalue:   \"\",\n\t\t\terrCode: codes.Unauthenticated,\n\t\t\tmsg:     \"must not allow multiple authentication methods\",\n\t\t},\n\t\t{\n\t\t\tmd:      grpcMetadata.Pairs(\"authorization\", \"\"),\n\t\t\tvalue:   \"\",\n\t\t\terrCode: codes.Unauthenticated,\n\t\t\tmsg:     \"authorization string must not be empty\",\n\t\t},\n\t\t{\n\t\t\tmd:      grpcMetadata.Pairs(\"authorization\", \"Bearer\"),\n\t\t\tvalue:   \"\",\n\t\t\terrCode: codes.Unauthenticated,\n\t\t\tmsg:     \"bearer token must not be empty\",\n\t\t},\n\t} {\n\t\tctx := metadata.MD(run.md).ToIncoming(context.TODO())\n\t\tout, err := AuthFromMD(ctx, \"bearer\")\n\t\tif run.errCode != codes.OK {\n\t\t\tassert.Equal(t, run.errCode, status.Code(err), run.msg)\n\t\t} else {\n\t\t\trequire.NoError(t, err, run.msg)\n\t\t}\n\t\tassert.Equal(t, run.value, out, run.msg)\n\t}\n}\n"
  },
  {
    "path": "interceptors/callmeta.go",
    "content": "// Copyright (c) The go-grpc-middleware Authors.\n// Licensed under the Apache License 2.0.\n\npackage interceptors\n\nimport (\n\t\"fmt\"\n\t\"strings\"\n\n\t\"google.golang.org/grpc\"\n)\n\nfunc splitFullMethodName(fullMethod string) (string, string) {\n\tfullMethod = strings.TrimPrefix(fullMethod, \"/\") // remove leading slash\n\tif i := strings.Index(fullMethod, \"/\"); i >= 0 {\n\t\treturn fullMethod[:i], fullMethod[i+1:]\n\t}\n\treturn \"unknown\", \"unknown\"\n}\n\ntype CallMeta struct {\n\tReqOrNil any\n\tTyp      GRPCType\n\tService  string\n\tMethod   string\n\tIsClient bool\n}\n\nfunc NewClientCallMeta(fullMethod string, streamDesc *grpc.StreamDesc, reqOrNil any) CallMeta {\n\tc := CallMeta{IsClient: true, ReqOrNil: reqOrNil, Typ: Unary}\n\tif streamDesc != nil {\n\t\tc.Typ = clientStreamType(streamDesc)\n\t}\n\tc.Service, c.Method = splitFullMethodName(fullMethod)\n\treturn c\n}\n\nfunc NewServerCallMeta(fullMethod string, streamInfo *grpc.StreamServerInfo, reqOrNil any) CallMeta {\n\tc := CallMeta{IsClient: false, ReqOrNil: reqOrNil, Typ: Unary}\n\tif streamInfo != nil {\n\t\tc.Typ = serverStreamType(streamInfo)\n\t}\n\tc.Service, c.Method = splitFullMethodName(fullMethod)\n\treturn c\n}\n\nfunc (c CallMeta) FullMethod() string {\n\treturn fmt.Sprintf(\"/%s/%s\", c.Service, c.Method)\n}\n\nfunc clientStreamType(desc *grpc.StreamDesc) GRPCType {\n\tif desc.ClientStreams && !desc.ServerStreams {\n\t\treturn ClientStream\n\t} else if !desc.ClientStreams && desc.ServerStreams {\n\t\treturn ServerStream\n\t}\n\treturn BidiStream\n}\n\nfunc serverStreamType(info *grpc.StreamServerInfo) GRPCType {\n\tif info.IsClientStream && !info.IsServerStream {\n\t\treturn ClientStream\n\t} else if !info.IsClientStream && info.IsServerStream {\n\t\treturn ServerStream\n\t}\n\treturn BidiStream\n}\n"
  },
  {
    "path": "interceptors/client.go",
    "content": "// Copyright (c) The go-grpc-middleware Authors.\n// Licensed under the Apache License 2.0.\n\n// Go gRPC Middleware monitoring interceptors for client-side gRPC.\n\npackage interceptors\n\nimport (\n\t\"context\"\n\t\"errors\"\n\t\"io\"\n\t\"time\"\n\n\t\"google.golang.org/grpc\"\n)\n\n// UnaryClientInterceptor is a gRPC client-side interceptor that provides reporting for Unary RPCs.\nfunc UnaryClientInterceptor(reportable ClientReportable) grpc.UnaryClientInterceptor {\n\treturn func(ctx context.Context, method string, req, reply any, cc *grpc.ClientConn, invoker grpc.UnaryInvoker, opts ...grpc.CallOption) error {\n\t\tr := newReport(NewClientCallMeta(method, nil, req))\n\t\treporter, newCtx := reportable.ClientReporter(ctx, r.callMeta)\n\n\t\treporter.PostMsgSend(req, nil, time.Since(r.startTime))\n\t\terr := invoker(newCtx, method, req, reply, cc, opts...)\n\t\treporter.PostMsgReceive(reply, err, time.Since(r.startTime))\n\t\treporter.PostCall(err, time.Since(r.startTime))\n\t\treturn err\n\t}\n}\n\n// StreamClientInterceptor is a gRPC client-side interceptor that provides reporting for Stream RPCs.\nfunc StreamClientInterceptor(reportable ClientReportable) grpc.StreamClientInterceptor {\n\treturn func(ctx context.Context, desc *grpc.StreamDesc, cc *grpc.ClientConn, method string, streamer grpc.Streamer, opts ...grpc.CallOption) (grpc.ClientStream, error) {\n\t\tr := newReport(NewClientCallMeta(method, desc, nil))\n\t\treporter, newCtx := reportable.ClientReporter(ctx, r.callMeta)\n\n\t\tclientStream, err := streamer(newCtx, desc, cc, method, opts...)\n\t\tif err != nil {\n\t\t\treporter.PostCall(err, time.Since(r.startTime))\n\t\t\treturn nil, err\n\t\t}\n\t\treturn &monitoredClientStream{ClientStream: clientStream, startTime: r.startTime, hasServerStream: desc.ServerStreams, reporter: reporter}, nil\n\t}\n}\n\n// monitoredClientStream wraps grpc.ClientStream allowing each Sent/Recv of message to report.\ntype monitoredClientStream struct {\n\tgrpc.ClientStream\n\n\tstartTime       time.Time\n\thasServerStream bool\n\treporter        Reporter\n}\n\nfunc (s *monitoredClientStream) SendMsg(m any) error {\n\tstart := time.Now()\n\terr := s.ClientStream.SendMsg(m)\n\ts.reporter.PostMsgSend(m, err, time.Since(start))\n\treturn err\n}\n\nfunc (s *monitoredClientStream) RecvMsg(m any) error {\n\tstart := time.Now()\n\terr := s.ClientStream.RecvMsg(m)\n\ts.reporter.PostMsgReceive(m, err, time.Since(start))\n\n\tif s.hasServerStream {\n\t\tif err == nil {\n\t\t\treturn nil\n\t\t}\n\t\tvar postErr error\n\t\tif !errors.Is(err, io.EOF) {\n\t\t\tpostErr = err\n\t\t}\n\t\ts.reporter.PostCall(postErr, time.Since(s.startTime))\n\t} else {\n\t\ts.reporter.PostCall(err, time.Since(s.startTime))\n\t}\n\treturn err\n}\n"
  },
  {
    "path": "interceptors/client_test.go",
    "content": "// Copyright (c) The go-grpc-middleware Authors.\n// Licensed under the Apache License 2.0.\n\npackage interceptors\n\nimport (\n\t\"context\"\n\t\"errors\"\n\t\"io\"\n\t\"net\"\n\t\"sync\"\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/grpc-ecosystem/go-grpc-middleware/v2/testing/testpb\"\n\t\"github.com/stretchr/testify/require\"\n\t\"github.com/stretchr/testify/suite\"\n\t\"google.golang.org/grpc\"\n\t\"google.golang.org/grpc/codes\"\n\t\"google.golang.org/grpc/credentials/insecure\"\n\t\"google.golang.org/grpc/status\"\n)\n\ntype mockReport struct {\n\tCallMeta\n\n\tpostCalls       []error\n\tpostMsgSends    []error\n\tpostMsgReceives []error\n}\n\ntype mockReportable struct {\n\tm    sync.Mutex\n\tcurr *mockReport\n\n\treports []*mockReport\n}\n\n// Equal replaces require.Equal as google.golang.org/grpc/status errors are not easily comparable.\nfunc (m *mockReportable) Equal(t *testing.T, expected []*mockReport) {\n\tt.Helper()\n\n\trequire.Len(t, expected, len(m.reports))\n\tfor i, e := range m.reports {\n\t\trequire.Equal(t, expected[i].Typ, e.Typ, \"%v\", i)\n\t\trequire.Equal(t, expected[i].Service, e.Service, \"%v\", i)\n\t\trequire.Equal(t, expected[i].Method, e.Method, \"%v\", i)\n\n\t\trequire.Len(t, expected[i].postCalls, len(e.postCalls), \"%v\", i)\n\t\tfor k, err := range e.postCalls {\n\t\t\tif expected[i].postCalls[k] == nil {\n\t\t\t\trequire.NoError(t, err)\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\trequire.EqualError(t, err, expected[i].postCalls[k].Error(), \"%v %v\", i, k)\n\t\t}\n\t\trequire.Len(t, expected[i].postMsgSends, len(e.postMsgSends), \"%v\", i)\n\t\tfor k, err := range e.postMsgSends {\n\t\t\tif expected[i].postMsgSends[k] == nil {\n\t\t\t\trequire.NoError(t, err)\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\trequire.Equal(t, expected[i].postMsgSends[k].Error(), err.Error(), \"%v %v\", i, k)\n\t\t}\n\t\trequire.Len(t, expected[i].postMsgReceives, len(e.postMsgReceives), \"%v\", i)\n\t\tfor k, err := range e.postMsgReceives {\n\t\t\tif expected[i].postMsgReceives[k] == nil {\n\t\t\t\trequire.NoError(t, err)\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\trequire.Equal(t, expected[i].postMsgReceives[k].Error(), err.Error(), \"%v %v\", i, k)\n\t\t}\n\n\t}\n}\n\nfunc (m *mockReportable) requireOneReportWithRetry(ctx context.Context, t *testing.T, expected *mockReport) {\n\tfor {\n\t\tselect {\n\t\tcase <-ctx.Done():\n\t\t\tt.Fatal(\"timeout waiting for mockReport\")\n\t\tcase <-time.After(200 * time.Millisecond):\n\t\t}\n\n\t\tm.m.Lock()\n\t\tif len(m.reports) == 0 {\n\t\t\tm.m.Unlock()\n\t\t\tcontinue\n\t\t}\n\t\tdefer m.m.Unlock()\n\t\tbreak\n\t}\n\t// Even without reading, we should get initial mockReport.\n\tm.Equal(t, []*mockReport{expected})\n}\n\nfunc (m *mockReportable) PostCall(err error, _ time.Duration) {\n\tm.m.Lock()\n\tdefer m.m.Unlock()\n\tm.curr.postCalls = append(m.curr.postCalls, err)\n}\n\nfunc (m *mockReportable) PostMsgSend(_ any, err error, _ time.Duration) {\n\tm.m.Lock()\n\tdefer m.m.Unlock()\n\tm.curr.postMsgSends = append(m.curr.postMsgSends, err)\n}\n\nfunc (m *mockReportable) PostMsgReceive(_ any, err error, _ time.Duration) {\n\tm.m.Lock()\n\tdefer m.m.Unlock()\n\tm.curr.postMsgReceives = append(m.curr.postMsgReceives, err)\n}\n\nfunc (m *mockReportable) ClientReporter(ctx context.Context, c CallMeta) (Reporter, context.Context) {\n\tm.curr = &mockReport{CallMeta: c}\n\tm.reports = append(m.reports, m.curr)\n\treturn m, ctx\n}\n\nfunc (m *mockReportable) ServerReporter(ctx context.Context, c CallMeta) (Reporter, context.Context) {\n\tm.curr = &mockReport{CallMeta: c}\n\tm.reports = append(m.reports, m.curr)\n\treturn m, ctx\n}\n\nfunc TestClientInterceptorSuite(t *testing.T) {\n\tsuite.Run(t, &ClientInterceptorTestSuite{})\n}\n\ntype ClientInterceptorTestSuite struct {\n\tsuite.Suite\n\n\tserverListener net.Listener\n\tserver         *grpc.Server\n\tclientConn     *grpc.ClientConn\n\ttestClient     testpb.TestServiceClient\n\tctx            context.Context\n\tcancel         context.CancelFunc\n\n\tmock *mockReportable\n\n\tstopped chan error\n}\n\nfunc (s *ClientInterceptorTestSuite) SetupSuite() {\n\tvar err error\n\ts.stopped = make(chan error)\n\ts.mock = &mockReportable{}\n\n\ts.serverListener, err = net.Listen(\"tcp\", \"127.0.0.1:0\")\n\ts.Require().NoError(err, \"must be able to allocate a port for serverListener\")\n\n\ts.server = grpc.NewServer()\n\ttestpb.RegisterTestServiceServer(s.server, &testpb.TestPingService{})\n\n\tgo func() {\n\t\tdefer close(s.stopped)\n\t\ts.stopped <- s.server.Serve(s.serverListener)\n\t}()\n\n\t// This is the point where we hook up the interceptor.\n\ts.clientConn, err = grpc.NewClient(\n\t\ts.serverListener.Addr().String(),\n\t\tgrpc.WithTransportCredentials(insecure.NewCredentials()),\n\t\tgrpc.WithUnaryInterceptor(UnaryClientInterceptor(s.mock)),\n\t\tgrpc.WithStreamInterceptor(StreamClientInterceptor(s.mock)),\n\t)\n\ts.Require().NoError(err, \"must not error on client Dial\")\n\ts.testClient = testpb.NewTestServiceClient(s.clientConn)\n}\n\nfunc (s *ClientInterceptorTestSuite) SetupTest() {\n\tselect {\n\tcase err := <-s.stopped:\n\t\ts.T().Fatal(\"gRPC server stopped prematurely\", err)\n\tdefault:\n\t}\n\n\t// Make all RPC calls last at most 2 sec, meaning all async issues or deadlock will not kill tests.\n\ts.ctx, s.cancel = context.WithTimeout(context.TODO(), 2*time.Second)\n\ts.mock.reports = s.mock.reports[:0]\n}\n\nfunc (s *ClientInterceptorTestSuite) TearDownSuite() {\n\tif s.serverListener != nil {\n\t\ts.server.Stop()\n\t\ts.T().Logf(\"stopped grpc.Server at: %v\", s.serverListener.Addr().String())\n\t\t_ = s.serverListener.Close()\n\t}\n\tif s.clientConn != nil {\n\t\t_ = s.clientConn.Close()\n\t}\n\t<-s.stopped\n}\n\nfunc (s *ClientInterceptorTestSuite) TearDownTest() {\n\ts.cancel()\n}\n\nfunc (s *ClientInterceptorTestSuite) TestUnaryReporting() {\n\t_, err := s.testClient.PingEmpty(s.ctx, &testpb.PingEmptyRequest{}) // should return with code=OK\n\ts.Require().NoError(err)\n\ts.mock.Equal(s.T(), []*mockReport{{\n\t\tCallMeta:        CallMeta{Typ: Unary, Service: testpb.TestServiceFullName, Method: \"PingEmpty\"},\n\t\tpostCalls:       []error{nil},\n\t\tpostMsgReceives: []error{nil},\n\t\tpostMsgSends:    []error{nil},\n\t}})\n\ts.mock.reports = s.mock.reports[:0] // Reset.\n\n\t_, err = s.testClient.PingError(s.ctx, &testpb.PingErrorRequest{ErrorCodeReturned: uint32(codes.FailedPrecondition)}) // should return with code=FailedPrecondition\n\ts.Require().Error(err)\n\ts.mock.Equal(s.T(), []*mockReport{{\n\t\tCallMeta:        CallMeta{Typ: Unary, Service: testpb.TestServiceFullName, Method: \"PingError\"},\n\t\tpostCalls:       []error{status.Error(codes.FailedPrecondition, \"Userspace error\")},\n\t\tpostMsgReceives: []error{status.Error(codes.FailedPrecondition, \"Userspace error\")},\n\t\tpostMsgSends:    []error{nil},\n\t}})\n}\n\nfunc (s *ClientInterceptorTestSuite) TestStartedListReporting() {\n\t_, err := s.testClient.PingList(s.ctx, &testpb.PingListRequest{})\n\ts.Require().NoError(err)\n\n\t// Even without reading, we should get initial mockReport.\n\ts.mock.Equal(s.T(), []*mockReport{{\n\t\tCallMeta:     CallMeta{Typ: ServerStream, Service: testpb.TestServiceFullName, Method: \"PingList\"},\n\t\tpostMsgSends: []error{nil},\n\t}})\n\n\t_, err = s.testClient.PingList(s.ctx, &testpb.PingListRequest{ErrorCodeReturned: uint32(codes.FailedPrecondition)})\n\ts.Require().NoError(err, \"PingList must not fail immediately\")\n\n\t// Even without reading, we should get initial mockReport.\n\ts.mock.Equal(s.T(), []*mockReport{{\n\t\tCallMeta:     CallMeta{Typ: ServerStream, Service: testpb.TestServiceFullName, Method: \"PingList\"},\n\t\tpostMsgSends: []error{nil},\n\t}, {\n\t\tCallMeta:     CallMeta{Typ: ServerStream, Service: testpb.TestServiceFullName, Method: \"PingList\"},\n\t\tpostMsgSends: []error{nil},\n\t}})\n}\n\nfunc (s *ClientInterceptorTestSuite) TestListReporting() {\n\tss, err := s.testClient.PingList(s.ctx, &testpb.PingListRequest{})\n\ts.Require().NoError(err)\n\n\t// Do a read, just for kicks.\n\tcount := 0\n\tfor {\n\t\t_, err = ss.Recv()\n\t\tif errors.Is(err, io.EOF) {\n\t\t\tbreak\n\t\t}\n\t\ts.Require().NoError(err, \"reading pingList shouldn't fail\")\n\t\tcount++\n\t}\n\ts.Require().Equal(testpb.ListResponseCount, count, \"Number of received msg on the wire must match\")\n\n\ts.mock.Equal(s.T(), []*mockReport{{\n\t\tCallMeta:        CallMeta{Typ: ServerStream, Service: testpb.TestServiceFullName, Method: \"PingList\"},\n\t\tpostCalls:       []error{nil},\n\t\tpostMsgReceives: append(make([]error, testpb.ListResponseCount), io.EOF),\n\t\tpostMsgSends:    []error{nil},\n\t}})\n\ts.mock.reports = s.mock.reports[:0] // Reset.\n\n\tss, err = s.testClient.PingList(s.ctx, &testpb.PingListRequest{ErrorCodeReturned: uint32(codes.FailedPrecondition)})\n\ts.Require().NoError(err, \"PingList must not fail immediately\")\n\n\t// Do a read, just to propagate errors.\n\t_, err = ss.Recv()\n\ts.Require().Error(err)\n\tst, _ := status.FromError(err)\n\ts.Require().Equal(codes.FailedPrecondition, st.Code(), \"Recv must return FailedPrecondition, otherwise the test is wrong\")\n\n\t// Next same.\n\t_, err = ss.Recv()\n\ts.Require().Error(err)\n\tst, _ = status.FromError(err)\n\ts.Require().Equal(codes.FailedPrecondition, st.Code(), \"Recv must return FailedPrecondition, otherwise the test is wrong\")\n\n\ts.mock.Equal(s.T(), []*mockReport{{\n\t\tCallMeta:        CallMeta{Typ: ServerStream, Service: testpb.TestServiceFullName, Method: \"PingList\"},\n\t\tpostCalls:       []error{status.Error(codes.FailedPrecondition, \"foobar\"), status.Error(codes.FailedPrecondition, \"foobar\")},\n\t\tpostMsgReceives: []error{status.Error(codes.FailedPrecondition, \"foobar\"), status.Error(codes.FailedPrecondition, \"foobar\")},\n\t\tpostMsgSends:    []error{nil},\n\t}})\n}\n\nfunc (s *ClientInterceptorTestSuite) TestBiStreamingReporting() {\n\tss, err := s.testClient.PingStream(s.ctx)\n\ts.Require().NoError(err)\n\n\twg := sync.WaitGroup{}\n\tdefer func() {\n\t\t_ = ss.CloseSend()\n\t\twg.Wait()\n\t}()\n\n\tcount := 0\n\twg.Add(1)\n\tgo func() {\n\t\tdefer wg.Done()\n\t\tfor s.ctx.Err() == nil {\n\n\t\t\t_, err := ss.Recv()\n\t\t\tif errors.Is(err, io.EOF) {\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tif !s.Assert().NoError(err, \"reading pingStream shouldn't fail\") {\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tcount++\n\t\t}\n\t}()\n\tfor i := 0; i < 100; i++ {\n\t\ts.Require().NoError(ss.Send(&testpb.PingStreamRequest{}), \"sending shouldn't fail\")\n\t}\n\n\ts.Require().NoError(ss.CloseSend())\n\twg.Wait()\n\n\ts.Require().Equal(100, count, \"Number of received msg on the wire must match\")\n\ts.mock.Equal(s.T(), []*mockReport{{\n\t\tCallMeta:        CallMeta{Typ: BidiStream, Service: testpb.TestServiceFullName, Method: \"PingStream\"},\n\t\tpostCalls:       []error{nil},\n\t\tpostMsgReceives: append(make([]error, 100), io.EOF),\n\t\tpostMsgSends:    make([]error, 100),\n\t}})\n}\n\nfunc (s *ClientInterceptorTestSuite) TestClientStream() {\n\tss, err := s.testClient.PingClientStream(s.ctx)\n\ts.Require().NoError(err)\n\n\tdefer func() {\n\t\t_, _ = ss.CloseAndRecv()\n\t}()\n\n\tfor i := 0; i < 100; i++ {\n\t\ts.Require().NoError(ss.Send(&testpb.PingClientStreamRequest{}), \"sending shouldn't fail\")\n\t}\n\n\t_, err = ss.CloseAndRecv()\n\ts.Require().NoError(err)\n\n\ts.mock.Equal(s.T(), []*mockReport{{\n\t\tCallMeta:        CallMeta{Typ: ClientStream, Service: testpb.TestServiceFullName, Method: \"PingClientStream\"},\n\t\tpostCalls:       []error{nil},\n\t\tpostMsgReceives: []error{nil},\n\t\tpostMsgSends:    make([]error, 100),\n\t}})\n}\n"
  },
  {
    "path": "interceptors/doc.go",
    "content": "// Copyright (c) The go-grpc-middleware Authors.\n// Licensed under the Apache License 2.0.\n\n//\n/*\ninterceptor is an internal package used by higher level middlewares. It allows injecting custom code in various\nplaces of the gRPC lifecycle.\n\nThis particular package is intended for use by other middleware, metric, logging or otherwise.\nThis allows code to be shared between different implementations.\n*/\npackage interceptors\n"
  },
  {
    "path": "interceptors/logging/doc.go",
    "content": "// Copyright (c) The go-grpc-middleware Authors.\n// Licensed under the Apache License 2.0.\n\n/*\nPackage logging is a \"parent\" package for gRPC logging middlewares.\n\nThe gRPC logging middleware populates request-scoped data to `logging.Fields` that relate to the current gRPC call\n(e.g. service and method names). You can extract/inject data in the propagated context using `logging.ExtractFields` and `logging.InjectFields`.\n\nOnce the gRPC logging middleware has added the gRPC specific Fields to the ctx they will then be written with the log lines.\n\nAll logging middleware will emit a final log statement. It is based on the error returned by the handler function,\nthe gRPC status code, an error (if any) and it emits at a level controlled via `WithLevels`. You can control this behavior\nusing `WithDecider`.\n\n# This parent package\n\nThis particular package is intended for use by other middleware, logging or otherwise. It contains interfaces that other\nlogging middlewares *could* share. This allows code to be shared between different implementations.\n\n# Field names\n\nAll field names of loggers follow the OpenTracing semantics definitions, with `grpc.` prefix if needed:\nhttps://github.com/opentracing/specification/blob/master/semantic_conventions.md\n\nImplementations:\n\n* providers/kit\n* providers/logr\n* providers/logrus\n* providers/phuslog\n* providers/slog\n* providers/zap\n* providers/zerolog\n*/\npackage logging\n"
  },
  {
    "path": "interceptors/logging/examples/go.mod",
    "content": "module github.com/grpc-ecosystem/go-grpc-middleware/interceptors/logging/examples\n\ngo 1.23.0\n\nrequire (\n\tgithub.com/go-kit/log v0.2.1\n\tgithub.com/go-logr/logr v1.4.3\n\tgithub.com/grpc-ecosystem/go-grpc-middleware/v2 v2.0.0\n\tgithub.com/rs/zerolog v1.29.0\n\tgithub.com/sirupsen/logrus v1.9.0\n\tgo.uber.org/zap v1.24.0\n\tgoogle.golang.org/grpc v1.74.2\n\tk8s.io/klog/v2 v2.90.1\n)\n\nrequire (\n\tgithub.com/go-logfmt/logfmt v0.5.1 // indirect\n\tgithub.com/mattn/go-colorable v0.1.12 // indirect\n\tgithub.com/mattn/go-isatty v0.0.14 // indirect\n\tgo.uber.org/atomic v1.7.0 // indirect\n\tgo.uber.org/multierr v1.6.0 // indirect\n\tgolang.org/x/net v0.40.0 // indirect\n\tgolang.org/x/sys v0.33.0 // indirect\n\tgolang.org/x/text v0.25.0 // indirect\n\tgoogle.golang.org/genproto/googleapis/rpc v0.0.0-20250528174236-200df99c418a // indirect\n\tgoogle.golang.org/protobuf v1.36.6 // indirect\n)\n\nreplace github.com/grpc-ecosystem/go-grpc-middleware/v2 => ../../../\n"
  },
  {
    "path": "interceptors/logging/examples/go.sum",
    "content": "github.com/benbjohnson/clock v1.1.0 h1:Q92kusRqC1XV2MjkWETPvjJVqKetz1OzxZB7mHJLju8=\ngithub.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA=\ngithub.com/coreos/go-systemd/v22 v22.3.3-0.20220203105225-a9a7ef127534/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=\ngithub.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=\ngithub.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=\ngithub.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=\ngithub.com/go-kit/log v0.2.1 h1:MRVx0/zhvdseW+Gza6N9rVzU/IVzaeE1SFI4raAhmBU=\ngithub.com/go-kit/log v0.2.1/go.mod h1:NwTd00d/i8cPZ3xOwwiv2PO5MOcx78fFErGNcVmBjv0=\ngithub.com/go-logfmt/logfmt v0.5.1 h1:otpy5pqBCBZ1ng9RQ0dPu4PN7ba75Y/aA+UpowDyNVA=\ngithub.com/go-logfmt/logfmt v0.5.1/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs=\ngithub.com/go-logr/logr v1.2.0/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=\ngithub.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI=\ngithub.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=\ngithub.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=\ngithub.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=\ngithub.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=\ngithub.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek=\ngithub.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps=\ngithub.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=\ngithub.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=\ngithub.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=\ngithub.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=\ngithub.com/mattn/go-colorable v0.1.12 h1:jF+Du6AlPIjs2BiUiQlKOX0rt3SujHxPnksPKZbaA40=\ngithub.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4=\ngithub.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y=\ngithub.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=\ngithub.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=\ngithub.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=\ngithub.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=\ngithub.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=\ngithub.com/rs/xid v1.4.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg=\ngithub.com/rs/zerolog v1.29.0 h1:Zes4hju04hjbvkVkOhdl2HpZa+0PmVwigmo8XoORE5w=\ngithub.com/rs/zerolog v1.29.0/go.mod h1:NILgTygv/Uej1ra5XxGf82ZFSLk58MFGAUS2o6usyD0=\ngithub.com/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0=\ngithub.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=\ngithub.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=\ngithub.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=\ngithub.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=\ngithub.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=\ngithub.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=\ngo.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA=\ngo.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A=\ngo.opentelemetry.io/otel v1.36.0 h1:UumtzIklRBY6cI/lllNZlALOF5nNIzJVb16APdvgTXg=\ngo.opentelemetry.io/otel v1.36.0/go.mod h1:/TcFMXYjyRNh8khOAO9ybYkqaDBb/70aVwkNML4pP8E=\ngo.opentelemetry.io/otel/metric v1.36.0 h1:MoWPKVhQvJ+eeXWHFBOPoBOi20jh6Iq2CcCREuTYufE=\ngo.opentelemetry.io/otel/metric v1.36.0/go.mod h1:zC7Ks+yeyJt4xig9DEw9kuUFe5C3zLbVjV2PzT6qzbs=\ngo.opentelemetry.io/otel/sdk v1.36.0 h1:b6SYIuLRs88ztox4EyrvRti80uXIFy+Sqzoh9kFULbs=\ngo.opentelemetry.io/otel/sdk v1.36.0/go.mod h1:+lC+mTgD+MUWfjJubi2vvXWcVxyr9rmlshZni72pXeY=\ngo.opentelemetry.io/otel/sdk/metric v1.36.0 h1:r0ntwwGosWGaa0CrSt8cuNuTcccMXERFwHX4dThiPis=\ngo.opentelemetry.io/otel/sdk/metric v1.36.0/go.mod h1:qTNOhFDfKRwX0yXOqJYegL5WRaW376QbB7P4Pb0qva4=\ngo.opentelemetry.io/otel/trace v1.36.0 h1:ahxWNuqZjpdiFAyrIoQ4GIiAIhxAunQR6MUoKrsNd4w=\ngo.opentelemetry.io/otel/trace v1.36.0/go.mod h1:gQ+OnDZzrybY4k4seLzPAWNwVBBVlF2szhehOBB/tGA=\ngo.uber.org/atomic v1.7.0 h1:ADUqmZGgLDDfbSL9ZmPxKTybcoEYHgpYfELNoN+7hsw=\ngo.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=\ngo.uber.org/goleak v1.1.11 h1:wy28qYRKZgnJTxGxvye5/wgWr1EKjmUDGYox5mGlRlI=\ngo.uber.org/goleak v1.1.11/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ=\ngo.uber.org/multierr v1.6.0 h1:y6IPFStTAIT5Ytl7/XYmHvzXQ7S3g/IeZW9hyZ5thw4=\ngo.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU=\ngo.uber.org/zap v1.24.0 h1:FiJd5l1UOLj0wCgbSE0rwwXHzEdAZS6hiiSnxJN/D60=\ngo.uber.org/zap v1.24.0/go.mod h1:2kMP+WWQ8aoFoedH3T2sq6iJ2yDWpHbP0f6MQbS9Gkg=\ngolang.org/x/net v0.40.0 h1:79Xs7wF06Gbdcg4kdCCIQArK11Z1hr5POQ6+fIYHNuY=\ngolang.org/x/net v0.40.0/go.mod h1:y0hY0exeL2Pku80/zKK7tpntoX23cqL3Oa6njdgRtds=\ngolang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.33.0 h1:q3i8TbbEz+JRD9ywIRlyRAQbM0qF7hu24q3teo2hbuw=\ngolang.org/x/sys v0.33.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=\ngolang.org/x/text v0.25.0 h1:qVyWApTSYLk/drJRO5mDlNYskwQznZmkpV2c8q9zls4=\ngolang.org/x/text v0.25.0/go.mod h1:WEdwpYrmk1qmdHvhkSTNPm3app7v4rsT8F2UD6+VHIA=\ngoogle.golang.org/genproto/googleapis/rpc v0.0.0-20250528174236-200df99c418a h1:v2PbRU4K3llS09c7zodFpNePeamkAwG3mPrAery9VeE=\ngoogle.golang.org/genproto/googleapis/rpc v0.0.0-20250528174236-200df99c418a/go.mod h1:qQ0YXyHHx3XkvlzUtpXDkS29lDSafHMZBAZDc03LQ3A=\ngoogle.golang.org/grpc v1.74.2 h1:WoosgB65DlWVC9FqI82dGsZhWFNBSLjQ84bjROOpMu4=\ngoogle.golang.org/grpc v1.74.2/go.mod h1:CtQ+BGjaAIXHs/5YS3i473GqwBBa1zGQNevxdeBEXrM=\ngoogle.golang.org/protobuf v1.36.6 h1:z1NpPI8ku2WgiWnf+t9wTPsn6eP1L7ksHUlkfLvd9xY=\ngoogle.golang.org/protobuf v1.36.6/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY=\ngopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=\ngopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=\ngopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=\ngopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=\nk8s.io/klog/v2 v2.90.1 h1:m4bYOKall2MmOiRaR1J+We67Do7vm9KiQVlT96lnHUw=\nk8s.io/klog/v2 v2.90.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0=\n"
  },
  {
    "path": "interceptors/logging/examples/kit/example_test.go",
    "content": "// Copyright (c) The go-grpc-middleware Authors.\n// Licensed under the Apache License 2.0.\n\npackage kit_test\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\n\t\"github.com/go-kit/log\"\n\t\"github.com/go-kit/log/level\"\n\t\"github.com/grpc-ecosystem/go-grpc-middleware/v2/interceptors/logging\"\n\t\"google.golang.org/grpc\"\n)\n\n// InterceptorLogger adapts go-kit logger to interceptor logger.\n// This code is simple enough to be copied and not imported.\nfunc InterceptorLogger(l log.Logger) logging.Logger {\n\treturn logging.LoggerFunc(func(_ context.Context, lvl logging.Level, msg string, fields ...any) {\n\t\tlargs := append([]any{\"msg\", msg}, fields...)\n\t\tswitch lvl {\n\t\tcase logging.LevelDebug:\n\t\t\t_ = level.Debug(l).Log(largs...)\n\t\tcase logging.LevelInfo:\n\t\t\t_ = level.Info(l).Log(largs...)\n\t\tcase logging.LevelWarn:\n\t\t\t_ = level.Warn(l).Log(largs...)\n\t\tcase logging.LevelError:\n\t\t\t_ = level.Error(l).Log(largs...)\n\t\tdefault:\n\t\t\tpanic(fmt.Sprintf(\"unknown level %v\", lvl))\n\t\t}\n\t})\n}\n\nfunc ExampleInterceptorLogger() {\n\tlogger := log.NewNopLogger()\n\n\topts := []logging.Option{\n\t\tlogging.WithLogOnEvents(logging.StartCall, logging.FinishCall),\n\t\t// Add any other option (check functions starting with logging.With).\n\t}\n\n\t// You can now create a server with logging instrumentation that e.g. logs when the unary or stream call is started or finished.\n\t_ = grpc.NewServer(\n\t\tgrpc.ChainUnaryInterceptor(\n\t\t\tlogging.UnaryServerInterceptor(InterceptorLogger(logger), opts...),\n\t\t\t// Add any other interceptor you want.\n\t\t),\n\t\tgrpc.ChainStreamInterceptor(\n\t\t\tlogging.StreamServerInterceptor(InterceptorLogger(logger), opts...),\n\t\t\t// Add any other interceptor you want.\n\t\t),\n\t)\n\t// ...user server.\n\n\t// Similarly you can create client that will log for the unary and stream client started or finished calls.\n\t_, _ = grpc.Dial(\n\t\t\"some-target\",\n\t\tgrpc.WithChainUnaryInterceptor(\n\t\t\tlogging.UnaryClientInterceptor(InterceptorLogger(logger), opts...),\n\t\t\t// Add any other interceptor you want.\n\t\t),\n\t\tgrpc.WithChainStreamInterceptor(\n\t\t\tlogging.StreamClientInterceptor(InterceptorLogger(logger), opts...),\n\t\t\t// Add any other interceptor you want.\n\t\t),\n\t)\n\t// Output:\n}\n"
  },
  {
    "path": "interceptors/logging/examples/log/example_test.go",
    "content": "// Copyright (c) The go-grpc-middleware Authors.\n// Licensed under the Apache License 2.0.\n\npackage log_test\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"log\"\n\t\"os\"\n\n\t\"github.com/grpc-ecosystem/go-grpc-middleware/v2/interceptors/logging\"\n\t\"google.golang.org/grpc\"\n)\n\n// InterceptorLogger adapts standard Go logger to interceptor logger.\n// This code is simple enough to be copied and not imported.\nfunc InterceptorLogger(l *log.Logger) logging.Logger {\n\treturn logging.LoggerFunc(func(_ context.Context, lvl logging.Level, msg string, fields ...any) {\n\t\tswitch lvl {\n\t\tcase logging.LevelDebug:\n\t\t\tmsg = fmt.Sprintf(\"DEBUG :%v\", msg)\n\t\tcase logging.LevelInfo:\n\t\t\tmsg = fmt.Sprintf(\"INFO :%v\", msg)\n\t\tcase logging.LevelWarn:\n\t\t\tmsg = fmt.Sprintf(\"WARN :%v\", msg)\n\t\tcase logging.LevelError:\n\t\t\tmsg = fmt.Sprintf(\"ERROR :%v\", msg)\n\t\tdefault:\n\t\t\tpanic(fmt.Sprintf(\"unknown level %v\", lvl))\n\t\t}\n\t\tl.Println(append([]any{\"msg\", msg}, fields...))\n\t})\n}\n\nfunc ExampleInterceptorLogger() {\n\tlogger := log.New(os.Stderr, \"\", log.Ldate|log.Ltime|log.Lshortfile)\n\n\topts := []logging.Option{\n\t\tlogging.WithLogOnEvents(logging.StartCall, logging.FinishCall),\n\t\t// Add any other option (check functions starting with logging.With).\n\t}\n\n\t// You can now create a server with logging instrumentation that e.g. logs when the unary or stream call is started or finished.\n\t_ = grpc.NewServer(\n\t\tgrpc.ChainUnaryInterceptor(\n\t\t\tlogging.UnaryServerInterceptor(InterceptorLogger(logger), opts...),\n\t\t\t// Add any other interceptor you want.\n\t\t),\n\t\tgrpc.ChainStreamInterceptor(\n\t\t\tlogging.StreamServerInterceptor(InterceptorLogger(logger), opts...),\n\t\t\t// Add any other interceptor you want.\n\t\t),\n\t)\n\t// ...user server.\n\n\t// Similarly you can create client that will log for the unary and stream client started or finished calls.\n\t_, _ = grpc.Dial(\n\t\t\"some-target\",\n\t\tgrpc.WithChainUnaryInterceptor(\n\t\t\tlogging.UnaryClientInterceptor(InterceptorLogger(logger), opts...),\n\t\t\t// Add any other interceptor you want.\n\t\t),\n\t\tgrpc.WithChainStreamInterceptor(\n\t\t\tlogging.StreamClientInterceptor(InterceptorLogger(logger), opts...),\n\t\t\t// Add any other interceptor you want.\n\t\t),\n\t)\n\t// Output:\n}\n"
  },
  {
    "path": "interceptors/logging/examples/logr/example_test.go",
    "content": "// Copyright (c) The go-grpc-middleware Authors.\n// Licensed under the Apache License 2.0.\n\npackage logr_test\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\n\t\"github.com/go-logr/logr\"\n\t\"github.com/grpc-ecosystem/go-grpc-middleware/v2/interceptors/logging\"\n\t\"google.golang.org/grpc\"\n\t\"k8s.io/klog/v2\"\n)\n\n// verbosity https://github.com/kubernetes/community/blob/master/contributors/devel/sig-instrumentation/logging.md#what-method-to-use\nconst (\n\tdebugVerbosity = 4\n\tinfoVerbosity  = 2\n\twarnVerbosity  = 1\n\terrorVerbosity = 0\n)\n\n// InterceptorLogger adapts logr logger to interceptor logger.\n// This code is simple enough to be copied and not imported.\nfunc InterceptorLogger(l logr.Logger) logging.Logger {\n\treturn logging.LoggerFunc(func(_ context.Context, lvl logging.Level, msg string, fields ...any) {\n\t\tl := l.WithValues(fields...)\n\t\tswitch lvl {\n\t\tcase logging.LevelDebug:\n\t\t\tl.V(debugVerbosity).Info(msg)\n\t\tcase logging.LevelInfo:\n\t\t\tl.V(infoVerbosity).Info(msg)\n\t\tcase logging.LevelWarn:\n\t\t\tl.V(warnVerbosity).Info(msg)\n\t\tcase logging.LevelError:\n\t\t\tl.V(errorVerbosity).Info(msg)\n\t\tdefault:\n\t\t\tpanic(fmt.Sprintf(\"unknown level %v\", lvl))\n\t\t}\n\t})\n}\n\nfunc ExampleInterceptorLogger() {\n\tlogger := klog.NewKlogr()\n\n\topts := []logging.Option{\n\t\tlogging.WithLogOnEvents(logging.StartCall, logging.FinishCall),\n\t\t// Add any other option (check functions starting with logging.With).\n\t}\n\n\t// You can now create a server with logging instrumentation that e.g. logs when the unary or stream call is started or finished.\n\t_ = grpc.NewServer(\n\t\tgrpc.ChainUnaryInterceptor(\n\t\t\tlogging.UnaryServerInterceptor(InterceptorLogger(logger), opts...),\n\t\t\t// Add any other interceptor you want.\n\t\t),\n\t\tgrpc.ChainStreamInterceptor(\n\t\t\tlogging.StreamServerInterceptor(InterceptorLogger(logger), opts...),\n\t\t\t// Add any other interceptor you want.\n\t\t),\n\t)\n\t// ...user server.\n\n\t// Similarly you can create client that will log for the unary and stream client started or finished calls.\n\t_, _ = grpc.Dial(\n\t\t\"some-target\",\n\t\tgrpc.WithChainUnaryInterceptor(\n\t\t\tlogging.UnaryClientInterceptor(InterceptorLogger(logger), opts...),\n\t\t\t// Add any other interceptor you want.\n\t\t),\n\t\tgrpc.WithChainStreamInterceptor(\n\t\t\tlogging.StreamClientInterceptor(InterceptorLogger(logger), opts...),\n\t\t\t// Add any other interceptor you want.\n\t\t),\n\t)\n\t// Output:\n}\n"
  },
  {
    "path": "interceptors/logging/examples/logrus/example_test.go",
    "content": "// Copyright (c) The go-grpc-middleware Authors.\n// Licensed under the Apache License 2.0.\n\npackage logrus_test\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\n\t\"github.com/grpc-ecosystem/go-grpc-middleware/v2/interceptors/logging\"\n\t\"github.com/sirupsen/logrus\"\n\t\"google.golang.org/grpc\"\n)\n\n// InterceptorLogger adapts logrus logger to interceptor logger.\n// This code is simple enough to be copied and not imported.\nfunc InterceptorLogger(l logrus.FieldLogger) logging.Logger {\n\treturn logging.LoggerFunc(func(_ context.Context, lvl logging.Level, msg string, fields ...any) {\n\t\tf := make(map[string]any, len(fields)/2)\n\t\ti := logging.Fields(fields).Iterator()\n\t\tfor i.Next() {\n\t\t\tk, v := i.At()\n\t\t\tf[k] = v\n\t\t}\n\t\tl := l.WithFields(f)\n\n\t\tswitch lvl {\n\t\tcase logging.LevelDebug:\n\t\t\tl.Debug(msg)\n\t\tcase logging.LevelInfo:\n\t\t\tl.Info(msg)\n\t\tcase logging.LevelWarn:\n\t\t\tl.Warn(msg)\n\t\tcase logging.LevelError:\n\t\t\tl.Error(msg)\n\t\tdefault:\n\t\t\tpanic(fmt.Sprintf(\"unknown level %v\", lvl))\n\t\t}\n\t})\n}\n\nfunc ExampleInterceptorLogger() {\n\tlogger := logrus.New()\n\n\topts := []logging.Option{\n\t\tlogging.WithLogOnEvents(logging.StartCall, logging.FinishCall),\n\t\t// Add any other option (check functions starting with logging.With).\n\t}\n\n\t// You can now create a server with logging instrumentation that e.g. logs when the unary or stream call is started or finished.\n\t_ = grpc.NewServer(\n\t\tgrpc.ChainUnaryInterceptor(\n\t\t\tlogging.UnaryServerInterceptor(InterceptorLogger(logger), opts...),\n\t\t\t// Add any other interceptor you want.\n\t\t),\n\t\tgrpc.ChainStreamInterceptor(\n\t\t\tlogging.StreamServerInterceptor(InterceptorLogger(logger), opts...),\n\t\t\t// Add any other interceptor you want.\n\t\t),\n\t)\n\t// ...user server.\n\n\t// Similarly you can create client that will log for the unary and stream client started or finished calls.\n\t_, _ = grpc.Dial(\n\t\t\"some-target\",\n\t\tgrpc.WithChainUnaryInterceptor(\n\t\t\tlogging.UnaryClientInterceptor(InterceptorLogger(logger), opts...),\n\t\t\t// Add any other interceptor you want.\n\t\t),\n\t\tgrpc.WithChainStreamInterceptor(\n\t\t\tlogging.StreamClientInterceptor(InterceptorLogger(logger), opts...),\n\t\t\t// Add any other interceptor you want.\n\t\t),\n\t)\n\t// Output:\n}\n"
  },
  {
    "path": "interceptors/logging/examples/skip_healthchecks/example_test.go",
    "content": "// Copyright (c) The go-grpc-middleware Authors.\n// Licensed under the Apache License 2.0.\n\npackage slog_test\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\n\t\"github.com/grpc-ecosystem/go-grpc-middleware/v2/interceptors\"\n\t\"github.com/grpc-ecosystem/go-grpc-middleware/v2/interceptors/logging\"\n\t\"github.com/grpc-ecosystem/go-grpc-middleware/v2/interceptors/selector\"\n\t\"google.golang.org/grpc\"\n)\n\nfunc InterceptorLogger() logging.Logger {\n\treturn logging.LoggerFunc(func(ctx context.Context, lvl logging.Level, msg string, fields ...any) {\n\t\tfmt.Printf(\"This will not print anything for health checks or reflection, but will print this message for other requests\")\n\t})\n}\n\nfunc SkipHealthAndReflectionRequests(_ context.Context, c interceptors.CallMeta) bool {\n\treturn c.FullMethod() != \"/grpc.health.v1.Health/Check\" &&\n\t\tc.FullMethod() != \"/grpc.reflection.v1alpha.ServerReflection/ServerReflectionInfo\"\n}\n\nfunc ExampleInterceptorLogger() {\n\n\topts := []logging.Option{\n\t\tlogging.WithLogOnEvents(logging.StartCall, logging.FinishCall),\n\t}\n\n\t// Create a server and wrap the logging interceptor with the selector interceptor to skip health checks and reflection requests.\n\t_ = grpc.NewServer(\n\t\tgrpc.ChainUnaryInterceptor(\n\t\t\t// Wrap the logging interceptor with the selector interceptor to skip health checks and reflection requests.\n\t\t\tselector.UnaryServerInterceptor(\n\t\t\t\tlogging.UnaryServerInterceptor(InterceptorLogger(), opts...),\n\t\t\t\tselector.MatchFunc(SkipHealthAndReflectionRequests),\n\t\t\t),\n\t\t),\n\t\tgrpc.ChainStreamInterceptor(\n\t\t\tselector.StreamServerInterceptor(\n\t\t\t\tlogging.StreamServerInterceptor(InterceptorLogger(), opts...),\n\t\t\t\tselector.MatchFunc(SkipHealthAndReflectionRequests),\n\t\t\t),\n\t\t),\n\t)\n\n\t// Similarly you can create client and wrap the logging interceptor with the selector interceptor to skip health checks and reflection requests.\n\t_, _ = grpc.Dial(\n\t\t\"some-target\",\n\t\tgrpc.WithChainUnaryInterceptor(\n\t\t\tselector.UnaryClientInterceptor(\n\t\t\t\tlogging.UnaryClientInterceptor(InterceptorLogger(), opts...),\n\t\t\t\tselector.MatchFunc(SkipHealthAndReflectionRequests),\n\t\t\t),\n\t\t),\n\t\tgrpc.WithChainStreamInterceptor(\n\t\t\tselector.StreamClientInterceptor(\n\t\t\t\tlogging.StreamClientInterceptor(InterceptorLogger(), opts...),\n\t\t\t\tselector.MatchFunc(SkipHealthAndReflectionRequests),\n\t\t\t),\n\t\t),\n\t)\n\t// Output:\n}\n"
  },
  {
    "path": "interceptors/logging/examples/slog/example_test.go",
    "content": "// Copyright (c) The go-grpc-middleware Authors.\n// Licensed under the Apache License 2.0.\n\npackage slog_test\n\nimport (\n\t\"context\"\n\t\"log/slog\"\n\t\"os\"\n\n\t\"github.com/grpc-ecosystem/go-grpc-middleware/v2/interceptors/logging\"\n\t\"google.golang.org/grpc\"\n)\n\n// InterceptorLogger adapts slog logger to interceptor logger.\n// This code is simple enough to be copied and not imported.\nfunc InterceptorLogger(l *slog.Logger) logging.Logger {\n\treturn logging.LoggerFunc(func(ctx context.Context, lvl logging.Level, msg string, fields ...any) {\n\t\tl.Log(ctx, slog.Level(lvl), msg, fields...)\n\t})\n}\n\nfunc ExampleInterceptorLogger() {\n\tlogger := slog.New(slog.NewTextHandler(os.Stderr, nil))\n\n\topts := []logging.Option{\n\t\tlogging.WithLogOnEvents(logging.StartCall, logging.FinishCall),\n\t\t// Add any other option (check functions starting with logging.With).\n\t}\n\n\t// You can now create a server with logging instrumentation that e.g. logs when the unary or stream call is started or finished.\n\t_ = grpc.NewServer(\n\t\tgrpc.ChainUnaryInterceptor(\n\t\t\tlogging.UnaryServerInterceptor(InterceptorLogger(logger), opts...),\n\t\t\t// Add any other interceptor you want.\n\t\t),\n\t\tgrpc.ChainStreamInterceptor(\n\t\t\tlogging.StreamServerInterceptor(InterceptorLogger(logger), opts...),\n\t\t\t// Add any other interceptor you want.\n\t\t),\n\t)\n\t// ...user server.\n\n\t// Similarly you can create client that will log for the unary and stream client started or finished calls.\n\t_, _ = grpc.Dial(\n\t\t\"some-target\",\n\t\tgrpc.WithChainUnaryInterceptor(\n\t\t\tlogging.UnaryClientInterceptor(InterceptorLogger(logger), opts...),\n\t\t\t// Add any other interceptor you want.\n\t\t),\n\t\tgrpc.WithChainStreamInterceptor(\n\t\t\tlogging.StreamClientInterceptor(InterceptorLogger(logger), opts...),\n\t\t\t// Add any other interceptor you want.\n\t\t),\n\t)\n\t// Output:\n}\n"
  },
  {
    "path": "interceptors/logging/examples/zap/example_test.go",
    "content": "// Copyright (c) The go-grpc-middleware Authors.\n// Licensed under the Apache License 2.0.\n\npackage zap_test\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\n\t\"github.com/grpc-ecosystem/go-grpc-middleware/v2/interceptors/logging\"\n\t\"go.uber.org/zap\"\n\t\"google.golang.org/grpc\"\n)\n\n// InterceptorLogger adapts zap logger to interceptor logger.\n// This code is simple enough to be copied and not imported.\nfunc InterceptorLogger(l *zap.Logger) logging.Logger {\n\treturn logging.LoggerFunc(func(ctx context.Context, lvl logging.Level, msg string, fields ...any) {\n\t\tf := make([]zap.Field, 0, len(fields)/2)\n\n\t\tfor i := 0; i < len(fields); i += 2 {\n\t\t\tkey := fields[i]\n\t\t\tvalue := fields[i+1]\n\n\t\t\tswitch v := value.(type) {\n\t\t\tcase string:\n\t\t\t\tf = append(f, zap.String(key.(string), v))\n\t\t\tcase int:\n\t\t\t\tf = append(f, zap.Int(key.(string), v))\n\t\t\tcase bool:\n\t\t\t\tf = append(f, zap.Bool(key.(string), v))\n\t\t\tdefault:\n\t\t\t\tf = append(f, zap.Any(key.(string), v))\n\t\t\t}\n\t\t}\n\n\t\tlogger := l.WithOptions(zap.AddCallerSkip(1)).With(f...)\n\n\t\tswitch lvl {\n\t\tcase logging.LevelDebug:\n\t\t\tlogger.Debug(msg)\n\t\tcase logging.LevelInfo:\n\t\t\tlogger.Info(msg)\n\t\tcase logging.LevelWarn:\n\t\t\tlogger.Warn(msg)\n\t\tcase logging.LevelError:\n\t\t\tlogger.Error(msg)\n\t\tdefault:\n\t\t\tpanic(fmt.Sprintf(\"unknown level %v\", lvl))\n\t\t}\n\t})\n}\n\nfunc ExampleInterceptorLogger() {\n\tlogger := zap.NewExample()\n\n\topts := []logging.Option{\n\t\tlogging.WithLogOnEvents(logging.StartCall, logging.FinishCall),\n\t\t// Add any other option (check functions starting with logging.With).\n\t}\n\n\t// You can now create a server with logging instrumentation that e.g. logs when the unary or stream call is started or finished.\n\t_ = grpc.NewServer(\n\t\tgrpc.ChainUnaryInterceptor(\n\t\t\tlogging.UnaryServerInterceptor(InterceptorLogger(logger), opts...),\n\t\t\t// Add any other interceptor you want.\n\t\t),\n\t\tgrpc.ChainStreamInterceptor(\n\t\t\tlogging.StreamServerInterceptor(InterceptorLogger(logger), opts...),\n\t\t\t// Add any other interceptor you want.\n\t\t),\n\t)\n\t// ...user server.\n\n\t// Similarly you can create client that will log for the unary and stream client started or finished calls.\n\t_, _ = grpc.Dial(\n\t\t\"some-target\",\n\t\tgrpc.WithChainUnaryInterceptor(\n\t\t\tlogging.UnaryClientInterceptor(InterceptorLogger(logger), opts...),\n\t\t\t// Add any other interceptor you want.\n\t\t),\n\t\tgrpc.WithChainStreamInterceptor(\n\t\t\tlogging.StreamClientInterceptor(InterceptorLogger(logger), opts...),\n\t\t\t// Add any other interceptor you want.\n\t\t),\n\t)\n\t// Output:\n}\n"
  },
  {
    "path": "interceptors/logging/examples/zerolog/example_test.go",
    "content": "// Copyright (c) The go-grpc-middleware Authors.\n// Licensed under the Apache License 2.0.\n\npackage zerolog_test\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"os\"\n\n\t\"github.com/grpc-ecosystem/go-grpc-middleware/v2/interceptors/logging\"\n\t\"github.com/rs/zerolog\"\n\t\"google.golang.org/grpc\"\n)\n\n// InterceptorLogger adapts zerolog logger to interceptor logger.\n// This code is simple enough to be copied and not imported.\nfunc InterceptorLogger(l zerolog.Logger) logging.Logger {\n\treturn logging.LoggerFunc(func(ctx context.Context, lvl logging.Level, msg string, fields ...any) {\n\t\tl := l.With().Fields(fields).Logger()\n\n\t\tswitch lvl {\n\t\tcase logging.LevelDebug:\n\t\t\tl.Debug().Msg(msg)\n\t\tcase logging.LevelInfo:\n\t\t\tl.Info().Msg(msg)\n\t\tcase logging.LevelWarn:\n\t\t\tl.Warn().Msg(msg)\n\t\tcase logging.LevelError:\n\t\t\tl.Error().Msg(msg)\n\t\tdefault:\n\t\t\tpanic(fmt.Sprintf(\"unknown level %v\", lvl))\n\t\t}\n\t})\n}\n\nfunc ExampleInterceptorLogger() {\n\tlogger := zerolog.New(os.Stderr)\n\n\topts := []logging.Option{\n\t\tlogging.WithLogOnEvents(logging.StartCall, logging.FinishCall),\n\t\t// Add any other option (check functions starting with logging.With).\n\t}\n\n\t// You can now create a server with logging instrumentation that e.g. logs when the unary or stream call is started or finished.\n\t_ = grpc.NewServer(\n\t\tgrpc.ChainUnaryInterceptor(\n\t\t\tlogging.UnaryServerInterceptor(InterceptorLogger(logger), opts...),\n\t\t\t// Add any other interceptor you want.\n\t\t),\n\t\tgrpc.ChainStreamInterceptor(\n\t\t\tlogging.StreamServerInterceptor(InterceptorLogger(logger), opts...),\n\t\t\t// Add any other interceptor you want.\n\t\t),\n\t)\n\t// ...user server.\n\n\t// Similarly you can create client that will log for the unary and stream client started or finished calls.\n\t_, _ = grpc.Dial(\n\t\t\"some-target\",\n\t\tgrpc.WithChainUnaryInterceptor(\n\t\t\tlogging.UnaryClientInterceptor(InterceptorLogger(logger), opts...),\n\t\t\t// Add any other interceptor you want.\n\t\t),\n\t\tgrpc.WithChainStreamInterceptor(\n\t\t\tlogging.StreamClientInterceptor(InterceptorLogger(logger), opts...),\n\t\t\t// Add any other interceptor you want.\n\t\t),\n\t)\n\t// Output:\n}\n"
  },
  {
    "path": "interceptors/logging/interceptors.go",
    "content": "// Copyright (c) The go-grpc-middleware Authors.\n// Licensed under the Apache License 2.0.\n\npackage logging\n\nimport (\n\t\"context\"\n\t\"errors\"\n\t\"fmt\"\n\t\"io\"\n\t\"time\"\n\n\t\"github.com/grpc-ecosystem/go-grpc-middleware/v2/interceptors\"\n\t\"google.golang.org/grpc\"\n\t\"google.golang.org/grpc/peer\"\n\t\"google.golang.org/protobuf/proto\"\n)\n\ntype reporter struct {\n\tinterceptors.CallMeta\n\n\tctx             context.Context\n\tkind            string\n\tstartCallLogged bool\n\n\topts   *options\n\tfields Fields\n\tlogger Logger\n}\n\nfunc (c *reporter) PostCall(err error, duration time.Duration) {\n\tif !has(c.opts.loggableEvents, FinishCall) {\n\t\treturn\n\t}\n\tif errors.Is(err, io.EOF) {\n\t\terr = nil\n\t}\n\n\tcode := c.opts.codeFunc(err)\n\tfields := c.fields.WithUnique(ExtractFields(c.ctx))\n\tfields = fields.AppendUnique(Fields{\"grpc.code\", code.String()})\n\tif err != nil {\n\t\tfields = fields.AppendUnique(Fields{\"grpc.error\", fmt.Sprintf(\"%v\", err)})\n\t\tif c.opts.errorToFieldsFunc != nil {\n\t\t\tfields = fields.AppendUnique(c.opts.errorToFieldsFunc(err))\n\t\t}\n\t}\n\tif c.opts.fieldsFromCtxCallMetaFn != nil {\n\t\t// fieldsFromCtxFn dups override the existing fields.\n\t\tfields = c.opts.fieldsFromCtxCallMetaFn(c.ctx, c.CallMeta).AppendUnique(fields)\n\t}\n\tc.logger.Log(c.ctx, c.opts.levelFunc(code), \"finished call\", fields.AppendUnique(c.opts.durationFieldFunc(duration))...)\n}\n\nfunc (c *reporter) PostMsgSend(payload any, err error, duration time.Duration) {\n\tlogStartCall := !c.startCallLogged && has(c.opts.loggableEvents, StartCall)\n\tlogPayloadSend := err == nil && has(c.opts.loggableEvents, PayloadSent)\n\tif !logStartCall && !logPayloadSend {\n\t\treturn\n\t}\n\n\tlogLvl := c.opts.levelFunc(c.opts.codeFunc(err))\n\tfields := c.fields.WithUnique(ExtractFields(c.ctx))\n\tif err != nil {\n\t\tfields = fields.AppendUnique(Fields{\"grpc.error\", fmt.Sprintf(\"%v\", err)})\n\t\tif c.opts.errorToFieldsFunc != nil {\n\t\t\tfields = fields.AppendUnique(c.opts.errorToFieldsFunc(err))\n\t\t}\n\t}\n\tif c.opts.fieldsFromCtxCallMetaFn != nil {\n\t\t// fieldsFromCtxFn dups override the existing fields.\n\t\tfields = c.opts.fieldsFromCtxCallMetaFn(c.ctx, c.CallMeta).AppendUnique(fields)\n\t}\n\tif logStartCall {\n\t\tc.startCallLogged = true\n\t\tc.logger.Log(c.ctx, logLvl, \"started call\", fields.AppendUnique(c.opts.durationFieldFunc(duration))...)\n\t}\n\n\tif !logPayloadSend {\n\t\treturn\n\t}\n\tcallType := \"response\"\n\tif c.IsClient {\n\t\tcallType = \"request\"\n\t}\n\tp, ok := payload.(proto.Message)\n\tif !ok {\n\t\tc.logger.Log(\n\t\t\tc.ctx,\n\t\t\tLevelError,\n\t\t\t\"payload is not a google.golang.org/protobuf/proto.Message; programmatic error?\",\n\t\t\tfields.AppendUnique(Fields{fmt.Sprintf(\"grpc.%s.type\", callType), fmt.Sprintf(\"%T\", payload)})...,\n\t\t)\n\t\treturn\n\t}\n\n\tfields = fields.AppendUnique(Fields{\"grpc.send.duration\", duration.String(), fmt.Sprintf(\"grpc.%s.content\", callType), p})\n\tfields = fields.AppendUnique(c.opts.durationFieldFunc(duration))\n\tc.logger.Log(c.ctx, logLvl, fmt.Sprintf(\"%s sent\", callType), fields...)\n}\n\nfunc (c *reporter) PostMsgReceive(payload any, err error, duration time.Duration) {\n\tlogStartCall := !c.startCallLogged && has(c.opts.loggableEvents, StartCall)\n\tlogPayloadReceived := err == nil && has(c.opts.loggableEvents, PayloadReceived)\n\tif !logStartCall && !logPayloadReceived {\n\t\treturn\n\t}\n\n\tlogLvl := c.opts.levelFunc(c.opts.codeFunc(err))\n\tfields := c.fields.WithUnique(ExtractFields(c.ctx))\n\tif err != nil {\n\t\tfields = fields.AppendUnique(Fields{\"grpc.error\", fmt.Sprintf(\"%v\", err)})\n\t\tif c.opts.errorToFieldsFunc != nil {\n\t\t\tfields = fields.AppendUnique(c.opts.errorToFieldsFunc(err))\n\t\t}\n\t}\n\tif c.opts.fieldsFromCtxCallMetaFn != nil {\n\t\t// fieldsFromCtxFn dups override the existing fields.\n\t\tfields = c.opts.fieldsFromCtxCallMetaFn(c.ctx, c.CallMeta).AppendUnique(fields)\n\t}\n\tif logStartCall {\n\t\tc.startCallLogged = true\n\t\tc.logger.Log(c.ctx, logLvl, \"started call\", fields.AppendUnique(c.opts.durationFieldFunc(duration))...)\n\t}\n\n\tif !logPayloadReceived {\n\t\treturn\n\t}\n\tcallType := \"request\"\n\tif c.IsClient {\n\t\tcallType = \"response\"\n\t}\n\tp, ok := payload.(proto.Message)\n\tif !ok {\n\t\tc.logger.Log(\n\t\t\tc.ctx,\n\t\t\tLevelError,\n\t\t\t\"payload is not a google.golang.org/protouf/proto.Message; programmatic error?\",\n\t\t\tfields.AppendUnique(Fields{fmt.Sprintf(\"grpc.%s.type\", callType), fmt.Sprintf(\"%T\", payload)})...,\n\t\t)\n\t\treturn\n\t}\n\n\tfields = fields.AppendUnique(Fields{\"grpc.recv.duration\", duration.String(), fmt.Sprintf(\"grpc.%s.content\", callType), p})\n\tfields = fields.AppendUnique(c.opts.durationFieldFunc(duration))\n\tc.logger.Log(c.ctx, logLvl, fmt.Sprintf(\"%s received\", callType), fields...)\n}\n\nfunc reportable(logger Logger, opts *options) interceptors.CommonReportableFunc {\n\treturn func(ctx context.Context, c interceptors.CallMeta) (interceptors.Reporter, context.Context) {\n\t\tkind := KindServerFieldValue\n\t\tif c.IsClient {\n\t\t\tkind = KindClientFieldValue\n\t\t}\n\n\t\t// Field dups from context override the common fields.\n\t\tfields := newCommonFields(kind, c)\n\t\tif opts.disableGrpcLogFields != nil {\n\t\t\tfields = disableCommonLoggingFields(kind, c, opts.disableGrpcLogFields)\n\t\t}\n\t\tfields = fields.WithUnique(ExtractFields(ctx))\n\n\t\tif !c.IsClient {\n\t\t\tif peer, ok := peer.FromContext(ctx); ok {\n\t\t\t\tfields = append(fields, \"peer.address\", peer.Addr.String())\n\t\t\t}\n\t\t}\n\t\tif opts.fieldsFromCtxCallMetaFn != nil {\n\t\t\t// fieldsFromCtxFn dups override the existing fields.\n\t\t\tfields = opts.fieldsFromCtxCallMetaFn(ctx, c).AppendUnique(fields)\n\t\t}\n\n\t\tsingleUseFields := Fields{\"grpc.start_time\", time.Now().Format(opts.timestampFormat)}\n\t\tif d, ok := ctx.Deadline(); ok {\n\t\t\tsingleUseFields = singleUseFields.AppendUnique(Fields{\"grpc.request.deadline\", d.Format(opts.timestampFormat)})\n\t\t}\n\t\tctx = InjectFields(ctx, fields)\n\t\treturn &reporter{\n\t\t\tCallMeta:        c,\n\t\t\tctx:             ctx,\n\t\t\tstartCallLogged: false,\n\t\t\topts:            opts,\n\t\t\tfields:          fields.WithUnique(singleUseFields),\n\t\t\tlogger:          logger,\n\t\t\tkind:            kind,\n\t\t}, ctx\n\t}\n}\n\n// UnaryClientInterceptor returns a new unary client interceptor that optionally logs the execution of external gRPC calls.\n// Logger will read existing and write new logging.Fields available in current context.\n// See `ExtractFields` and `InjectFields` for details.\nfunc UnaryClientInterceptor(logger Logger, opts ...Option) grpc.UnaryClientInterceptor {\n\to := evaluateClientOpt(opts)\n\treturn interceptors.UnaryClientInterceptor(reportable(logger, o))\n}\n\n// StreamClientInterceptor returns a new streaming client interceptor that optionally logs the execution of external gRPC calls.\n// Logger will read existing and write new logging.Fields available in current context.\n// See `ExtractFields` and `InjectFields` for details.\nfunc StreamClientInterceptor(logger Logger, opts ...Option) grpc.StreamClientInterceptor {\n\to := evaluateClientOpt(opts)\n\treturn interceptors.StreamClientInterceptor(reportable(logger, o))\n}\n\n// UnaryServerInterceptor returns a new unary server interceptors that optionally logs endpoint handling.\n// Logger will read existing and write new logging.Fields available in current context.\n// See `ExtractFields` and `InjectFields` for details.\nfunc UnaryServerInterceptor(logger Logger, opts ...Option) grpc.UnaryServerInterceptor {\n\to := evaluateServerOpt(opts)\n\treturn interceptors.UnaryServerInterceptor(reportable(logger, o))\n}\n\n// StreamServerInterceptor returns a new stream server interceptors that optionally logs endpoint handling.\n// Logger will read existing and write new logging.Fields available in current context.\n// See `ExtractFields` and `InjectFields` for details..\nfunc StreamServerInterceptor(logger Logger, opts ...Option) grpc.StreamServerInterceptor {\n\to := evaluateServerOpt(opts)\n\treturn interceptors.StreamServerInterceptor(reportable(logger, o))\n}\n"
  },
  {
    "path": "interceptors/logging/interceptors_test.go",
    "content": "// Copyright (c) The go-grpc-middleware Authors.\n// Licensed under the Apache License 2.0.\n\npackage logging_test\n\nimport (\n\t\"bytes\"\n\t\"context\"\n\t\"encoding/json\"\n\t\"errors\"\n\t\"fmt\"\n\t\"io\"\n\t\"runtime\"\n\t\"sort\"\n\t\"strconv\"\n\t\"strings\"\n\t\"sync\"\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/grpc-ecosystem/go-grpc-middleware/v2/interceptors\"\n\t\"github.com/grpc-ecosystem/go-grpc-middleware/v2/interceptors/logging\"\n\t\"github.com/grpc-ecosystem/go-grpc-middleware/v2/testing/testpb\"\n\t\"github.com/stretchr/testify/assert\"\n\t\"github.com/stretchr/testify/require\"\n\t\"github.com/stretchr/testify/suite\"\n\t\"google.golang.org/grpc\"\n\t\"google.golang.org/grpc/codes\"\n\t\"google.golang.org/protobuf/encoding/protojson\"\n\t\"google.golang.org/protobuf/proto\"\n)\n\ntype testDisposableFields map[string]string\n\nfunc (f testDisposableFields) AssertField(t *testing.T, key, value string) testDisposableFields {\n\tt.Helper()\n\n\trequire.NotEmptyf(t, f, \"expected field %s = %v, but fields ended\", key, value)\n\tassert.Equalf(t, value, f[key], \"expected %s for %s\", value, key)\n\tdelete(f, key)\n\treturn f\n}\n\nfunc (f testDisposableFields) AssertFieldNotEmpty(t *testing.T, key string) testDisposableFields {\n\tt.Helper()\n\n\trequire.NotEmptyf(t, f, \"expected field %s and some non-empty value, but fields ended\", key)\n\tassert.NotEmptyf(t, f[key], \"%s is empty\", key)\n\tdelete(f, key)\n\treturn f\n}\n\nfunc (f testDisposableFields) AssertNoMoreTags(t *testing.T) {\n\tt.Helper()\n\n\tassert.Emptyf(t, f, \"expected no more fields in testDisposableFields but still got %v\", f)\n}\n\ntype LogLine struct {\n\tmsg    string\n\tfields testDisposableFields\n\tlvl    logging.Level\n}\n\ntype LogLines []LogLine\n\nfunc (l LogLines) Len() int {\n\treturn len(l)\n}\n\nfunc (l LogLines) Less(i, j int) bool {\n\tif l[i].fields[logging.ComponentFieldKey] != l[j].fields[logging.ComponentFieldKey] {\n\t\treturn l[i].fields[logging.ComponentFieldKey] < l[j].fields[logging.ComponentFieldKey]\n\t}\n\tif l[i].msg != l[j].msg {\n\t\treturn l[i].msg < l[j].msg\n\t}\n\n\t// We want to sort by counter which in string, so we need to parse it.\n\ta := testpb.PingResponse{}\n\tb := testpb.PingResponse{}\n\t_ = json.Unmarshal([]byte(l[i].fields[\"grpc.response.content\"]), &a)\n\t_ = json.Unmarshal([]byte(l[j].fields[\"grpc.response.content\"]), &b)\n\tif a.Counter != b.Counter {\n\t\treturn a.Counter < b.Counter\n\t}\n\n\t_ = json.Unmarshal([]byte(l[i].fields[\"grpc.request.content\"]), &a)\n\t_ = json.Unmarshal([]byte(l[j].fields[\"grpc.request.content\"]), &b)\n\treturn a.Counter < b.Counter\n}\n\nfunc (l LogLines) Swap(i, j int) {\n\tl[i], l[j] = l[j], l[i]\n}\n\ntype output struct {\n\tm     sync.Mutex\n\tlines LogLines\n}\n\nfunc (o *output) Lines() LogLines {\n\to.m.Lock()\n\tdefer o.m.Unlock()\n\n\tretLines := make(LogLines, len(o.lines))\n\tcopy(retLines, o.lines)\n\n\treturn retLines\n}\n\nfunc (o *output) Append(lines ...LogLine) {\n\to.m.Lock()\n\tdefer o.m.Unlock()\n\n\to.lines = append(o.lines, lines...)\n}\n\nfunc (o *output) Reset() {\n\to.m.Lock()\n\tdefer o.m.Unlock()\n\n\to.lines = o.lines[:0]\n}\n\ntype mockLogger struct {\n\to *output\n}\n\nfunc newMockLogger() *mockLogger {\n\treturn &mockLogger{o: &output{}}\n}\n\nfunc (l *mockLogger) Log(_ context.Context, lvl logging.Level, msg string, args ...any) {\n\tline := LogLine{\n\t\tlvl:    lvl,\n\t\tmsg:    msg,\n\t\tfields: map[string]string{},\n\t}\n\n\t// For test purposes we assume all args are string (or proto messages) and there is always pair.\n\tfor i := 0; i < len(args); i += 2 {\n\t\tif v, ok := args[i+1].(string); ok {\n\t\t\tline.fields[args[i].(string)] = v\n\t\t\tcontinue\n\t\t}\n\t\tpayload, err := protojson.Marshal(args[i+1].(proto.Message))\n\t\tif err != nil {\n\t\t\tpanic(err)\n\t\t}\n\t\t// Trim spaces for deterministic output (https://github.com/goolang/protobuf/issues/1269).\n\t\tline.fields[args[i].(string)] = string(bytes.ReplaceAll(payload, []byte{' '}, []byte{}))\n\t}\n\tl.o.Append(line)\n}\n\ntype baseLoggingSuite struct {\n\t*testpb.InterceptorTestSuite\n\tlogger *mockLogger\n}\n\nfunc (s *baseLoggingSuite) SetupTest() {\n\ts.logger.o.Reset()\n}\n\nfunc customClientCodeToLevel(c codes.Code) logging.Level {\n\tif c == codes.Unauthenticated {\n\t\t// Make this a special case for tests, and an error.\n\t\treturn logging.LevelError\n\t}\n\treturn logging.DefaultClientCodeToLevel(c)\n}\n\ntype loggingClientServerSuite struct {\n\t*baseLoggingSuite\n}\n\nfunc customFields(ctx context.Context) logging.Fields {\n\tvar val string\n\tn := testpb.ExtractCtxTestNumber(ctx)\n\tif n != nil {\n\t\tval = strconv.Itoa(*n)\n\t}\n\t// Add custom fields. The second one overrides the first one.\n\treturn logging.Fields{\"custom-field\", \"foo\", \"custom-field\", \"yolo\", \"custom-ctx-field\", val}\n}\n\nfunc TestSuite(t *testing.T) {\n\tif strings.HasPrefix(runtime.Version(), \"go1.7\") {\n\t\tt.Skipf(\"Skipping due to json.RawMessage incompatibility with go1.7\")\n\t\treturn\n\t}\n\n\ts := &loggingClientServerSuite{\n\t\t&baseLoggingSuite{\n\t\t\tlogger: newMockLogger(),\n\t\t\tInterceptorTestSuite: &testpb.InterceptorTestSuite{\n\t\t\t\tTestService: &testpb.TestPingService{\n\t\t\t\t\tPingFunc: func(ctx context.Context) {\n\t\t\t\t\t\t// Modify the fields already in the context.\n\t\t\t\t\t\tlogging.AddFields(ctx, logging.Fields{\"business-field\", \"baguette\"})\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t}\n\ts.ClientOpts = []grpc.DialOption{\n\t\tgrpc.WithChainUnaryInterceptor(\n\t\t\tlogging.UnaryClientInterceptor(s.logger, logging.WithLevels(customClientCodeToLevel), logging.WithFieldsFromContext(customFields)),\n\t\t),\n\t\tgrpc.WithChainStreamInterceptor(\n\t\t\tlogging.StreamClientInterceptor(s.logger, logging.WithLevels(customClientCodeToLevel), logging.WithFieldsFromContext(customFields)),\n\t\t),\n\t}\n\terrorFields := func(err error) logging.Fields {\n\t\treturn testpb.ExtractErrorFields(err)\n\t}\n\ts.ServerOpts = []grpc.ServerOption{\n\t\tgrpc.StreamInterceptor(logging.StreamServerInterceptor(s.logger, logging.WithLevels(customClientCodeToLevel), logging.WithFieldsFromContext(customFields), logging.WithErrorFields(errorFields))),\n\t\tgrpc.UnaryInterceptor(logging.UnaryServerInterceptor(s.logger, logging.WithLevels(customClientCodeToLevel), logging.WithFieldsFromContext(customFields), logging.WithErrorFields(errorFields))),\n\t}\n\tsuite.Run(t, s)\n}\n\nfunc assertStandardFields(t *testing.T, kind string, f testDisposableFields, method string, typ interceptors.GRPCType) testDisposableFields {\n\treturn f.AssertField(t, logging.SystemTag[0], logging.SystemTag[1]).\n\t\tAssertField(t, logging.ComponentFieldKey, kind).\n\t\tAssertField(t, logging.ServiceFieldKey, testpb.TestServiceFullName).\n\t\tAssertField(t, logging.MethodFieldKey, method).\n\t\tAssertField(t, logging.MethodTypeFieldKey, string(typ))\n}\n\nfunc (s *loggingClientServerSuite) TestPing() {\n\tctx := logging.InjectFields(s.SimpleCtx(), logging.Fields{\"grpc.request.value\", testpb.GoodPing.Value})\n\t_, err := s.Client.Ping(ctx, testpb.GoodPing)\n\ts.Require().NoError(err, \"there must be not be an on a successful call\")\n\n\tlines := s.logger.o.Lines()\n\tsort.Sort(lines)\n\ts.Require().Len(lines, 4)\n\n\tclientStartCallLogLine := lines[1]\n\ts.Assert().Equal(logging.LevelDebug, clientStartCallLogLine.lvl)\n\ts.Assert().Equal(\"started call\", clientStartCallLogLine.msg)\n\t_ = assertStandardFields(s.T(), logging.KindClientFieldValue, clientStartCallLogLine.fields, \"Ping\", interceptors.Unary)\n\n\tserverStartCallLogLine := lines[3]\n\ts.Assert().Equal(logging.LevelDebug, serverStartCallLogLine.lvl)\n\ts.Assert().Equal(\"started call\", serverStartCallLogLine.msg)\n\t_ = assertStandardFields(s.T(), logging.KindServerFieldValue, serverStartCallLogLine.fields, \"Ping\", interceptors.Unary)\n\t// This field is zero initially, but will be updated by the service, which we should see after the call is finished\n\tserverStartCallLogLine.fields.AssertField(s.T(), \"custom-ctx-field\", \"0\")\n\n\tserverFinishCallLogLine := lines[2]\n\ts.Assert().Equal(logging.LevelDebug, serverFinishCallLogLine.lvl)\n\ts.Assert().Equal(\"finished call\", serverFinishCallLogLine.msg)\n\tserverFinishCallFields := assertStandardFields(s.T(), logging.KindServerFieldValue, serverFinishCallLogLine.fields, \"Ping\", interceptors.Unary)\n\tserverFinishCallFields.AssertFieldNotEmpty(s.T(), \"peer.address\").\n\t\tAssertField(s.T(), \"custom-field\", \"yolo\").\n\t\t// should be updated from 0 to 42\n\t\tAssertField(s.T(), \"custom-ctx-field\", \"42\").\n\t\tAssertFieldNotEmpty(s.T(), \"grpc.start_time\").\n\t\tAssertFieldNotEmpty(s.T(), \"grpc.request.deadline\").\n\t\tAssertField(s.T(), \"grpc.code\", \"OK\").\n\t\tAssertFieldNotEmpty(s.T(), \"grpc.time_ms\").\n\t\tAssertField(s.T(), \"business-field\", \"baguette\").AssertNoMoreTags(s.T())\n\n\tclientFinishCallLogLine := lines[0]\n\ts.Assert().Equal(logging.LevelDebug, clientFinishCallLogLine.lvl)\n\ts.Assert().Equal(\"finished call\", clientFinishCallLogLine.msg)\n\tclientFinishCallFields := assertStandardFields(s.T(), logging.KindClientFieldValue, clientFinishCallLogLine.fields, \"Ping\", interceptors.Unary)\n\tclientFinishCallFields.AssertField(s.T(), \"custom-field\", \"yolo\").\n\t\t// should be updated from 0 to 42\n\t\tAssertField(s.T(), \"custom-ctx-field\", \"42\").\n\t\tAssertField(s.T(), \"grpc.request.value\", \"something\").\n\t\tAssertFieldNotEmpty(s.T(), \"grpc.start_time\").\n\t\tAssertFieldNotEmpty(s.T(), \"grpc.request.deadline\").\n\t\tAssertField(s.T(), \"grpc.code\", \"OK\").\n\t\tAssertFieldNotEmpty(s.T(), \"grpc.time_ms\").AssertNoMoreTags(s.T())\n}\n\nfunc (s *loggingClientServerSuite) TestPingList() {\n\tstream, err := s.Client.PingList(s.SimpleCtx(), testpb.GoodPingList)\n\ts.Require().NoError(err, \"should not fail on establishing the stream\")\n\tfor {\n\t\t_, err := stream.Recv()\n\t\tif errors.Is(err, io.EOF) {\n\t\t\tbreak\n\t\t}\n\t\ts.Require().NoError(err, \"reading stream should not fail\")\n\t}\n\tlines := s.logger.o.Lines()\n\tsort.Sort(lines)\n\ts.Require().Len(lines, 4)\n\n\tserverStartCallLogLine := lines[3]\n\ts.Assert().Equal(logging.LevelDebug, serverStartCallLogLine.lvl)\n\ts.Assert().Equal(\"started call\", serverStartCallLogLine.msg)\n\t_ = assertStandardFields(s.T(), logging.KindServerFieldValue, serverStartCallLogLine.fields, \"PingList\", interceptors.ServerStream)\n\n\tclientStartCallLogLine := lines[1]\n\ts.Assert().Equal(logging.LevelDebug, clientStartCallLogLine.lvl)\n\ts.Assert().Equal(\"started call\", clientStartCallLogLine.msg)\n\t_ = assertStandardFields(s.T(), logging.KindClientFieldValue, clientStartCallLogLine.fields, \"PingList\", interceptors.ServerStream)\n\n\tserverFinishCallLogLine := lines[2]\n\ts.Assert().Equal(logging.LevelDebug, serverFinishCallLogLine.lvl)\n\ts.Assert().Equal(\"finished call\", serverFinishCallLogLine.msg)\n\tserverFinishCallFields := assertStandardFields(s.T(), logging.KindServerFieldValue, serverFinishCallLogLine.fields, \"PingList\", interceptors.ServerStream)\n\tserverFinishCallFields.AssertField(s.T(), \"custom-field\", \"yolo\").\n\t\t// should be updated from 0 to 42\n\t\tAssertField(s.T(), \"custom-ctx-field\", \"42\").\n\t\tAssertFieldNotEmpty(s.T(), \"peer.address\").\n\t\tAssertFieldNotEmpty(s.T(), \"grpc.start_time\").\n\t\tAssertFieldNotEmpty(s.T(), \"grpc.request.deadline\").\n\t\tAssertField(s.T(), \"grpc.code\", \"OK\").\n\t\tAssertFieldNotEmpty(s.T(), \"grpc.time_ms\").AssertNoMoreTags(s.T())\n\n\tclientFinishCallLogLine := lines[0]\n\ts.Assert().Equal(logging.LevelDebug, clientFinishCallLogLine.lvl)\n\ts.Assert().Equal(\"finished call\", clientFinishCallLogLine.msg)\n\tclientFinishCallFields := assertStandardFields(s.T(), logging.KindClientFieldValue, clientFinishCallLogLine.fields, \"PingList\", interceptors.ServerStream)\n\tclientFinishCallFields.AssertFieldNotEmpty(s.T(), \"grpc.start_time\").\n\t\tAssertField(s.T(), \"custom-field\", \"yolo\").\n\t\t// should be updated from 0 to 42\n\t\tAssertField(s.T(), \"custom-ctx-field\", \"42\").\n\t\tAssertFieldNotEmpty(s.T(), \"grpc.request.deadline\").\n\t\tAssertField(s.T(), \"grpc.code\", \"OK\").\n\t\tAssertFieldNotEmpty(s.T(), \"grpc.time_ms\").AssertNoMoreTags(s.T())\n}\n\nfunc (s *loggingClientServerSuite) TestPingError_WithCustomLevels() {\n\tfor _, tcase := range []struct {\n\t\tcode  codes.Code\n\t\tlevel logging.Level\n\t\tmsg   string\n\t}{\n\t\t{\n\t\t\tcode:  codes.Internal,\n\t\t\tlevel: logging.LevelWarn,\n\t\t\tmsg:   \"Internal must remap to WarnLevel in DefaultClientCodeToLevel\",\n\t\t},\n\t\t{\n\t\t\tcode:  codes.NotFound,\n\t\t\tlevel: logging.LevelDebug,\n\t\t\tmsg:   \"NotFound must remap to DebugLevel in DefaultClientCodeToLevel\",\n\t\t},\n\t\t{\n\t\t\tcode:  codes.FailedPrecondition,\n\t\t\tlevel: logging.LevelDebug,\n\t\t\tmsg:   \"FailedPrecondition must remap to DebugLevel in DefaultClientCodeToLevel\",\n\t\t},\n\t\t{\n\t\t\tcode:  codes.Unauthenticated,\n\t\t\tlevel: logging.LevelError,\n\t\t\tmsg:   \"Unauthenticated is overwritten to ErrorLevel with customClientCodeToLevel override, which probably didn't work\",\n\t\t},\n\t} {\n\t\ts.SetupTest()\n\t\ts.Run(tcase.msg, func() {\n\t\t\t_, err := s.Client.PingError(\n\t\t\t\ts.SimpleCtx(),\n\t\t\t\t&testpb.PingErrorRequest{Value: \"something\", ErrorCodeReturned: uint32(tcase.code)})\n\t\t\ts.Require().Error(err, \"each call here must return an error\")\n\t\t\tlines := s.logger.o.Lines()\n\t\t\tsort.Sort(lines)\n\t\t\ts.Require().Len(lines, 4)\n\n\t\t\tserverFinishCallLogLine := lines[2]\n\t\t\ts.Assert().Equal(tcase.level, serverFinishCallLogLine.lvl)\n\t\t\ts.Assert().Equal(\"finished call\", serverFinishCallLogLine.msg)\n\t\t\tserverFinishCallFields := assertStandardFields(s.T(), logging.KindServerFieldValue, serverFinishCallLogLine.fields, \"PingError\", interceptors.Unary)\n\t\t\tserverFinishCallFields.AssertField(s.T(), \"custom-field\", \"yolo\").\n\t\t\t\t// should be updated from 0 to 42\n\t\t\t\tAssertField(s.T(), \"custom-ctx-field\", \"42\").\n\t\t\t\tAssertFieldNotEmpty(s.T(), \"peer.address\").\n\t\t\t\tAssertFieldNotEmpty(s.T(), \"grpc.start_time\").\n\t\t\t\tAssertFieldNotEmpty(s.T(), \"grpc.request.deadline\").\n\t\t\t\tAssertField(s.T(), \"grpc.code\", tcase.code.String()).\n\t\t\t\tAssertField(s.T(), \"grpc.error\", fmt.Sprintf(\"rpc error: code = %s desc = Userspace error\", tcase.code.String())).\n\t\t\t\tAssertField(s.T(), \"error-field\", \"plop\").\n\t\t\t\tAssertFieldNotEmpty(s.T(), \"grpc.time_ms\").AssertNoMoreTags(s.T())\n\n\t\t\tclientFinishCallLogLine := lines[0]\n\t\t\ts.Assert().Equal(tcase.level, clientFinishCallLogLine.lvl)\n\t\t\ts.Assert().Equal(\"finished call\", clientFinishCallLogLine.msg)\n\t\t\tclientFinishCallFields := assertStandardFields(s.T(), logging.KindClientFieldValue, clientFinishCallLogLine.fields, \"PingError\", interceptors.Unary)\n\t\t\tclientFinishCallFields.AssertField(s.T(), \"custom-field\", \"yolo\").\n\t\t\t\t// should be updated from 0 to 42\n\t\t\t\tAssertField(s.T(), \"custom-ctx-field\", \"42\").\n\t\t\t\tAssertFieldNotEmpty(s.T(), \"grpc.start_time\").\n\t\t\t\tAssertFieldNotEmpty(s.T(), \"grpc.request.deadline\").\n\t\t\t\tAssertField(s.T(), \"grpc.code\", tcase.code.String()).\n\t\t\t\tAssertField(s.T(), \"grpc.error\", fmt.Sprintf(\"rpc error: code = %s desc = Userspace error\", tcase.code.String())).\n\t\t\t\tAssertFieldNotEmpty(s.T(), \"grpc.time_ms\").AssertNoMoreTags(s.T())\n\t\t})\n\t}\n}\n\ntype loggingCustomDurationSuite struct {\n\t*baseLoggingSuite\n}\n\nfunc TestCustomDurationSuite(t *testing.T) {\n\tif strings.HasPrefix(runtime.Version(), \"go1.7\") {\n\t\tt.Skipf(\"Skipping due to json.RawMessage incompatibility with go1.7\")\n\t\treturn\n\t}\n\n\ts := &loggingCustomDurationSuite{\n\t\tbaseLoggingSuite: &baseLoggingSuite{\n\t\t\tlogger: newMockLogger(),\n\t\t\tInterceptorTestSuite: &testpb.InterceptorTestSuite{\n\t\t\t\tTestService: &testpb.TestPingService{},\n\t\t\t},\n\t\t},\n\t}\n\ts.ClientOpts = []grpc.DialOption{\n\t\tgrpc.WithUnaryInterceptor(logging.UnaryClientInterceptor(s.logger, logging.WithDurationField(logging.DurationToDurationField))),\n\t\tgrpc.WithStreamInterceptor(logging.StreamClientInterceptor(s.logger, logging.WithDurationField(logging.DurationToDurationField))),\n\t}\n\ts.ServerOpts = []grpc.ServerOption{\n\t\tgrpc.StreamInterceptor(logging.StreamServerInterceptor(s.logger, logging.WithDurationField(logging.DurationToDurationField))),\n\t\tgrpc.UnaryInterceptor(logging.UnaryServerInterceptor(s.logger, logging.WithDurationField(logging.DurationToDurationField))),\n\t}\n\tsuite.Run(t, s)\n}\n\nfunc (s *loggingCustomDurationSuite) TestPing_HasOverriddenDuration() {\n\t_, err := s.Client.Ping(s.SimpleCtx(), testpb.GoodPing)\n\ts.Require().NoError(err, \"there must be not be an on a successful call\")\n\n\tlines := s.logger.o.Lines()\n\tsort.Sort(lines)\n\ts.Require().Len(lines, 4)\n\n\tserverStartedCallLogLine := lines[3]\n\ts.Assert().Equal(logging.LevelInfo, serverStartedCallLogLine.lvl)\n\ts.Assert().Equal(\"started call\", serverStartedCallLogLine.msg)\n\t_ = assertStandardFields(s.T(), logging.KindServerFieldValue, serverStartedCallLogLine.fields, \"Ping\", interceptors.Unary)\n\n\tclientStartedCallLogLine := lines[1]\n\ts.Assert().Equal(logging.LevelDebug, clientStartedCallLogLine.lvl)\n\ts.Assert().Equal(\"started call\", clientStartedCallLogLine.msg)\n\t_ = assertStandardFields(s.T(), logging.KindClientFieldValue, clientStartedCallLogLine.fields, \"Ping\", interceptors.Unary)\n\n\tserverFinishCallLogLine := lines[2]\n\ts.Assert().Equal(logging.LevelInfo, serverFinishCallLogLine.lvl)\n\ts.Assert().Equal(\"finished call\", serverFinishCallLogLine.msg)\n\tserverFinishCallFields := assertStandardFields(s.T(), logging.KindServerFieldValue, serverFinishCallLogLine.fields, \"Ping\", interceptors.Unary)\n\tserverFinishCallFields.AssertFieldNotEmpty(s.T(), \"peer.address\").\n\t\tAssertFieldNotEmpty(s.T(), \"grpc.start_time\").\n\t\tAssertFieldNotEmpty(s.T(), \"grpc.request.deadline\").\n\t\tAssertField(s.T(), \"grpc.code\", \"OK\").\n\t\tAssertFieldNotEmpty(s.T(), \"grpc.duration\").AssertNoMoreTags(s.T())\n\n\tclientFinishCallLogLine := lines[0]\n\ts.Assert().Equal(logging.LevelDebug, clientFinishCallLogLine.lvl)\n\ts.Assert().Equal(\"finished call\", clientFinishCallLogLine.msg)\n\tclientFinishCallFields := assertStandardFields(s.T(), logging.KindClientFieldValue, clientFinishCallLogLine.fields, \"Ping\", interceptors.Unary)\n\tclientFinishCallFields.AssertFieldNotEmpty(s.T(), \"grpc.start_time\").\n\t\tAssertFieldNotEmpty(s.T(), \"grpc.request.deadline\").\n\t\tAssertField(s.T(), \"grpc.code\", \"OK\").\n\t\tAssertFieldNotEmpty(s.T(), \"grpc.duration\").AssertNoMoreTags(s.T())\n}\n\nfunc (s *loggingCustomDurationSuite) TestPingList_HasOverriddenDuration() {\n\tstream, err := s.Client.PingList(s.SimpleCtx(), testpb.GoodPingList)\n\ts.Require().NoError(err, \"should not fail on establishing the stream\")\n\tfor {\n\t\t_, err := stream.Recv()\n\t\tif errors.Is(err, io.EOF) {\n\t\t\tbreak\n\t\t}\n\t\ts.Require().NoError(err, \"reading stream should not fail\")\n\t}\n\n\tlines := s.logger.o.Lines()\n\tsort.Sort(lines)\n\ts.Require().Len(lines, 4)\n\n\tserverStartedCallLogLine := lines[3]\n\ts.Assert().Equal(logging.LevelInfo, serverStartedCallLogLine.lvl)\n\ts.Assert().Equal(\"started call\", serverStartedCallLogLine.msg)\n\t_ = assertStandardFields(s.T(), logging.KindServerFieldValue, serverStartedCallLogLine.fields, \"PingList\", interceptors.ServerStream)\n\n\tclientStartedCallLogLine := lines[1]\n\ts.Assert().Equal(logging.LevelDebug, clientStartedCallLogLine.lvl)\n\ts.Assert().Equal(\"started call\", clientStartedCallLogLine.msg)\n\t_ = assertStandardFields(s.T(), logging.KindClientFieldValue, clientStartedCallLogLine.fields, \"PingList\", interceptors.ServerStream)\n\n\tserverFinishCallLogLine := lines[2]\n\ts.Assert().Equal(logging.LevelInfo, serverFinishCallLogLine.lvl)\n\ts.Assert().Equal(\"finished call\", serverFinishCallLogLine.msg)\n\tserverFinishCallFields := assertStandardFields(s.T(), logging.KindServerFieldValue, serverFinishCallLogLine.fields, \"PingList\", interceptors.ServerStream)\n\tserverFinishCallFields.AssertFieldNotEmpty(s.T(), \"peer.address\").\n\t\tAssertFieldNotEmpty(s.T(), \"grpc.start_time\").\n\t\tAssertFieldNotEmpty(s.T(), \"grpc.request.deadline\").\n\t\tAssertField(s.T(), \"grpc.code\", \"OK\").\n\t\tAssertFieldNotEmpty(s.T(), \"grpc.duration\").AssertNoMoreTags(s.T())\n\n\tclientFinishCallLogLine := lines[0]\n\ts.Assert().Equal(logging.LevelDebug, clientFinishCallLogLine.lvl)\n\ts.Assert().Equal(\"finished call\", clientFinishCallLogLine.msg)\n\tclientFinishCallFields := assertStandardFields(s.T(), logging.KindClientFieldValue, clientFinishCallLogLine.fields, \"PingList\", interceptors.ServerStream)\n\tclientFinishCallFields.AssertFieldNotEmpty(s.T(), \"grpc.start_time\").\n\t\tAssertFieldNotEmpty(s.T(), \"grpc.request.deadline\").\n\t\tAssertField(s.T(), \"grpc.code\", \"OK\").\n\t\tAssertFieldNotEmpty(s.T(), \"grpc.duration\").AssertNoMoreTags(s.T())\n}\n\ntype loggingPayloadSuite struct {\n\t*baseLoggingSuite\n}\n\nfunc TestPayloadSuite(t *testing.T) {\n\ts := &loggingPayloadSuite{\n\t\tbaseLoggingSuite: &baseLoggingSuite{\n\t\t\tlogger: newMockLogger(),\n\t\t\tInterceptorTestSuite: &testpb.InterceptorTestSuite{\n\t\t\t\tTestService: &testpb.TestPingService{},\n\t\t\t},\n\t\t},\n\t}\n\ts.ClientOpts = []grpc.DialOption{\n\t\tgrpc.WithUnaryInterceptor(logging.UnaryClientInterceptor(\n\t\t\ts.logger,\n\t\t\tlogging.WithLogOnEvents(logging.PayloadReceived, logging.PayloadSent),\n\t\t\tlogging.WithLevels(logging.DefaultClientCodeToLevel),\n\t\t)),\n\t\tgrpc.WithStreamInterceptor(logging.StreamClientInterceptor(s.logger,\n\t\t\tlogging.WithLogOnEvents(logging.PayloadReceived, logging.PayloadSent),\n\t\t\tlogging.WithLevels(logging.DefaultClientCodeToLevel),\n\t\t)),\n\t}\n\ts.ServerOpts = []grpc.ServerOption{\n\t\tgrpc.StreamInterceptor(logging.StreamServerInterceptor(s.logger,\n\t\t\tlogging.WithLogOnEvents(logging.PayloadReceived, logging.PayloadSent),\n\t\t\tlogging.WithLevels(logging.DefaultServerCodeToLevel),\n\t\t)),\n\t\tgrpc.UnaryInterceptor(logging.UnaryServerInterceptor(s.logger,\n\t\t\tlogging.WithLogOnEvents(logging.PayloadReceived, logging.PayloadSent),\n\t\t\tlogging.WithLevels(logging.DefaultServerCodeToLevel),\n\t\t)),\n\t}\n\tsuite.Run(t, s)\n}\n\nfunc (s *loggingPayloadSuite) TestPing_LogsBothRequestAndResponse() {\n\t_, err := s.Client.Ping(s.SimpleCtx(), testpb.GoodPing)\n\ts.Require().NoError(err, \"there must be not be an error on a successful call\")\n\n\tlines := s.logger.o.Lines()\n\ts.Require().Len(lines, 4)\n\ts.assertPayloadLogLinesForMessage(lines, \"Ping\", interceptors.Unary)\n}\n\nfunc (s *loggingPayloadSuite) TestPingError_LogsOnlyRequestsOnError() {\n\t_, err := s.Client.PingError(s.SimpleCtx(), &testpb.PingErrorRequest{Value: \"something\", ErrorCodeReturned: uint32(4)})\n\ts.Require().Error(err, \"there must be an error on an unsuccessful call\")\n\n\tlines := s.logger.o.Lines()\n\tsort.Sort(lines)\n\ts.Require().Len(lines, 2) // Only one client and one server for request, since no response (error).\n\tclientRequestLogLine := lines[0]\n\ts.Assert().Equal(logging.DefaultClientCodeToLevel(codes.OK), clientRequestLogLine.lvl)\n\ts.Assert().Equal(\"request sent\", clientRequestLogLine.msg)\n\tclientRequestFields := assertStandardFields(s.T(), logging.KindClientFieldValue, clientRequestLogLine.fields, \"PingError\", interceptors.Unary)\n\n\tclientRequestFields.AssertFieldNotEmpty(s.T(), \"grpc.start_time\").\n\t\tAssertFieldNotEmpty(s.T(), \"grpc.send.duration\").\n\t\tAssertFieldNotEmpty(s.T(), \"grpc.time_ms\").\n\t\tAssertField(s.T(), \"grpc.request.content\", `{\"value\":\"something\",\"errorCodeReturned\":4}`).\n\t\tAssertFieldNotEmpty(s.T(), \"grpc.request.deadline\").AssertNoMoreTags(s.T())\n}\n\nfunc (s *loggingPayloadSuite) TestPingStream_LogsAllRequestsAndResponses() {\n\tmessagesExpected := 20\n\tstream, err := s.Client.PingStream(s.SimpleCtx())\n\n\ts.Require().NoError(err, \"no error on stream creation\")\n\tfor i := 0; i < messagesExpected; i++ {\n\t\ts.Require().NoError(stream.Send(testpb.GoodPingStream), \"sending must succeed\")\n\n\t\tpong := &testpb.PingResponse{}\n\t\terr := stream.RecvMsg(pong)\n\t\ts.Require().NoError(err, \"no error on receive\")\n\t}\n\ts.Require().NoError(stream.CloseSend(), \"no error on send stream\")\n\n\tctx, cancel := context.WithTimeout(context.Background(), 2*time.Minute)\n\tdefer cancel()\n\ts.Require().NoError(waitUntil(200*time.Millisecond, ctx.Done(), func() error {\n\t\tgot := len(s.logger.o.Lines())\n\t\tif got >= 4*messagesExpected {\n\t\t\treturn nil\n\t\t}\n\t\treturn fmt.Errorf(\"not enough log lines, waiting; got: %v\", got)\n\t}))\n\ts.assertPayloadLogLinesForMessage(s.logger.o.Lines(), \"PingStream\", interceptors.BidiStream)\n}\n\nfunc (s *loggingPayloadSuite) assertPayloadLogLinesForMessage(lines LogLines, method string, typ interceptors.GRPCType) {\n\t// Order matter for assertion, we don't rely on it though, so sort.\n\tsort.Sort(lines)\n\n\trepetitions := len(lines) / 4\n\tcurr := 0\n\tfor i := curr; i < repetitions; i++ {\n\t\tclientRequestLogLine := lines[i]\n\t\ts.Assert().Equal(logging.DefaultClientCodeToLevel(codes.OK), clientRequestLogLine.lvl)\n\t\ts.Assert().Equal(\"request sent\", clientRequestLogLine.msg)\n\t\tclientRequestFields := assertStandardFields(s.T(), logging.KindClientFieldValue, clientRequestLogLine.fields, method, typ)\n\t\tclientRequestFields.AssertFieldNotEmpty(s.T(), \"grpc.start_time\").\n\t\t\tAssertFieldNotEmpty(s.T(), \"grpc.send.duration\").\n\t\t\tAssertFieldNotEmpty(s.T(), \"grpc.time_ms\").\n\t\t\tAssertField(s.T(), \"grpc.request.content\", `{\"value\":\"something\",\"sleepTimeMs\":9999}`).\n\t\t\tAssertFieldNotEmpty(s.T(), \"grpc.request.deadline\").AssertNoMoreTags(s.T())\n\t}\n\tcurr += repetitions\n\tfor i := curr; i < curr+repetitions; i++ {\n\t\tclientResponseLogLine := lines[i]\n\t\ts.Assert().Equal(logging.DefaultClientCodeToLevel(codes.OK), clientResponseLogLine.lvl)\n\t\ts.Assert().Equal(\"response received\", clientResponseLogLine.msg)\n\t\tclientResponseFields := assertStandardFields(s.T(), logging.KindClientFieldValue, clientResponseLogLine.fields, method, typ)\n\t\tclientResponseFields = clientResponseFields.AssertFieldNotEmpty(s.T(), \"grpc.start_time\").\n\t\t\tAssertFieldNotEmpty(s.T(), \"grpc.recv.duration\").\n\t\t\tAssertFieldNotEmpty(s.T(), \"grpc.time_ms\").\n\t\t\tAssertFieldNotEmpty(s.T(), \"grpc.request.deadline\")\n\t\tif i-curr == 0 {\n\t\t\tclientResponseFields = clientResponseFields.AssertField(s.T(), \"grpc.response.content\", `{\"value\":\"something\"}`)\n\t\t} else {\n\t\t\tclientResponseFields = clientResponseFields.AssertField(s.T(), \"grpc.response.content\", fmt.Sprintf(`{\"value\":\"something\",\"counter\":%v}`, i-curr))\n\t\t}\n\t\tclientResponseFields.AssertNoMoreTags(s.T())\n\t}\n\tcurr += repetitions\n\tfor i := curr; i < curr+repetitions; i++ {\n\t\tserverRequestLogLine := lines[i]\n\t\ts.Assert().Equal(logging.DefaultServerCodeToLevel(codes.OK), serverRequestLogLine.lvl)\n\t\ts.Assert().Equal(\"request received\", serverRequestLogLine.msg)\n\t\tserverRequestFields := assertStandardFields(s.T(), logging.KindServerFieldValue, serverRequestLogLine.fields, method, typ)\n\t\tserverRequestFields.AssertFieldNotEmpty(s.T(), \"peer.address\").\n\t\t\tAssertFieldNotEmpty(s.T(), \"grpc.start_time\").\n\t\t\tAssertFieldNotEmpty(s.T(), \"grpc.recv.duration\").\n\t\t\tAssertFieldNotEmpty(s.T(), \"grpc.request.deadline\").\n\t\t\tAssertFieldNotEmpty(s.T(), \"grpc.time_ms\").\n\t\t\tAssertField(s.T(), \"grpc.request.content\", `{\"value\":\"something\",\"sleepTimeMs\":9999}`).AssertNoMoreTags(s.T())\n\t}\n\tcurr += repetitions\n\tfor i := curr; i < curr+repetitions; i++ {\n\t\tserverResponseLogLine := lines[i]\n\t\ts.Assert().Equal(logging.DefaultServerCodeToLevel(codes.OK), serverResponseLogLine.lvl)\n\t\ts.Assert().Equal(\"response sent\", serverResponseLogLine.msg)\n\t\tserverResponseFields := assertStandardFields(s.T(), logging.KindServerFieldValue, serverResponseLogLine.fields, method, typ)\n\t\tserverResponseFields = serverResponseFields.AssertFieldNotEmpty(s.T(), \"peer.address\").\n\t\t\tAssertFieldNotEmpty(s.T(), \"grpc.start_time\").\n\t\t\tAssertFieldNotEmpty(s.T(), \"grpc.send.duration\").\n\t\t\tAssertFieldNotEmpty(s.T(), \"grpc.time_ms\").\n\t\t\tAssertFieldNotEmpty(s.T(), \"grpc.request.deadline\")\n\t\tif i-curr == 0 {\n\t\t\tserverResponseFields = serverResponseFields.AssertField(s.T(), \"grpc.response.content\", `{\"value\":\"something\"}`)\n\t\t} else {\n\t\t\tserverResponseFields = serverResponseFields.AssertField(s.T(), \"grpc.response.content\", fmt.Sprintf(`{\"value\":\"something\",\"counter\":%v}`, i-curr))\n\t\t}\n\t\tserverResponseFields.AssertNoMoreTags(s.T())\n\t}\n}\n\ntype loggingCustomGrpcLogFieldsSuite struct {\n\t*baseLoggingSuite\n}\n\nfunc TestCustomGrpcLogFieldsSuite(t *testing.T) {\n\tif strings.HasPrefix(runtime.Version(), \"go1.7\") {\n\t\tt.Skipf(\"Skipping due to json.RawMessage incompatibility with go1.7\")\n\t\treturn\n\t}\n\ts := &loggingCustomGrpcLogFieldsSuite{\n\t\tbaseLoggingSuite: &baseLoggingSuite{\n\t\t\tlogger: newMockLogger(),\n\t\t\tInterceptorTestSuite: &testpb.InterceptorTestSuite{\n\t\t\t\tTestService: &testpb.TestPingService{},\n\t\t\t},\n\t\t},\n\t}\n\ts.ClientOpts = []grpc.DialOption{\n\t\tgrpc.WithUnaryInterceptor(logging.UnaryClientInterceptor(s.logger, logging.WithDisableLoggingFields(logging.ComponentFieldKey, logging.MethodTypeFieldKey, logging.SystemTag[0], \"custom-field-should-be-ignored\"))),\n\t\tgrpc.WithStreamInterceptor(logging.StreamClientInterceptor(s.logger, logging.WithDisableLoggingFields(logging.ComponentFieldKey, logging.MethodTypeFieldKey, logging.SystemTag[0], \"custom-field-should-be-ignored\"))),\n\t}\n\ts.ServerOpts = []grpc.ServerOption{\n\t\tgrpc.StreamInterceptor(logging.StreamServerInterceptor(s.logger, logging.WithDisableLoggingFields(logging.ComponentFieldKey, logging.MethodTypeFieldKey, logging.SystemTag[0], \"custom-field-should-be-ignored\"))),\n\t\tgrpc.UnaryInterceptor(logging.UnaryServerInterceptor(s.logger, logging.WithDisableLoggingFields(logging.ComponentFieldKey, logging.MethodTypeFieldKey, logging.SystemTag[0], \"custom-field-should-be-ignore\"))),\n\t}\n\tsuite.Run(t, s)\n}\n\n// Test that fields are added to logs using withGrpcLogFields.\nfunc (s *loggingCustomGrpcLogFieldsSuite) TestCustomGrpcLogFieldsWithPing() {\n\t_, err := s.Client.Ping(s.SimpleCtx(), testpb.GoodPing)\n\ts.Require().NoError(err, \"there must be not be an on a successful call\")\n\n\tlines := s.logger.o.Lines()\n\tsort.Sort(lines)\n\ts.Require().Len(lines, 4)\n\n\tclientStartCallLogLine := lines[2]\n\ts.Assert().Equal(logging.LevelDebug, clientStartCallLogLine.lvl)\n\ts.Assert().Equal(\"started call\", clientStartCallLogLine.msg)\n\tclientStartCallFields := clientStartCallLogLine.fields\n\tclientStartCallFields.AssertFieldNotEmpty(s.T(), \"grpc.start_time\").\n\t\tAssertFieldNotEmpty(s.T(), \"grpc.request.deadline\").\n\t\tAssertFieldNotEmpty(s.T(), \"grpc.time_ms\").\n\t\tAssertField(s.T(), logging.MethodFieldKey, \"Ping\").\n\t\tAssertField(s.T(), logging.ServiceFieldKey, testpb.TestServiceFullName).AssertNoMoreTags(s.T())\n\n\tserverStartCallLogLine := lines[3]\n\ts.Assert().Equal(logging.LevelInfo, serverStartCallLogLine.lvl)\n\ts.Assert().Equal(\"started call\", serverStartCallLogLine.msg)\n\tserverStartCallFields := serverStartCallLogLine.fields\n\tserverStartCallFields.AssertFieldNotEmpty(s.T(), \"peer.address\").\n\t\tAssertFieldNotEmpty(s.T(), \"grpc.start_time\").\n\t\tAssertFieldNotEmpty(s.T(), \"grpc.request.deadline\").\n\t\tAssertFieldNotEmpty(s.T(), \"grpc.time_ms\").\n\t\tAssertField(s.T(), logging.MethodFieldKey, \"Ping\").\n\t\tAssertField(s.T(), logging.ServiceFieldKey, testpb.TestServiceFullName).AssertNoMoreTags(s.T())\n\n\tserverFinishCallLogLine := lines[0]\n\ts.Assert().Equal(logging.LevelInfo, serverFinishCallLogLine.lvl)\n\ts.Assert().Equal(\"finished call\", serverFinishCallLogLine.msg)\n\tserverFinishCallFields := serverFinishCallLogLine.fields\n\tserverFinishCallFields.AssertFieldNotEmpty(s.T(), \"peer.address\").\n\t\tAssertFieldNotEmpty(s.T(), \"grpc.start_time\").\n\t\tAssertFieldNotEmpty(s.T(), \"grpc.request.deadline\").\n\t\tAssertField(s.T(), \"grpc.code\", \"OK\").\n\t\tAssertFieldNotEmpty(s.T(), \"grpc.time_ms\").\n\t\tAssertField(s.T(), logging.MethodFieldKey, \"Ping\").\n\t\tAssertField(s.T(), logging.ServiceFieldKey, testpb.TestServiceFullName).AssertNoMoreTags(s.T())\n\n\tclientFinishCallLogLine := lines[1]\n\ts.Assert().Equal(logging.LevelDebug, clientFinishCallLogLine.lvl)\n\ts.Assert().Equal(\"finished call\", clientFinishCallLogLine.msg)\n\n\tclientFinishCallFields := clientFinishCallLogLine.fields\n\tclientFinishCallFields.AssertFieldNotEmpty(s.T(), \"grpc.start_time\").\n\t\tAssertFieldNotEmpty(s.T(), \"grpc.request.deadline\").\n\t\tAssertField(s.T(), \"grpc.code\", \"OK\").\n\t\tAssertFieldNotEmpty(s.T(), \"grpc.time_ms\").\n\t\tAssertField(s.T(), logging.MethodFieldKey, \"Ping\").\n\t\tAssertField(s.T(), logging.ServiceFieldKey, testpb.TestServiceFullName).AssertNoMoreTags(s.T())\n}\n\nfunc (s *loggingCustomGrpcLogFieldsSuite) TestCustomGrpcLogFieldsWithPingList() {\n\tstream, err := s.Client.PingList(s.SimpleCtx(), testpb.GoodPingList)\n\ts.Require().NoError(err, \"should not fail on establishing the stream\")\n\tfor {\n\t\t_, err := stream.Recv()\n\t\tif errors.Is(err, io.EOF) {\n\t\t\tbreak\n\t\t}\n\t\ts.Require().NoError(err, \"reading stream should not fail\")\n\t}\n\tlines := s.logger.o.Lines()\n\tsort.Sort(lines)\n\ts.Require().Len(lines, 4)\n\n\tclientStartCallLogLine := lines[2]\n\ts.Assert().Equal(logging.LevelDebug, clientStartCallLogLine.lvl)\n\ts.Assert().Equal(\"started call\", clientStartCallLogLine.msg)\n\tclientStartCallFields := clientStartCallLogLine.fields\n\tclientStartCallFields.AssertFieldNotEmpty(s.T(), \"grpc.start_time\").\n\t\tAssertFieldNotEmpty(s.T(), \"grpc.request.deadline\").\n\t\tAssertFieldNotEmpty(s.T(), \"grpc.time_ms\").\n\t\tAssertField(s.T(), logging.MethodFieldKey, \"PingList\").\n\t\tAssertField(s.T(), logging.ServiceFieldKey, testpb.TestServiceFullName).AssertNoMoreTags(s.T())\n\n\tserverStartCallLogLine := lines[3]\n\ts.Assert().Equal(logging.LevelInfo, serverStartCallLogLine.lvl)\n\ts.Assert().Equal(\"started call\", serverStartCallLogLine.msg)\n\tserverStartCallFields := serverStartCallLogLine.fields\n\tserverStartCallFields.AssertFieldNotEmpty(s.T(), \"peer.address\").\n\t\tAssertFieldNotEmpty(s.T(), \"grpc.start_time\").\n\t\tAssertFieldNotEmpty(s.T(), \"grpc.request.deadline\").\n\t\tAssertFieldNotEmpty(s.T(), \"grpc.time_ms\").\n\t\tAssertField(s.T(), logging.MethodFieldKey, \"PingList\").\n\t\tAssertField(s.T(), logging.ServiceFieldKey, testpb.TestServiceFullName).AssertNoMoreTags(s.T())\n\n\tserverFinishCallLogLine := lines[0]\n\ts.Assert().Equal(logging.LevelInfo, serverFinishCallLogLine.lvl)\n\ts.Assert().Equal(\"finished call\", serverFinishCallLogLine.msg)\n\tserverFinishCallFields := serverFinishCallLogLine.fields\n\tserverFinishCallFields.AssertFieldNotEmpty(s.T(), \"peer.address\").\n\t\tAssertFieldNotEmpty(s.T(), \"grpc.start_time\").\n\t\tAssertFieldNotEmpty(s.T(), \"grpc.request.deadline\").\n\t\tAssertField(s.T(), \"grpc.code\", \"OK\").\n\t\tAssertFieldNotEmpty(s.T(), \"grpc.time_ms\").\n\t\tAssertField(s.T(), logging.MethodFieldKey, \"PingList\").\n\t\tAssertField(s.T(), logging.ServiceFieldKey, testpb.TestServiceFullName).AssertNoMoreTags(s.T())\n\n\tclientFinishCallLogLine := lines[1]\n\ts.Assert().Equal(logging.LevelDebug, clientFinishCallLogLine.lvl)\n\ts.Assert().Equal(\"finished call\", clientFinishCallLogLine.msg)\n\n\tclientFinishCallFields := clientFinishCallLogLine.fields\n\tclientFinishCallFields.AssertFieldNotEmpty(s.T(), \"grpc.start_time\").\n\t\tAssertFieldNotEmpty(s.T(), \"grpc.request.deadline\").\n\t\tAssertField(s.T(), \"grpc.code\", \"OK\").\n\t\tAssertFieldNotEmpty(s.T(), \"grpc.time_ms\").\n\t\tAssertField(s.T(), logging.MethodFieldKey, \"PingList\").\n\t\tAssertField(s.T(), logging.ServiceFieldKey, testpb.TestServiceFullName).AssertNoMoreTags(s.T())\n}\n\n// waitUntil executes f every interval seconds until timeout or no error is returned from f.\nfunc waitUntil(interval time.Duration, stopc <-chan struct{}, f func() error) error {\n\ttick := time.NewTicker(interval)\n\tdefer tick.Stop()\n\n\tvar err error\n\tfor {\n\t\tif err = f(); err == nil {\n\t\t\treturn nil\n\t\t}\n\t\tselect {\n\t\tcase <-stopc:\n\t\t\treturn err\n\t\tcase <-tick.C:\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "interceptors/logging/logging.go",
    "content": "// Copyright (c) The go-grpc-middleware Authors.\n// Licensed under the Apache License 2.0.\n\npackage logging\n\nimport (\n\t\"context\"\n\n\t\"github.com/grpc-ecosystem/go-grpc-middleware/v2/interceptors\"\n)\n\nvar (\n\t// SystemTag is tag representing an event inside gRPC call.\n\tSystemTag = []string{\"protocol\", \"grpc\"}\n\t// ComponentFieldKey is a tag representing the client/server that is calling.\n\tComponentFieldKey    = \"grpc.component\"\n\tKindServerFieldValue = \"server\"\n\tKindClientFieldValue = \"client\"\n\tServiceFieldKey      = \"grpc.service\"\n\tMethodFieldKey       = \"grpc.method\"\n\tMethodTypeFieldKey   = \"grpc.method_type\"\n)\n\ntype (\n\tfieldsCtxMarker struct{}\n\tfieldsCtxValue  struct {\n\t\tfields Fields\n\t}\n)\n\n// fieldsCtxMarkerKey is the Context value marker that is used by logging middleware to read and write logging fields into context.\nvar fieldsCtxMarkerKey = &fieldsCtxMarker{}\n\nfunc newCommonFields(kind string, c interceptors.CallMeta) Fields {\n\treturn Fields{\n\t\tSystemTag[0], SystemTag[1],\n\t\tComponentFieldKey, kind,\n\t\tServiceFieldKey, c.Service,\n\t\tMethodFieldKey, c.Method,\n\t\tMethodTypeFieldKey, string(c.Typ),\n\t}\n}\n\n// disableCommonLoggingFields returns copy of newCommonFields with disabled fields removed from the following\n// default list. The following are the default logging fields:\n//   - SystemTag[0]\n//   - ComponentFieldKey\n//   - ServiceFieldKey\n//   - MethodFieldKey\n//   - MethodTypeFieldKey\nfunc disableCommonLoggingFields(kind string, c interceptors.CallMeta, disableFields []string) Fields {\n\tcommonFields := newCommonFields(kind, c)\n\tfor _, key := range disableFields {\n\t\tcommonFields.Delete(key)\n\t}\n\treturn commonFields\n}\n\n// Fields loosely represents key value pairs that adds context to log lines. The key has to be type of string, whereas\n// value can be an arbitrary object.\ntype Fields []any\n\n// Iterator returns iterator that allows iterating over pair of elements representing field.\n// If number of elements is uneven, last element won't be included will be assumed as key with empty string value.\n// If key is not string, At will panic.\nfunc (f Fields) Iterator() *iter {\n\t// We start from -2 as we iterate over two items per iteration and first iteration will advance iterator to 0.\n\treturn &iter{i: -2, f: f}\n}\n\ntype iter struct {\n\tf Fields\n\ti int\n}\n\nfunc (i *iter) Next() bool {\n\tif i.i >= len(i.f) {\n\t\treturn false\n\t}\n\n\ti.i += 2\n\treturn i.i < len(i.f)\n}\n\nfunc (i *iter) At() (k string, v any) {\n\tif i.i < 0 || i.i >= len(i.f) {\n\t\treturn \"\", \"\"\n\t}\n\n\tif i.i+1 == len(i.f) {\n\t\t// Non even number of elements, add empty string.\n\t\treturn i.f[i.i].(string), \"\"\n\t}\n\treturn i.f[i.i].(string), i.f[i.i+1]\n}\n\nfunc (f *Fields) Delete(key string) {\n\ti := f.Iterator()\n\tfor i.Next() {\n\t\tk, _ := i.At()\n\t\tif k != key {\n\t\t\tcontinue\n\t\t}\n\t\t*f = append((*f)[:i.i], (*f)[i.i+2:]...)\n\t\treturn\n\t}\n}\n\n// WithUnique returns copy of fields which is the union of all unique keys.\n// Any duplicates in the added or current fields will be deduplicated where first occurrence takes precedence.\nfunc (f Fields) WithUnique(add Fields) Fields {\n\tif len(add) == 0 {\n\t\tn := make(Fields, len(f))\n\t\tcopy(n, f)\n\t\treturn n\n\t}\n\n\texisting := map[any]struct{}{}\n\ti := f.Iterator()\n\tfor i.Next() {\n\t\tk, _ := i.At()\n\t\texisting[k] = struct{}{}\n\t}\n\n\tn := make(Fields, len(f), len(f)+len(add))\n\tcopy(n, f)\n\n\ta := add.Iterator()\n\tfor a.Next() {\n\t\tk, v := a.At()\n\t\tif _, ok := existing[k]; ok {\n\t\t\tcontinue\n\t\t}\n\t\tn = append(n, k, v)\n\t}\n\treturn n\n}\n\n// AppendUnique appends (can reuse array!) fields which does not occur in existing fields slice.\nfunc (f Fields) AppendUnique(add Fields) Fields {\n\tif len(add) == 0 {\n\t\treturn f\n\t}\n\n\ta := add.Iterator()\nNextAddField:\n\tfor a.Next() {\n\t\tk, v := a.At()\n\t\ti := f.Iterator()\n\t\tfor i.Next() {\n\t\t\tfk, _ := i.At()\n\t\t\tif fk == k {\n\t\t\t\tcontinue NextAddField\n\t\t\t}\n\t\t}\n\t\tf = append(f, k, v)\n\t}\n\treturn f\n}\n\n// ExtractFields returns logging fields from the context.\n// Fields can be added from the context using InjectFields. For example logging interceptor adds some (base) fields\n// into context when used.\n// If there are no fields in the context, it returns an empty Fields value.\n// Extracted fields are useful to construct your own logger that has fields from gRPC interceptors.\nfunc ExtractFields(ctx context.Context) Fields {\n\tt, ok := ctx.Value(fieldsCtxMarkerKey).(*fieldsCtxValue)\n\tif !ok {\n\t\treturn nil\n\t}\n\tn := make(Fields, len(t.fields))\n\tcopy(n, t.fields)\n\treturn n\n}\n\n// InjectFields returns a new context with merged fields that will be used by the logging interceptor or can be\n// extracted further in ExtractFields.\n// For explicitness, in case of duplicates, the newest field occurrence wins. This allows nested components to update\n// popular fields like grpc.component (e.g. server invoking gRPC client).\n//\n// Don't overuse mutation of fields to avoid surprises.\nfunc InjectFields(ctx context.Context, f Fields) context.Context {\n\treturn context.WithValue(ctx, fieldsCtxMarkerKey, &fieldsCtxValue{fields: f.WithUnique(ExtractFields(ctx))})\n}\n\n// InjectLogField is like InjectFields, just for one field.\nfunc InjectLogField(ctx context.Context, key string, val any) context.Context {\n\treturn InjectFields(ctx, Fields{key, val})\n}\n\n// AddFields updates the fields already in the context that will be used by the logging interceptor or can be\n// extracted further in ExtractFields. For explicitness, in case of duplicates, the newest field occurrence wins.\n//\n// InjectFields should be used instead of AddFields where possible, as it does not require mutating the values\n// already in the context.\n//\n// This function is not safe to call concurrently.\nfunc AddFields(ctx context.Context, f Fields) {\n\tt, ok := ctx.Value(fieldsCtxMarkerKey).(*fieldsCtxValue)\n\tif !ok {\n\t\treturn\n\t}\n\tt.fields = f.AppendUnique(t.fields)\n}\n\n// Logger requires Log method, similar to experimental slog, allowing logging interceptor to be interoperable. Official\n// adapters for popular loggers are in `provider/` directory (separate modules). It's totally ok to copy simple function\n// implementation over.\n// TODO(bwplotka): Once slog is official, we could use slog method directly. Currently level is copied over, so we don't\n// depend on experimental module.\n// interface used for all our interceptors.\ntype Logger interface {\n\tLog(ctx context.Context, level Level, msg string, fields ...any)\n}\n\n// LoggerFunc is a function that also implements Logger interface.\ntype LoggerFunc func(ctx context.Context, level Level, msg string, fields ...any)\n\nfunc (f LoggerFunc) Log(ctx context.Context, level Level, msg string, fields ...any) {\n\tf(ctx, level, msg, fields...)\n}\n"
  },
  {
    "path": "interceptors/logging/logging_test.go",
    "content": "// Copyright (c) The go-grpc-middleware Authors.\n// Licensed under the Apache License 2.0.\n\npackage logging\n\nimport (\n\t\"context\"\n\t\"testing\"\n\n\t\"github.com/stretchr/testify/require\"\n)\n\nfunc TestFieldsInjectExtractFromContext(t *testing.T) {\n\tc := context.Background()\n\tf := ExtractFields(c)\n\trequire.Equal(t, Fields(nil), f)\n\n\tf = f.AppendUnique([]any{\"a\", \"1\", \"b\", \"2\"})\n\trequire.Equal(t, Fields{\"a\", \"1\", \"b\", \"2\"}, f)\n\n\tc2 := InjectFields(c, f)\n\n\t// First context should be untouched.\n\tf = ExtractFields(c)\n\trequire.Equal(t, Fields(nil), f)\n\tf = ExtractFields(c2)\n\trequire.Equal(t, Fields{\"a\", \"1\", \"b\", \"2\"}, f)\n\n\tf = Fields{\"a\", \"changed\"}.WithUnique(f)\n\trequire.Equal(t, Fields{\"a\", \"changed\", \"b\", \"2\"}, f)\n\n\tc3 := InjectFields(c, f)\n\n\t// Old contexts should be untouched.\n\tf = ExtractFields(c)\n\trequire.Equal(t, Fields(nil), f)\n\tf = ExtractFields(c2)\n\trequire.Equal(t, Fields{\"a\", \"1\", \"b\", \"2\"}, f)\n\tf = ExtractFields(c3)\n\trequire.Equal(t, Fields{\"a\", \"changed\", \"b\", \"2\"}, f)\n}\n\nfunc TestFieldsDelete(t *testing.T) {\n\tf := Fields{\"a\", \"1\", \"b\", \"2\"}\n\tf.Delete(\"a\")\n\trequire.Equal(t, Fields{\"b\", \"2\"}, f)\n\tf.Delete(\"b\")\n\trequire.Equal(t, Fields{}, f)\n\tf.Delete(\"c\")\n\trequire.Equal(t, Fields{}, f)\n}\n\nfunc TestAddFields(t *testing.T) {\n\tc := InjectFields(context.Background(), Fields{\"a\", \"2\", \"c\", \"3\"})\n\tf := ExtractFields(c)\n\trequire.Equal(t, Fields{\"a\", \"2\", \"c\", \"3\"}, f)\n\tAddFields(c, Fields{\"a\", \"1\", \"b\", \"2\"})\n\n\t// First context should have updated values.\n\tf = ExtractFields(c)\n\trequire.Equal(t, Fields{\"a\", \"1\", \"b\", \"2\", \"c\", \"3\"}, f)\n}\n"
  },
  {
    "path": "interceptors/logging/options.go",
    "content": "// Copyright (c) The go-grpc-middleware Authors.\n// Licensed under the Apache License 2.0.\n\npackage logging\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"time\"\n\n\t\"github.com/grpc-ecosystem/go-grpc-middleware/v2/interceptors\"\n\t\"google.golang.org/grpc/codes\"\n\t\"google.golang.org/grpc/status\"\n)\n\n// LoggableEvent defines the events a log line can be added on.\ntype LoggableEvent uint\n\nconst (\n\t// StartCall is a loggable event representing start of the gRPC call.\n\tStartCall LoggableEvent = iota\n\t// FinishCall is a loggable event representing finish of the gRPC call.\n\tFinishCall\n\t// PayloadReceived is a loggable event representing received request (server) or response (client).\n\t// Log line for this event also includes (potentially big) proto.Message of that payload in\n\t// \"grpc.request.content\" (server) or \"grpc.response.content\" (client) field.\n\t// NOTE: This can get quite verbose, especially for streaming calls, use with caution (e.g. debug only purposes).\n\tPayloadReceived\n\t// PayloadSent is a loggable event representing sent response (server) or request (client).\n\t// Log line for this event also includes (potentially big) proto.Message of that payload in\n\t// \"grpc.response.content\" (server) or \"grpc.request.content\" (client) field.\n\t// NOTE: This can get quite verbose, especially for streaming calls, use with caution (e.g. debug only purposes).\n\tPayloadSent\n)\n\nfunc has(events []LoggableEvent, event LoggableEvent) bool {\n\tfor _, e := range events {\n\t\tif e == event {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n\nvar defaultOptions = &options{\n\tloggableEvents:    []LoggableEvent{StartCall, FinishCall},\n\tcodeFunc:          DefaultErrorToCode,\n\tdurationFieldFunc: DefaultDurationToFields,\n\t// levelFunc depends if it's client or server.\n\tlevelFunc:            nil,\n\ttimestampFormat:      time.RFC3339,\n\tdisableGrpcLogFields: nil,\n}\n\ntype options struct {\n\tlevelFunc               CodeToLevel\n\tloggableEvents          []LoggableEvent\n\terrorToFieldsFunc       ErrorToFields\n\tcodeFunc                ErrorToCode\n\tdurationFieldFunc       DurationToFields\n\ttimestampFormat         string\n\tfieldsFromCtxCallMetaFn fieldsFromCtxCallMetaFn\n\tdisableGrpcLogFields    []string\n}\n\ntype Option func(*options)\n\nfunc evaluateServerOpt(opts []Option) *options {\n\toptCopy := &options{}\n\t*optCopy = *defaultOptions\n\toptCopy.levelFunc = DefaultServerCodeToLevel\n\tfor _, o := range opts {\n\t\to(optCopy)\n\t}\n\treturn optCopy\n}\n\nfunc evaluateClientOpt(opts []Option) *options {\n\toptCopy := &options{}\n\t*optCopy = *defaultOptions\n\toptCopy.levelFunc = DefaultClientCodeToLevel\n\tfor _, o := range opts {\n\t\to(optCopy)\n\t}\n\treturn optCopy\n}\n\n// DurationToFields function defines how to produce duration fields for logging.\ntype DurationToFields func(duration time.Duration) Fields\n\n// ErrorToFields function extract fields from error.\ntype ErrorToFields func(err error) Fields\n\n// ErrorToCode function determines the error code of an error.\n// This makes using custom errors with grpc middleware easier.\ntype ErrorToCode func(err error) codes.Code\n\nfunc DefaultErrorToCode(err error) codes.Code {\n\treturn status.Code(err)\n}\n\n// CodeToLevel function defines the mapping between gRPC return codes and interceptor log level.\ntype CodeToLevel func(code codes.Code) Level\n\n// DefaultServerCodeToLevel is the helper mapper that maps gRPC return codes to log levels for server side.\nfunc DefaultServerCodeToLevel(code codes.Code) Level {\n\tswitch code {\n\tcase codes.OK, codes.NotFound, codes.Canceled, codes.AlreadyExists, codes.InvalidArgument, codes.Unauthenticated:\n\t\treturn LevelInfo\n\n\tcase codes.DeadlineExceeded, codes.PermissionDenied, codes.ResourceExhausted, codes.FailedPrecondition, codes.Aborted,\n\t\tcodes.OutOfRange, codes.Unavailable:\n\t\treturn LevelWarn\n\n\tcase codes.Unknown, codes.Unimplemented, codes.Internal, codes.DataLoss:\n\t\treturn LevelError\n\n\tdefault:\n\t\treturn LevelError\n\t}\n}\n\n// DefaultClientCodeToLevel is the helper mapper that maps gRPC return codes to log levels for client side.\nfunc DefaultClientCodeToLevel(code codes.Code) Level {\n\tswitch code {\n\tcase codes.OK, codes.Canceled, codes.InvalidArgument, codes.NotFound, codes.AlreadyExists, codes.ResourceExhausted,\n\t\tcodes.FailedPrecondition, codes.Aborted, codes.OutOfRange:\n\t\treturn LevelDebug\n\tcase codes.Unknown, codes.DeadlineExceeded, codes.PermissionDenied, codes.Unauthenticated:\n\t\treturn LevelInfo\n\tcase codes.Unimplemented, codes.Internal, codes.Unavailable, codes.DataLoss:\n\t\treturn LevelWarn\n\tdefault:\n\t\treturn LevelInfo\n\t}\n}\n\ntype (\n\tfieldsFromCtxFn         func(ctx context.Context) Fields\n\tfieldsFromCtxCallMetaFn func(ctx context.Context, c interceptors.CallMeta) Fields\n)\n\n// WithFieldsFromContext allows overriding existing or adding extra fields to all log messages per given context.\n// If called multiple times, it overwrites the existing FieldsFromContext/WithFieldsFromContextAndCallMeta function.\n// If you need to use multiple FieldsFromContext functions then you should combine them in a wrapper fieldsFromCtxFn.\n// Only one of WithFieldsFromContextAndCallMeta or WithFieldsFromContext should\n// be used, using both will result in the last one overwriting the previous.\nfunc WithFieldsFromContext(f fieldsFromCtxFn) Option {\n\treturn func(o *options) {\n\t\to.fieldsFromCtxCallMetaFn = func(ctx context.Context, _ interceptors.CallMeta) Fields {\n\t\t\treturn f(ctx)\n\t\t}\n\t}\n}\n\n// WithFieldsFromContextAndCallMeta allows overriding existing or adding extra fields to all log messages per given context and interceptor.CallMeta\n// If called multiple times, it overwrites the existing FieldsFromContext/WithFieldsFromContextAndCallMeta function.\n// If you need to use multiple WithFieldsFromContextAndCallMeta functions then you should combine them in a wrapper fieldsFromCtxCallMetaFn.\n// Only one of WithFieldsFromContextAndCallMeta or WithFieldsFromContext should\n// be used, using both will result in the last one overwriting the previous.\nfunc WithFieldsFromContextAndCallMeta(f fieldsFromCtxCallMetaFn) Option {\n\treturn func(o *options) {\n\t\to.fieldsFromCtxCallMetaFn = f\n\t}\n}\n\n// WithLogOnEvents customizes on what events the gRPC interceptor should log on.\nfunc WithLogOnEvents(events ...LoggableEvent) Option {\n\treturn func(o *options) {\n\t\to.loggableEvents = events\n\t}\n}\n\n// WithErrorFields allows to extract logging fields from an error.\nfunc WithErrorFields(f ErrorToFields) Option {\n\treturn func(o *options) {\n\t\to.errorToFieldsFunc = f\n\t}\n}\n\n// WithLevels customizes the function for mapping gRPC return codes and interceptor log level statements.\nfunc WithLevels(f CodeToLevel) Option {\n\treturn func(o *options) {\n\t\to.levelFunc = f\n\t}\n}\n\n// WithCodes customizes the function for mapping errors to error codes.\nfunc WithCodes(f ErrorToCode) Option {\n\treturn func(o *options) {\n\t\to.codeFunc = f\n\t}\n}\n\n// WithDurationField customizes the function for mapping request durations to log fields.\nfunc WithDurationField(f DurationToFields) Option {\n\treturn func(o *options) {\n\t\to.durationFieldFunc = f\n\t}\n}\n\n// DefaultDurationToFields is the default implementation of converting request duration to a field.\nvar DefaultDurationToFields = DurationToTimeMillisFields\n\n// DurationToTimeMillisFields converts the duration to milliseconds and uses the key `grpc.time_ms`.\nfunc DurationToTimeMillisFields(duration time.Duration) Fields {\n\treturn Fields{\"grpc.time_ms\", fmt.Sprintf(\"%v\", durationToMilliseconds(duration))}\n}\n\n// DurationToDurationField uses a Duration field to log the request duration\n// and leaves it up to Log's encoder settings to determine how that is output.\nfunc DurationToDurationField(duration time.Duration) Fields {\n\treturn Fields{\"grpc.duration\", duration.String()}\n}\n\nfunc durationToMilliseconds(duration time.Duration) float32 {\n\treturn float32(duration.Nanoseconds()/1000) / 1000\n}\n\n// WithTimestampFormat customizes the timestamps emitted in the log fields.\nfunc WithTimestampFormat(format string) Option {\n\treturn func(o *options) {\n\t\to.timestampFormat = format\n\t}\n}\n\n// WithDisableLoggingFields disables logging of gRPC fields provided.\n// The following are the default logging fields:\n//   - SystemTag[0]\n//   - ComponentFieldKey\n//   - ServiceFieldKey\n//   - MethodFieldKey\n//   - MethodTypeFieldKey\n//\n// Usage example - WithDisableLoggingFields(logging.MethodFieldKey, logging.MethodTypeFieldKey)\nfunc WithDisableLoggingFields(disableGrpcLogFields ...string) Option {\n\treturn func(o *options) {\n\t\to.disableGrpcLogFields = disableGrpcLogFields\n\t}\n}\n"
  },
  {
    "path": "interceptors/logging/slog.go",
    "content": "// Copyright (c) The go-grpc-middleware Authors.\n// Licensed under the Apache License 2.0.\n\n// Copyright 2022 The Go Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license that can be found in the LICENSE file.\n//\n// Copied from https://cs.opensource.google/go/x/exp/+/10a50721:slog/level.go\n\npackage logging\n\n// A Level is the importance or severity of a log event.\n// The higher the level, the more important or severe the event.\ntype Level int\n\n// Level numbers are inherently arbitrary,\n// but we picked them to satisfy three constraints.\n// Any system can map them to another numbering scheme if it wishes.\n//\n// First, we wanted the default level to be Info, Since Levels are ints, Info is\n// the default value for int, zero.\n//\n\n// Second, we wanted to make it easy to use levels to specify logger verbosity.\n// Since a larger level means a more severe event, a logger that accepts events\n// with smaller (or more negative) level means a more verbose logger. Logger\n// verbosity is thus the negation of event severity, and the default verbosity\n// of 0 accepts all events at least as severe as INFO.\n//\n// Third, we wanted some room between levels to accommodate schemes with named\n// levels between ours. For example, Google Cloud Logging defines a Notice level\n// between Info and Warn. Since there are only a few of these intermediate\n// levels, the gap between the numbers need not be large. Our gap of 4 matches\n// OpenTelemetry's mapping. Subtracting 9 from an OpenTelemetry level in the\n// DEBUG, INFO, WARN and ERROR ranges converts it to the corresponding slog\n// Level range. OpenTelemetry also has the names TRACE and FATAL, which slog\n// does not. But those OpenTelemetry levels can still be represented as slog\n// Levels by using the appropriate integers.\n//\n// Names for common levels.\nconst (\n\tLevelDebug Level = -4\n\tLevelInfo  Level = 0\n\tLevelWarn  Level = 4\n\tLevelError Level = 8\n)\n"
  },
  {
    "path": "interceptors/protovalidate/doc.go",
    "content": "// Copyright (c) The go-grpc-middleware Authors.\n// Licensed under the Apache License 2.0.\n\n/*\nPackage protovalidate is a request validator that uses https://github.com/bufbuild/protovalidate-go under the hood.\n\nIn case of a validation failure, an `InvalidArgument` gRPC status is returned, along with a\ndescription of the validation failure.\n\nIt supports two ways of work:\n\n1. use new annotations that will be caught and processed by `protovalidate-go` package.\n\n2. use legacy mode, annotations will be same as for `protoc-gen-validate` and `Validate()` method will be generated.\n\nExample of a service:\n\n\tsyntax = \"proto3\";\n\tpackage cloud.instance.v1;\n\n\timport \"buf/validate/validate.proto\";\n\timport \"validate/validate.proto\";\n\n\tservice InstanceService {\n\t // GetInstance is an example of request that uses a new constraints\n\t rpc GetInstance(GetInstanceRequest) returns (GetInstanceResponse) {}\n\n\t // Legacy is an example of request that uses protoc-gen-validate constraints\n\t // their support enabled in protovalidate library constructor\n\t rpc Legacy(LegacyRequest) returns (LegacyResponse) {}\n\t}\n\n\tmessage GetInstanceRequest {\n\t string instance_id = 1 [(buf.validate.field).string.uuid = true];\n\t}\n\n\tmessage GetInstanceResponse {}\n\n\tmessage LegacyRequest {\n\t string email = 1 [(validate.rules).string.email = true]; // https://github.com/bufbuild/protoc-gen-validate\n\t}\n\n\tmessage LegacyResponse {}\n\nPlease consult https://github.com/bufbuild/protovalidate for details and other parameters of customization.\n*/\npackage protovalidate\n"
  },
  {
    "path": "interceptors/protovalidate/example_stream_test.go",
    "content": "// Copyright (c) The go-grpc-middleware Authors.\n// Licensed under the Apache License 2.0.\n\npackage protovalidate_test\n\nimport (\n\t\"net\"\n\n\t\"buf.build/go/protovalidate\"\n\tprotovalidate_middleware \"github.com/grpc-ecosystem/go-grpc-middleware/v2/interceptors/protovalidate\"\n\ttestvalidatev1 \"github.com/grpc-ecosystem/go-grpc-middleware/v2/testing/testvalidate/v1\"\n\t\"google.golang.org/grpc\"\n)\n\ntype StreamService struct {\n\ttestvalidatev1.TestValidateServiceServer\n}\n\nfunc (s *StreamService) SendStream(_ *testvalidatev1.SendStreamRequest, _ testvalidatev1.TestValidateService_SendStreamServer) error {\n\treturn nil\n}\n\nfunc ExampleStreamServerInterceptor() {\n\tvalidator, err := protovalidate.New()\n\tif err != nil {\n\t\tpanic(err) // only for example purposes\n\t}\n\n\tvar (\n\t\tsrv = grpc.NewServer(\n\t\t\tgrpc.StreamInterceptor(\n\t\t\t\tprotovalidate_middleware.StreamServerInterceptor(validator,\n\t\t\t\t\tprotovalidate_middleware.WithIgnoreMessages(\n\t\t\t\t\t\t(&testvalidatev1.SendStreamRequest{}).ProtoReflect().Type(),\n\t\t\t\t\t)),\n\t\t\t),\n\t\t)\n\t\tsvc = &StreamService{}\n\t)\n\n\ttestvalidatev1.RegisterTestValidateServiceServer(srv, svc)\n\n\tlistener, err := net.Listen(\"tcp\", \":3000\")\n\tif err != nil {\n\t\tpanic(err) // only for example purposes\n\t}\n\n\tif err = srv.Serve(listener); err != nil {\n\t\tpanic(err) // only for example purposes\n\t}\n}\n"
  },
  {
    "path": "interceptors/protovalidate/example_unary_test.go",
    "content": "// Copyright (c) The go-grpc-middleware Authors.\n// Licensed under the Apache License 2.0.\n\npackage protovalidate_test\n\nimport (\n\t\"context\"\n\t\"net\"\n\n\t\"buf.build/go/protovalidate\"\n\tprotovalidate_middleware \"github.com/grpc-ecosystem/go-grpc-middleware/v2/interceptors/protovalidate\"\n\ttestvalidatev1 \"github.com/grpc-ecosystem/go-grpc-middleware/v2/testing/testvalidate/v1\"\n\t\"google.golang.org/grpc\"\n)\n\ntype UnaryService struct {\n\ttestvalidatev1.TestValidateServiceServer\n}\n\nfunc (s *UnaryService) Send(_ context.Context, _ *testvalidatev1.SendRequest) (*testvalidatev1.SendResponse, error) {\n\treturn &testvalidatev1.SendResponse{}, nil\n}\n\nfunc ExampleUnaryServerInterceptor() {\n\tvalidator, err := protovalidate.New()\n\tif err != nil {\n\t\tpanic(err) // only for example purposes\n\t}\n\n\tvar (\n\t\tsrv = grpc.NewServer(\n\t\t\tgrpc.UnaryInterceptor(\n\t\t\t\tprotovalidate_middleware.UnaryServerInterceptor(validator,\n\t\t\t\t\tprotovalidate_middleware.WithIgnoreMessages(\n\t\t\t\t\t\t(&testvalidatev1.SendRequest{}).ProtoReflect().Type(),\n\t\t\t\t\t),\n\t\t\t\t),\n\t\t\t),\n\t\t)\n\t\tsvc = &UnaryService{}\n\t)\n\n\ttestvalidatev1.RegisterTestValidateServiceServer(srv, svc)\n\n\tlistener, err := net.Listen(\"tcp\", \":3000\")\n\tif err != nil {\n\t\tpanic(err) // only for example purposes\n\t}\n\n\tif err = srv.Serve(listener); err != nil {\n\t\tpanic(err) // only for example purposes\n\t}\n}\n"
  },
  {
    "path": "interceptors/protovalidate/options.go",
    "content": "// Copyright (c) The go-grpc-middleware Authors.\n// Licensed under the Apache License 2.0.\n\n// Copyright 2017 David Ackroyd. All Rights Reserved.\n// See LICENSE for licensing terms.\n\npackage protovalidate\n\nimport (\n\t\"slices\"\n\n\t\"google.golang.org/protobuf/reflect/protoreflect\"\n)\n\ntype options struct {\n\tignoreMessages []protoreflect.FullName\n}\n\n// An Option lets you add options to protovalidate interceptors using With* funcs.\ntype Option func(*options)\n\nfunc evaluateOpts(opts []Option) *options {\n\toptCopy := &options{}\n\tfor _, o := range opts {\n\t\to(optCopy)\n\t}\n\treturn optCopy\n}\n\n// WithIgnoreMessages sets the messages that should be ignored by the\n// validator. Message types are matched using their fully-qualified Protobuf\n// names.\n//\n// Use with caution and ensure validation is performed elsewhere.\nfunc WithIgnoreMessages(msgs ...protoreflect.MessageType) Option {\n\tnames := make([]protoreflect.FullName, 0, len(msgs))\n\tfor _, msg := range msgs {\n\t\tnames = append(names, msg.Descriptor().FullName())\n\t}\n\tslices.Sort(names)\n\treturn func(o *options) {\n\t\to.ignoreMessages = names\n\t}\n}\n\nfunc (o *options) shouldIgnoreMessage(fqn protoreflect.FullName) bool {\n\t// Names are sorted in WithIgnoreMessages, so we can use binary search.\n\t_, found := slices.BinarySearch(o.ignoreMessages, fqn)\n\treturn found\n}\n"
  },
  {
    "path": "interceptors/protovalidate/protovalidate.go",
    "content": "// Copyright (c) The go-grpc-middleware Authors.\n// Licensed under the Apache License 2.0.\n\npackage protovalidate\n\nimport (\n\t\"context\"\n\t\"errors\"\n\n\t\"buf.build/go/protovalidate\"\n\t\"google.golang.org/grpc\"\n\t\"google.golang.org/grpc/codes\"\n\t\"google.golang.org/grpc/status\"\n\t\"google.golang.org/protobuf/proto\"\n)\n\n// UnaryServerInterceptor returns a new unary server interceptor that validates incoming messages.\n// If the request is invalid, clients may access a structured representation of the validation failure as an error detail.\nfunc UnaryServerInterceptor(validator protovalidate.Validator, opts ...Option) grpc.UnaryServerInterceptor {\n\to := evaluateOpts(opts)\n\n\treturn func(\n\t\tctx context.Context,\n\t\treq interface{},\n\t\tinfo *grpc.UnaryServerInfo,\n\t\thandler grpc.UnaryHandler,\n\t) (resp interface{}, err error) {\n\t\tif err := validateMsg(req, validator, o); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\treturn handler(ctx, req)\n\t}\n}\n\n// StreamServerInterceptor returns a new streaming server interceptor that validates incoming messages.\n// If the request is invalid, clients may access a structured representation of the validation failure as an error detail.\nfunc StreamServerInterceptor(validator protovalidate.Validator, opts ...Option) grpc.StreamServerInterceptor {\n\to := evaluateOpts(opts)\n\treturn func(\n\t\tsrv interface{},\n\t\tstream grpc.ServerStream,\n\t\tinfo *grpc.StreamServerInfo,\n\t\thandler grpc.StreamHandler,\n\t) error {\n\t\treturn handler(srv, &wrappedServerStream{\n\t\t\tServerStream: stream,\n\t\t\tvalidator:    validator,\n\t\t\toptions:      o,\n\t\t})\n\t}\n}\n\n// wrappedServerStream is a thin wrapper around grpc.ServerStream that allows modifying context.\ntype wrappedServerStream struct {\n\tgrpc.ServerStream\n\n\tvalidator protovalidate.Validator\n\toptions   *options\n}\n\nfunc (w *wrappedServerStream) RecvMsg(m interface{}) error {\n\tif err := w.ServerStream.RecvMsg(m); err != nil {\n\t\treturn err\n\t}\n\treturn validateMsg(m, w.validator, w.options)\n}\n\nfunc validateMsg(m interface{}, validator protovalidate.Validator, opts *options) error {\n\tmsg, ok := m.(proto.Message)\n\tif !ok {\n\t\treturn status.Errorf(codes.Internal, \"unsupported message type: %T\", m)\n\t}\n\tif opts.shouldIgnoreMessage(msg.ProtoReflect().Descriptor().FullName()) {\n\t\treturn nil\n\t}\n\terr := validator.Validate(msg)\n\tif err == nil {\n\t\treturn nil\n\t}\n\tvar valErr *protovalidate.ValidationError\n\tif errors.As(err, &valErr) {\n\t\t// Message is invalid.\n\t\tst := status.New(codes.InvalidArgument, err.Error())\n\t\tds, detErr := st.WithDetails(valErr.ToProto())\n\t\tif detErr != nil {\n\t\t\treturn st.Err()\n\t\t}\n\t\treturn ds.Err()\n\t}\n\t// CEL expression doesn't compile or type-check.\n\treturn status.Error(codes.Internal, err.Error())\n}\n"
  },
  {
    "path": "interceptors/protovalidate/protovalidate_test.go",
    "content": "// Copyright (c) The go-grpc-middleware Authors.\n// Licensed under the Apache License 2.0.\n\npackage protovalidate_test\n\nimport (\n\t\"context\"\n\t\"log\"\n\t\"net\"\n\t\"testing\"\n\n\t\"buf.build/gen/go/bufbuild/protovalidate/protocolbuffers/go/buf/validate\"\n\t\"buf.build/go/protovalidate\"\n\tprotovalidate_middleware \"github.com/grpc-ecosystem/go-grpc-middleware/v2/interceptors/protovalidate\"\n\t\"github.com/grpc-ecosystem/go-grpc-middleware/v2/testing/testvalidate\"\n\ttestvalidatev1 \"github.com/grpc-ecosystem/go-grpc-middleware/v2/testing/testvalidate/v1\"\n\t\"github.com/stretchr/testify/assert\"\n\t\"github.com/stretchr/testify/require\"\n\t\"google.golang.org/grpc\"\n\t\"google.golang.org/grpc/codes\"\n\t\"google.golang.org/grpc/credentials/insecure\"\n\t\"google.golang.org/grpc/status\"\n\t\"google.golang.org/grpc/test/bufconn\"\n\t\"google.golang.org/protobuf/proto\"\n\t\"google.golang.org/protobuf/reflect/protoreflect\"\n\t\"google.golang.org/protobuf/types/descriptorpb\"\n)\n\nfunc TestUnaryServerInterceptor(t *testing.T) {\n\tvalidator, err := protovalidate.New()\n\trequire.NoError(t, err)\n\n\tinterceptor := protovalidate_middleware.UnaryServerInterceptor(validator)\n\n\thandler := func(ctx context.Context, req any) (any, error) {\n\t\treturn \"good\", nil\n\t}\n\tinfo := &grpc.UnaryServerInfo{FullMethod: \"FakeMethod\"}\n\n\tt.Run(\"valid_email\", func(t *testing.T) {\n\t\tresp, interceptorError := interceptor(context.TODO(), testvalidate.GoodUnaryRequest, info, handler)\n\t\trequire.NoError(t, interceptorError)\n\t\tassert.Equal(t, \"good\", resp)\n\t})\n\n\tt.Run(\"invalid_email\", func(t *testing.T) {\n\t\t_, err = interceptor(context.TODO(), testvalidate.BadUnaryRequest, info, handler)\n\t\tassertEqualViolation(t, &validate.Violation{\n\t\t\tField: &validate.FieldPath{\n\t\t\t\tElements: []*validate.FieldPathElement{\n\t\t\t\t\t{\n\t\t\t\t\t\tFieldNumber: proto.Int32(1),\n\t\t\t\t\t\tFieldName:   proto.String(\"message\"),\n\t\t\t\t\t\tFieldType:   descriptorpb.FieldDescriptorProto_TYPE_STRING.Enum(),\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\tRule: &validate.FieldPath{\n\t\t\t\tElements: []*validate.FieldPathElement{\n\t\t\t\t\t{\n\t\t\t\t\t\tFieldNumber: proto.Int32(14),\n\t\t\t\t\t\tFieldName:   proto.String(\"string\"),\n\t\t\t\t\t\tFieldType:   descriptorpb.FieldDescriptorProto_TYPE_MESSAGE.Enum(),\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tFieldNumber: proto.Int32(12),\n\t\t\t\t\t\tFieldName:   proto.String(\"email\"),\n\t\t\t\t\t\tFieldType:   descriptorpb.FieldDescriptorProto_TYPE_BOOL.Enum(),\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\tRuleId:  proto.String(\"string.email\"),\n\t\t\tMessage: proto.String(\"value must be a valid email address\"),\n\t\t}, err)\n\t})\n\n\tt.Run(\"not_protobuf\", func(t *testing.T) {\n\t\t_, err = interceptor(context.Background(), \"not protobuf\", info, handler)\n\t\trequire.EqualError(t, err, \"rpc error: code = Internal desc = unsupported message type: string\")\n\t\tassert.Equal(t, codes.Internal, status.Code(err))\n\t})\n\n\tinterceptor = protovalidate_middleware.UnaryServerInterceptor(validator,\n\t\tprotovalidate_middleware.WithIgnoreMessages(testvalidate.BadUnaryRequest.ProtoReflect().Type()),\n\t)\n\n\tt.Run(\"invalid_email_ignored\", func(t *testing.T) {\n\t\tresp, err := interceptor(context.TODO(), testvalidate.BadUnaryRequest, info, handler)\n\t\trequire.NoError(t, err)\n\t\tassert.Equal(t, \"good\", resp)\n\t})\n}\n\ntype server struct {\n\ttestvalidatev1.UnimplementedTestValidateServiceServer\n\n\tcalled *bool\n}\n\nfunc (g *server) SendStream(\n\t_ *testvalidatev1.SendStreamRequest,\n\tstream testvalidatev1.TestValidateService_SendStreamServer,\n) error {\n\t*g.called = true\n\tif err := stream.Send(&testvalidatev1.SendStreamResponse{}); err != nil {\n\t\treturn err\n\t}\n\n\treturn nil\n}\n\nconst bufSize = 1024 * 1024\n\nfunc startGrpcServer(t *testing.T, called *bool, ignoreMessages ...protoreflect.MessageType) *grpc.ClientConn {\n\tlis := bufconn.Listen(bufSize)\n\n\tvalidator, err := protovalidate.New()\n\trequire.NoError(t, err)\n\n\ts := grpc.NewServer(\n\t\tgrpc.StreamInterceptor(\n\t\t\tprotovalidate_middleware.StreamServerInterceptor(validator,\n\t\t\t\tprotovalidate_middleware.WithIgnoreMessages(ignoreMessages...),\n\t\t\t),\n\t\t),\n\t)\n\ttestvalidatev1.RegisterTestValidateServiceServer(s, &server{called: called})\n\tgo func() {\n\t\tif err = s.Serve(lis); err != nil {\n\t\t\tlog.Fatalf(\"Server exited with error: %v\", err)\n\t\t}\n\t}()\n\n\tdialer := func(context.Context, string) (net.Conn, error) {\n\t\treturn lis.Dial()\n\t}\n\n\tconn, err := grpc.NewClient(\n\t\t\"passthrough:///bufnet\",\n\t\tgrpc.WithContextDialer(dialer),\n\t\tgrpc.WithTransportCredentials(insecure.NewCredentials()),\n\t)\n\tif err != nil {\n\t\tt.Fatalf(\"Failed to dial bufnet: %v\", err)\n\t}\n\n\tt.Cleanup(func() {\n\t\t_ = conn.Close()\n\t\ts.GracefulStop()\n\t\t_ = lis.Close()\n\t})\n\n\treturn conn\n}\n\nfunc TestStreamServerInterceptor(t *testing.T) {\n\tt.Run(\"valid_email\", func(t *testing.T) {\n\t\tcalled := proto.Bool(false)\n\t\tclient := testvalidatev1.NewTestValidateServiceClient(\n\t\t\tstartGrpcServer(t, called),\n\t\t)\n\n\t\tout, err := client.SendStream(context.Background(), testvalidate.GoodStreamRequest)\n\t\trequire.NoError(t, err, \"SendStream failed: %v\", err)\n\n\t\t_, err = out.Recv()\n\t\tt.Log(err)\n\t\trequire.NoError(t, err)\n\t\tassert.True(t, *called)\n\t})\n\n\tt.Run(\"invalid_email\", func(t *testing.T) {\n\t\tcalled := proto.Bool(false)\n\t\tclient := testvalidatev1.NewTestValidateServiceClient(\n\t\t\tstartGrpcServer(t, called),\n\t\t)\n\n\t\tout, err := client.SendStream(context.Background(), testvalidate.BadStreamRequest)\n\t\trequire.NoError(t, err, \"SendStream failed: %v\", err)\n\n\t\t_, err = out.Recv()\n\t\tassertEqualViolation(t, &validate.Violation{\n\t\t\tField: &validate.FieldPath{\n\t\t\t\tElements: []*validate.FieldPathElement{\n\t\t\t\t\t{\n\t\t\t\t\t\tFieldNumber: proto.Int32(1),\n\t\t\t\t\t\tFieldName:   proto.String(\"message\"),\n\t\t\t\t\t\tFieldType:   descriptorpb.FieldDescriptorProto_TYPE_STRING.Enum(),\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\tRule: &validate.FieldPath{\n\t\t\t\tElements: []*validate.FieldPathElement{\n\t\t\t\t\t{\n\t\t\t\t\t\tFieldNumber: proto.Int32(14),\n\t\t\t\t\t\tFieldName:   proto.String(\"string\"),\n\t\t\t\t\t\tFieldType:   descriptorpb.FieldDescriptorProto_TYPE_MESSAGE.Enum(),\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tFieldNumber: proto.Int32(12),\n\t\t\t\t\t\tFieldName:   proto.String(\"email\"),\n\t\t\t\t\t\tFieldType:   descriptorpb.FieldDescriptorProto_TYPE_BOOL.Enum(),\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\tRuleId:  proto.String(\"string.email\"),\n\t\t\tMessage: proto.String(\"value must be a valid email address\"),\n\t\t}, err)\n\t\tassert.False(t, *called)\n\t})\n\n\tt.Run(\"invalid_email_ignored\", func(t *testing.T) {\n\t\tcalled := proto.Bool(false)\n\t\tclient := testvalidatev1.NewTestValidateServiceClient(\n\t\t\tstartGrpcServer(t, called, testvalidate.BadStreamRequest.ProtoReflect().Type()),\n\t\t)\n\n\t\tout, err := client.SendStream(context.Background(), testvalidate.BadStreamRequest)\n\t\trequire.NoError(t, err, \"SendStream failed: %v\", err)\n\n\t\t_, err = out.Recv()\n\t\trequire.NoError(t, err)\n\t\tassert.True(t, *called)\n\t})\n}\n\nfunc assertEqualViolation(tb testing.TB, want *validate.Violation, got error) bool {\n\trequire.Error(tb, got)\n\tst := status.Convert(got)\n\tassert.Equal(tb, codes.InvalidArgument, st.Code())\n\tdetails := st.Proto().GetDetails()\n\trequire.Len(tb, details, 1)\n\tgotpb, unwrapErr := details[0].UnmarshalNew()\n\trequire.NoError(tb, unwrapErr)\n\tviolations := &validate.Violations{\n\t\tViolations: []*validate.Violation{want},\n\t}\n\ttb.Logf(\"got: %v\", gotpb)\n\ttb.Logf(\"want: %v\", violations)\n\treturn assert.True(tb, proto.Equal(gotpb, violations))\n}\n"
  },
  {
    "path": "interceptors/ratelimit/doc.go",
    "content": "// Copyright (c) The go-grpc-middleware Authors.\n// Licensed under the Apache License 2.0.\n\n/*\nPackage ratelimit is a middleware that limits the rate of requests.\n\n`ratelimit` a generic server-side ratelimit middleware for gRPC.\n\n# Server Side Ratelimit Middleware\n\nIt allows to do grpc rate limit by your own rate limiter (e.g. token bucket, leaky bucket, etc.)\n\nPlease see examples for simple examples of use.\n*/\npackage ratelimit\n"
  },
  {
    "path": "interceptors/ratelimit/examples_test.go",
    "content": "// Copyright (c) The go-grpc-middleware Authors.\n// Licensed under the Apache License 2.0.\n\npackage ratelimit_test\n\nimport (\n\t\"context\"\n\n\t\"github.com/grpc-ecosystem/go-grpc-middleware/v2/interceptors/ratelimit\"\n\t\"google.golang.org/grpc\"\n)\n\n// alwaysPassLimiter is an example limiter which implements Limiter interface.\n// It does not limit any request because Limit function always returns false.\ntype alwaysPassLimiter struct{}\n\nfunc (*alwaysPassLimiter) Limit(_ context.Context) error {\n\t// Example rate limiter could be implemented using e.g. github.com/juju/ratelimit\n\t//\t// Take one token per request. This call doesn't block.\n\t//\ttokenRes := l.tokenBucket.TakeAvailable(1)\n\t//\n\t//\t// When rate limit reached, return specific error for the clients.\n\t//\tif tokenRes == 0 {\n\t//\t\treturn fmt.Errorf(\"APP-XXX: reached Rate-Limiting %d\", l.tokenBucket.Available())\n\t//\t}\n\t//\n\t//\t// Rate limit isn't reached.\n\t//\treturn nil\n\t// }\n\treturn nil\n}\n\n// Simple example of a unary server initialization code.\nfunc ExampleUnaryServerInterceptor() {\n\t// Create unary/stream rateLimiters, based on token bucket here.\n\t// You can implement your own rate-limiter for the interface.\n\tlimiter := &alwaysPassLimiter{}\n\t_ = grpc.NewServer(\n\t\tgrpc.ChainUnaryInterceptor(\n\t\t\tratelimit.UnaryServerInterceptor(limiter),\n\t\t),\n\t)\n}\n\n// Simple example of a streaming server initialization code.\nfunc ExampleStreamServerInterceptor() {\n\t// Create unary/stream rateLimiters, based on token bucket here.\n\t// You can implement your own rate-limiter for the interface.\n\tlimiter := &alwaysPassLimiter{}\n\t_ = grpc.NewServer(\n\t\tgrpc.ChainStreamInterceptor(\n\t\t\tratelimit.StreamServerInterceptor(limiter),\n\t\t),\n\t)\n}\n\n// Simple example of a unary client initialization code.\nfunc ExampleUnaryClientInterceptor() {\n\t// Create stream rateLimiter, based on token bucket here.\n\t// You can implement your own rate-limiter for the interface.\n\tlimiter := &alwaysPassLimiter{}\n\t_, _ = grpc.NewClient(\n\t\t\":8080\",\n\t\tgrpc.WithUnaryInterceptor(\n\t\t\tratelimit.UnaryClientInterceptor(limiter),\n\t\t),\n\t)\n}\n\n// Simple example of a streaming client initialization code.\nfunc ExampleStreamClientInterceptor() {\n\t// Create stream rateLimiter, based on token bucket here.\n\t// You can implement your own rate-limiter for the interface.\n\tlimiter := &alwaysPassLimiter{}\n\t_, _ = grpc.NewClient(\n\t\t\":8080\",\n\t\tgrpc.WithChainStreamInterceptor(\n\t\t\tratelimit.StreamClientInterceptor(limiter),\n\t\t),\n\t)\n}\n"
  },
  {
    "path": "interceptors/ratelimit/ratelimit.go",
    "content": "// Copyright (c) The go-grpc-middleware Authors.\n// Licensed under the Apache License 2.0.\n\npackage ratelimit\n\nimport (\n\t\"context\"\n\n\t\"google.golang.org/grpc\"\n\t\"google.golang.org/grpc/codes\"\n\t\"google.golang.org/grpc/status\"\n)\n\n// Limiter defines the interface to perform request rate limiting.\n// If Limit function returns an error, the request will be rejected with the gRPC codes.ResourceExhausted and the provided error.\n// Otherwise, the request will pass.\ntype Limiter interface {\n\tLimit(ctx context.Context) error\n}\n\n// UnaryServerInterceptor returns a new unary server interceptors that performs request rate limiting.\nfunc UnaryServerInterceptor(limiter Limiter) grpc.UnaryServerInterceptor {\n\treturn func(ctx context.Context, req any, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (any, error) {\n\t\tif err := limiter.Limit(ctx); err != nil {\n\t\t\treturn nil, status.Errorf(codes.ResourceExhausted, \"%s is rejected by grpc_ratelimit middleware, please retry later. %s\", info.FullMethod, err)\n\t\t}\n\t\treturn handler(ctx, req)\n\t}\n}\n\n// StreamServerInterceptor returns a new stream server interceptor that performs rate limiting on the request.\nfunc StreamServerInterceptor(limiter Limiter) grpc.StreamServerInterceptor {\n\treturn func(srv any, stream grpc.ServerStream, info *grpc.StreamServerInfo, handler grpc.StreamHandler) error {\n\t\tif err := limiter.Limit(stream.Context()); err != nil {\n\t\t\treturn status.Errorf(codes.ResourceExhausted, \"%s is rejected by grpc_ratelimit middleware, please retry later. %s\", info.FullMethod, err)\n\t\t}\n\t\treturn handler(srv, stream)\n\t}\n}\n\n// UnaryClientInterceptor returns a new unary client interceptor that performs rate limiting on the request on the\n// client side.\n// This can be helpful for clients that want to limit the number of requests they send in a given time, potentially\n// saving cost.\nfunc UnaryClientInterceptor(limiter Limiter) grpc.UnaryClientInterceptor {\n\treturn func(ctx context.Context, method string, req, reply interface{}, cc *grpc.ClientConn,\n\t\tinvoker grpc.UnaryInvoker, opts ...grpc.CallOption,\n\t) error {\n\t\tif err := limiter.Limit(ctx); err != nil {\n\t\t\treturn status.Errorf(codes.ResourceExhausted, \"%s is rejected by grpc_ratelimit middleware, please retry later. %s\", method, err)\n\t\t}\n\t\treturn invoker(ctx, method, req, reply, cc, opts...)\n\t}\n}\n\n// StreamClientInterceptor returns a new stream client interceptor that performs rate limiting on the request on the\n// client side.\n// This can be helpful for clients that want to limit the number of requests they send in a given time, potentially\n// saving cost.\nfunc StreamClientInterceptor(limiter Limiter) grpc.StreamClientInterceptor {\n\treturn func(ctx context.Context, desc *grpc.StreamDesc, cc *grpc.ClientConn, method string, streamer grpc.Streamer, opts ...grpc.CallOption) (grpc.ClientStream, error) {\n\t\tif err := limiter.Limit(ctx); err != nil {\n\t\t\treturn nil, status.Errorf(codes.ResourceExhausted, \"%s is rejected by grpc_ratelimit middleware, please retry later. %s\", method, err)\n\t\t}\n\t\treturn streamer(ctx, desc, cc, method, opts...)\n\t}\n}\n"
  },
  {
    "path": "interceptors/ratelimit/ratelimit_test.go",
    "content": "// Copyright (c) The go-grpc-middleware Authors.\n// Licensed under the Apache License 2.0.\n\npackage ratelimit\n\nimport (\n\t\"context\"\n\t\"errors\"\n\t\"testing\"\n\n\t\"github.com/stretchr/testify/assert\"\n\t\"github.com/stretchr/testify/require\"\n\t\"google.golang.org/grpc\"\n\t\"google.golang.org/grpc/codes\"\n\t\"google.golang.org/grpc/status\"\n)\n\nconst errMsgFake = \"fake error\"\n\ntype ctxKey string\n\nvar ctxKeyShouldLimit = ctxKey(\"shouldLimit\")\n\ntype mockGRPCServerStream struct {\n\tgrpc.ServerStream\n\n\tctx context.Context\n}\n\nfunc (m *mockGRPCServerStream) Context() context.Context {\n\treturn m.ctx\n}\n\ntype mockContextBasedLimiter struct{}\n\nfunc (*mockContextBasedLimiter) Limit(ctx context.Context) error {\n\tshouldLimit, _ := ctx.Value(ctxKeyShouldLimit).(bool)\n\n\tif shouldLimit {\n\t\treturn errors.New(\"rate limit exceeded\")\n\t}\n\n\treturn nil\n}\n\nfunc TestUnaryServerInterceptor_RateLimitPass(t *testing.T) {\n\tlimiter := new(mockContextBasedLimiter)\n\tctx := context.WithValue(context.Background(), ctxKeyShouldLimit, false)\n\n\tinterceptor := UnaryServerInterceptor(limiter)\n\thandler := func(ctx context.Context, req any) (any, error) {\n\t\treturn nil, errors.New(errMsgFake)\n\t}\n\tinfo := &grpc.UnaryServerInfo{\n\t\tFullMethod: \"FakeMethod\",\n\t}\n\tresp, err := interceptor(ctx, nil, info, handler)\n\tassert.Nil(t, resp)\n\tassert.EqualError(t, err, errMsgFake)\n}\n\nfunc TestStreamServerInterceptor_RateLimitPass(t *testing.T) {\n\tlimiter := new(mockContextBasedLimiter)\n\tctx := context.WithValue(context.Background(), ctxKeyShouldLimit, false)\n\n\tinterceptor := StreamServerInterceptor(limiter)\n\thandler := func(srv any, stream grpc.ServerStream) error {\n\t\treturn errors.New(errMsgFake)\n\t}\n\tinfo := &grpc.StreamServerInfo{\n\t\tFullMethod: \"FakeMethod\",\n\t}\n\terr := interceptor(nil, &mockGRPCServerStream{ctx: ctx}, info, handler)\n\tassert.EqualError(t, err, errMsgFake)\n}\n\nfunc TestUnaryServerInterceptor_RateLimitFail(t *testing.T) {\n\tlimiter := new(mockContextBasedLimiter)\n\tctx := context.WithValue(context.Background(), ctxKeyShouldLimit, true)\n\n\tinterceptor := UnaryServerInterceptor(limiter)\n\tcalled := false\n\thandler := func(ctx context.Context, req any) (any, error) {\n\t\tcalled = true\n\t\treturn nil, errors.New(errMsgFake)\n\t}\n\tinfo := &grpc.UnaryServerInfo{\n\t\tFullMethod: \"FakeMethod\",\n\t}\n\tresp, err := interceptor(ctx, nil, info, handler)\n\texpErr := status.Errorf(\n\t\tcodes.ResourceExhausted,\n\t\t\"%s is rejected by grpc_ratelimit middleware, please retry later. %s\",\n\t\tinfo.FullMethod,\n\t\t\"rate limit exceeded\",\n\t)\n\tassert.Nil(t, resp)\n\trequire.EqualError(t, err, expErr.Error())\n\tassert.False(t, called)\n}\n\nfunc TestStreamServerInterceptor_RateLimitFail(t *testing.T) {\n\tlimiter := new(mockContextBasedLimiter)\n\tctx := context.WithValue(context.Background(), ctxKeyShouldLimit, true)\n\n\tinterceptor := StreamServerInterceptor(limiter)\n\tcalled := false\n\thandler := func(srv any, stream grpc.ServerStream) error {\n\t\tcalled = true\n\t\treturn errors.New(errMsgFake)\n\t}\n\tinfo := &grpc.StreamServerInfo{\n\t\tFullMethod: \"FakeMethod\",\n\t}\n\terr := interceptor(nil, &mockGRPCServerStream{ctx: ctx}, info, handler)\n\texpErr := status.Errorf(\n\t\tcodes.ResourceExhausted,\n\t\t\"%s is rejected by grpc_ratelimit middleware, please retry later. %s\",\n\t\tinfo.FullMethod,\n\t\t\"rate limit exceeded\",\n\t)\n\n\trequire.EqualError(t, err, expErr.Error())\n\tassert.False(t, called)\n}\n\nfunc TestUnaryClientInterceptor_RateLimitPass(t *testing.T) {\n\tlimiter := new(mockContextBasedLimiter)\n\tctx := context.WithValue(context.Background(), ctxKeyShouldLimit, false)\n\n\tinterceptor := UnaryClientInterceptor(limiter)\n\tinvoker := func(ctx context.Context, method string, req, reply any, cc *grpc.ClientConn, opts ...grpc.CallOption) error {\n\t\treturn errors.New(errMsgFake)\n\t}\n\terr := interceptor(ctx, \"FakeMethod\", nil, nil, nil, invoker)\n\tassert.EqualError(t, err, errMsgFake)\n}\n\nfunc TestStreamClientInterceptor_RateLimitPass(t *testing.T) {\n\tlimiter := new(mockContextBasedLimiter)\n\tctx := context.WithValue(context.Background(), ctxKeyShouldLimit, false)\n\n\tinterceptor := StreamClientInterceptor(limiter)\n\tinvoker := func(ctx context.Context, desc *grpc.StreamDesc, cc *grpc.ClientConn, method string, opts ...grpc.CallOption) (grpc.ClientStream, error) {\n\t\treturn nil, errors.New(errMsgFake)\n\t}\n\t_, err := interceptor(ctx, nil, nil, \"FakeMethod\", invoker)\n\tassert.EqualError(t, err, errMsgFake)\n}\n\nfunc TestUnaryClientInterceptor_RateLimitFail(t *testing.T) {\n\tlimiter := new(mockContextBasedLimiter)\n\tctx := context.WithValue(context.Background(), ctxKeyShouldLimit, true)\n\n\tinterceptor := UnaryClientInterceptor(limiter)\n\tcalled := false\n\tinvoker := func(ctx context.Context, method string, req, reply any, cc *grpc.ClientConn, opts ...grpc.CallOption) error {\n\t\tcalled = true\n\t\treturn errors.New(errMsgFake)\n\t}\n\terr := interceptor(ctx, \"FakeMethod\", nil, nil, nil, invoker)\n\texpErr := status.Errorf(\n\t\tcodes.ResourceExhausted,\n\t\t\"%s is rejected by grpc_ratelimit middleware, please retry later. %s\",\n\t\t\"FakeMethod\",\n\t\t\"rate limit exceeded\",\n\t)\n\trequire.EqualError(t, err, expErr.Error())\n\tassert.False(t, called)\n}\n\nfunc TestStreamClientInterceptor_RateLimitFail(t *testing.T) {\n\tlimiter := new(mockContextBasedLimiter)\n\tctx := context.WithValue(context.Background(), ctxKeyShouldLimit, true)\n\n\tinterceptor := StreamClientInterceptor(limiter)\n\tcalled := false\n\tinvoker := func(ctx context.Context, desc *grpc.StreamDesc, cc *grpc.ClientConn, method string, opts ...grpc.CallOption) (grpc.ClientStream, error) {\n\t\tcalled = true\n\t\treturn nil, errors.New(errMsgFake)\n\t}\n\t_, err := interceptor(ctx, nil, nil, \"FakeMethod\", invoker)\n\texpErr := status.Errorf(\n\t\tcodes.ResourceExhausted,\n\t\t\"%s is rejected by grpc_ratelimit middleware, please retry later. %s\",\n\t\t\"FakeMethod\",\n\t\t\"rate limit exceeded\",\n\t)\n\trequire.EqualError(t, err, expErr.Error())\n\tassert.False(t, called)\n}\n"
  },
  {
    "path": "interceptors/realip/doc.go",
    "content": "// Copyright (c) The go-grpc-middleware Authors.\n// Licensed under the Apache License 2.0.\n\n/*\nPackage realip is a middleware that extracts the real IP of requests based on\nheader values.\n\nThe real IP is subsequently placed inside the context of each request and can\nbe retrieved using the [FromContext] function.\n\nThe middleware is designed to work with gRPC servers serving clients over\nTCP/IP connections. If no headers are found, the middleware will return the\nremote peer address as the real IP. If remote peer address is not a TCP/IP\naddress, the middleware will return nil as the real IP.\n\nHeaders provided by clients in the request will be searched for in the order\nof the list provided to the middleware. The first header that contains a valid\nIP address will be used as the real IP.\n\nComma separated headers are supported. The last, rightmost, IP address in the\nheader will be used as the real IP.\n\n# Security\n\nThere are 2 main security concerns when deriving the real IP from request\nheaders:\n\n 1. Risk of spoofing the real IP by setting a header value.\n 2. Risk of injecting a header value that causes a denial of service.\n\nTo mitigate the risk of spoofing, the middleware introduces the concept of\n\"trusted peers\". Trusted peers are defined as a list of IP networks that are\nverified by the gRPC server operator to be trusted. If the peer address is found\nto be within one of the trusted networks, the middleware will attempt to extract\nthe real IP from the request headers. If the peer address is not found to be\nwithin one of the trusted networks, the peer address will be returned as the\nreal IP.\n\n\"trusted peer\" in this context means that the peer is configured to overwrite the\nheader value with the real IP. This is typically done by a proxy or load\nbalancer that is configured to forward the real IP of the client in a header\nvalue. Alternatively, the peer may be configured to append the real IP to the\nheader value. In this case, the middleware will use the last, rightmost, IP\naddress in the header as the real IP. Most load balancers, such as NGINX, AWS\nELB, are configured to append the real IP to the header value as their default action.\nHowever, Google Cloud Load Balancer for `X-Forwarded-For` follows the pattern:\n`<client-ip>,<load-balancer-ip>`. Hence we need to have an ability to exact the\nreal ip from the header ignoring the LB/proxy IPs.\n\n### Supported Methods for Extracting Real IP:\n\nThis is based on\n[Selecting an IP address](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Forwarded-For#selecting_an_ip_address).\n\n 1. Trusted Proxy Count\n\nWith this method, the count of reverse proxies between the internet and the server is configured.\nThe middleware searches the `X-Forwarded-For` IP list from the rightmost by that count.\n\n 2. Trusted Proxy List\n\nAlternatively, you can configure a list of trusted reverse proxies by specifying their\nIPs or IP ranges. The middleware will then search the `X-Forwarded-For` IP list from\nthe rightmost, skipping all addresses that are on the trusted proxy list.\nThe first non-matching address is considered the target address.\n\n# Individual IP addresses as trusted peers\n\nWhen creating the list of trusted peers, it is possible to specify individual IP\naddresses. This is useful when your proxy or load balancer has a set of\nwell-known addresses.\n\nThe following example shows how to specify individual IP addresses as trusted\npeers:\n\n\ttrusted := []net.IPNet{\n\t    {IP: net.IPv4(192, 168, 0, 1), Mask: net.IPv4Mask(255, 255, 255, 255)},\n\t    {IP: net.IPv4(192, 168, 0, 2), Mask: net.IPv4Mask(255, 255, 255, 255)},\n\t}\n\nIn the above example, the middleware will only attempt to extract the real IP\nfrom the request headers if the peer address is either 192.168.0.1 or\n192.168.0.2.\n\n# Headers\n\nHeaders to search for are specified as a list of strings when creating the\nmiddleware. The middleware will search for the headers in the order specified\nand use the first header that contains a valid IP address as the real IP.\n\nThe following are examples of headers that may contain the real IP:\n\n  - X-Forwarded-For: This header is set by proxies and contains a comma\n    separated list of IP addresses. Each proxy that forwards the request will\n    append the real IP to the header value.\n  - X-Real-IP: This header is set by NGINX and contains the real IP as a string\n    containing a single IP address.\n  - Forwarded-For: Header defined by RFC7239. This header is set by proxies and\n    contains the real IP as a string containing a single IP address. Please note\n    that the obfuscated identifier from section 6.3 of RFC7239, and that the\n    unknown identifier from section 6.2 of RFC7239 are not supported.\n  - True-Client-IP: This header is set by Cloudflare and contains the real IP\n    as a string containing a single IP address.\n\n# Usage\n\nPlease see examples for simple examples of use.\n*/\npackage realip\n"
  },
  {
    "path": "interceptors/realip/examples_test.go",
    "content": "// Copyright (c) The go-grpc-middleware Authors.\n// Licensed under the Apache License 2.0.\n\npackage realip_test\n\nimport (\n\t\"net/netip\"\n\n\t\"github.com/grpc-ecosystem/go-grpc-middleware/v2/interceptors/realip\"\n\t\"google.golang.org/grpc\"\n)\n\n// Simple example of a unary server initialization code.\nfunc ExampleUnaryServerInterceptorOpts() {\n\t// Define list of trusted peers from which we accept forwarded-for and\n\t// real-ip headers.\n\ttrustedPeers := []netip.Prefix{\n\t\tnetip.MustParsePrefix(\"127.0.0.1/32\"),\n\t}\n\t// Define headers to look for in the incoming request.\n\theaders := []string{realip.XForwardedFor, realip.XRealIp}\n\t// Consider that there is one proxy in front,\n\t// so the real client ip will be rightmost - 1 in the csv list of X-Forwarded-For\n\t// Optionally you can specify TrustedProxies\n\topts := []realip.Option{\n\t\trealip.WithTrustedPeers(trustedPeers),\n\t\trealip.WithHeaders(headers),\n\t\trealip.WithTrustedProxiesCount(1),\n\t}\n\t_ = grpc.NewServer(\n\t\tgrpc.ChainUnaryInterceptor(\n\t\t\trealip.UnaryServerInterceptorOpts(opts...),\n\t\t),\n\t)\n}\n\n// Simple example of a streaming server initialization code.\nfunc ExampleStreamServerInterceptorOpts() {\n\t// Define list of trusted peers from which we accept forwarded-for and\n\t// real-ip headers.\n\ttrustedPeers := []netip.Prefix{\n\t\tnetip.MustParsePrefix(\"127.0.0.1/32\"),\n\t}\n\t// Define headers to look for in the incoming request.\n\theaders := []string{realip.XForwardedFor, realip.XRealIp}\n\t// Consider that there is one proxy in front,\n\t// so the real client ip will be rightmost - 1 in the csv list of X-Forwarded-For\n\t// Optionally you can specify TrustedProxies\n\topts := []realip.Option{\n\t\trealip.WithTrustedPeers(trustedPeers),\n\t\trealip.WithHeaders(headers),\n\t\trealip.WithTrustedProxiesCount(1),\n\t}\n\t_ = grpc.NewServer(\n\t\tgrpc.ChainStreamInterceptor(\n\t\t\trealip.StreamServerInterceptorOpts(opts...),\n\t\t),\n\t)\n}\n"
  },
  {
    "path": "interceptors/realip/options.go",
    "content": "// Copyright (c) The go-grpc-middleware Authors.\n// Licensed under the Apache License 2.0.\n\npackage realip\n\nimport \"net/netip\"\n\n// options represents the configuration options for the realip middleware.\ntype options struct {\n\t// trustedPeers is a list of trusted peers network prefixes.\n\ttrustedPeers []netip.Prefix\n\t// trustedProxies is a list of trusted proxies network prefixes.\n\t// The first rightmost non-matching IP when going through X-Forwarded-For is considered the client IP.\n\ttrustedProxies []netip.Prefix\n\t// trustedProxiesCount specifies the number of proxies in front that may append X-Forwarded-For.\n\t// It defaults to 0.\n\ttrustedProxiesCount uint\n\t// headers specifies the headers to use in real IP extraction when the request is from a trusted peer.\n\theaders []string\n}\n\n// An Option lets you add options to realip interceptors using With* functions.\ntype Option func(*options)\n\nfunc evaluateOpts(opts []Option) *options {\n\toptCopy := &options{}\n\tfor _, o := range opts {\n\t\to(optCopy)\n\t}\n\treturn optCopy\n}\n\n// WithTrustedPeers sets the trusted peers network prefixes.\nfunc WithTrustedPeers(peers []netip.Prefix) Option {\n\treturn func(o *options) {\n\t\to.trustedPeers = peers\n\t}\n}\n\n// WithTrustedProxies sets the trusted proxies network prefixes.\nfunc WithTrustedProxies(proxies []netip.Prefix) Option {\n\treturn func(o *options) {\n\t\to.trustedProxies = proxies\n\t}\n}\n\n// WithTrustedProxiesCount sets the number of trusted proxies that may append X-Forwarded-For.\nfunc WithTrustedProxiesCount(count uint) Option {\n\treturn func(o *options) {\n\t\to.trustedProxiesCount = count\n\t}\n}\n\n// WithHeaders sets the headers to use in real IP extraction for requests from trusted peers.\nfunc WithHeaders(headers []string) Option {\n\treturn func(o *options) {\n\t\to.headers = headers\n\t}\n}\n"
  },
  {
    "path": "interceptors/realip/realip.go",
    "content": "// Copyright (c) The go-grpc-middleware Authors.\n// Licensed under the Apache License 2.0.\n\npackage realip\n\nimport (\n\t\"context\"\n\t\"net\"\n\t\"net/netip\"\n\t\"strings\"\n\n\t\"google.golang.org/grpc\"\n\t\"google.golang.org/grpc/metadata\"\n\t\"google.golang.org/grpc/peer\"\n)\n\n// XRealIp, XForwardedFor and TrueClientIp are header keys\n// used to extract the real client IP from the request. They represent common\n// conventions for identifying the originating IP address of a client connecting\n// through proxies or load balancers.\nconst (\n\tXRealIp       = \"X-Real-IP\"\n\tXForwardedFor = \"X-Forwarded-For\"\n\tTrueClientIp  = \"True-Client-IP\"\n)\n\nvar noIP = netip.Addr{}\n\ntype realipKey struct{}\n\n// FromContext extracts the real client IP from the context.\n// It returns the IP and a boolean indicating if it was present.\nfunc FromContext(ctx context.Context) (netip.Addr, bool) {\n\tip, ok := ctx.Value(realipKey{}).(netip.Addr)\n\treturn ip, ok\n}\n\nfunc remotePeer(ctx context.Context) net.Addr {\n\tpr, ok := peer.FromContext(ctx)\n\tif !ok {\n\t\treturn nil\n\t}\n\treturn pr.Addr\n}\n\nfunc ipInNets(ip netip.Addr, nets []netip.Prefix) bool {\n\tfor _, n := range nets {\n\t\tif n.Contains(ip) {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n\nfunc getHeader(ctx context.Context, key string) string {\n\tvals := metadata.ValueFromIncomingContext(ctx, key)\n\n\tif len(vals) == 0 {\n\t\treturn \"\"\n\t}\n\n\treturn vals[0]\n}\n\nfunc ipFromXForwardedFoR(trustedProxies []netip.Prefix, ips []string, idx int) netip.Addr {\n\tfor i := idx; i >= 0; i-- {\n\t\th := strings.TrimSpace(ips[i])\n\t\tip, err := netip.ParseAddr(h)\n\t\tif err != nil {\n\t\t\treturn noIP\n\t\t}\n\t\tif !ipInNets(ip, trustedProxies) {\n\t\t\treturn ip\n\t\t}\n\t}\n\treturn noIP\n}\n\nfunc ipFromHeaders(ctx context.Context, headers []string, trustedProxies []netip.Prefix, trustedProxyCnt uint) netip.Addr {\n\tfor _, header := range headers {\n\t\ta := strings.Split(getHeader(ctx, header), \",\")\n\t\tidx := len(a) - 1\n\t\tif header == XForwardedFor {\n\t\t\tidx -= int(trustedProxyCnt)\n\t\t\tif idx < 0 {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\treturn ipFromXForwardedFoR(trustedProxies, a, idx)\n\t\t}\n\t\th := strings.TrimSpace(a[idx])\n\t\tip, err := netip.ParseAddr(h)\n\t\tif err == nil {\n\t\t\treturn ip\n\t\t}\n\t}\n\treturn noIP\n}\n\nfunc getRemoteIP(ctx context.Context, trustedPeers, trustedProxies []netip.Prefix, headers []string, proxyCnt uint) netip.Addr {\n\tpr := remotePeer(ctx)\n\tif pr == nil {\n\t\treturn noIP\n\t}\n\n\taddrPort, err := netip.ParseAddrPort(pr.String())\n\tif err != nil {\n\t\treturn noIP\n\t}\n\tip := addrPort.Addr()\n\n\tif len(trustedPeers) == 0 || !ipInNets(ip, trustedPeers) {\n\t\treturn ip\n\t}\n\tif resolvedIP := ipFromHeaders(ctx, headers, trustedProxies, proxyCnt); resolvedIP != noIP {\n\t\treturn resolvedIP\n\t}\n\t// No ip from the headers, return the peer ip.\n\treturn ip\n}\n\ntype serverStream struct {\n\tgrpc.ServerStream\n\tctx context.Context\n}\n\nfunc (s *serverStream) Context() context.Context {\n\treturn s.ctx\n}\n\n// UnaryServerInterceptor returns a new unary server interceptor that extracts the real client IP from request headers.\n// It checks if the request comes from a trusted peer, and if so, extracts the IP from the configured headers.\n// The real IP is added to the request context.\n// See UnaryServerInterceptorOpts as it allows to configure trusted proxy ips list and count that should work better with Google LB\nfunc UnaryServerInterceptor(trustedPeers []netip.Prefix, headers []string) grpc.UnaryServerInterceptor {\n\treturn UnaryServerInterceptorOpts(WithTrustedPeers(trustedPeers), WithHeaders(headers))\n}\n\n// StreamServerInterceptor returns a new stream server interceptor that extracts the real client IP from request headers.\n// It checks if the request comes from a trusted peer, and if so, extracts the IP from the configured headers.\n// The real IP is added to the request context.\n// See UnaryServerInterceptorOpts as it allows to configure trusted proxy ips list and count that should work better with Google LB\nfunc StreamServerInterceptor(trustedPeers []netip.Prefix, headers []string) grpc.StreamServerInterceptor {\n\treturn StreamServerInterceptorOpts(WithTrustedPeers(trustedPeers), WithHeaders(headers))\n}\n\n// UnaryServerInterceptorOpts returns a new unary server interceptor that extracts the real client IP from request headers.\n// It checks if the request comes from a trusted peer, validates headers against trusted proxies list and trusted proxies count\n// then it extracts the IP from the configured headers.\n// The real IP is added to the request context.\nfunc UnaryServerInterceptorOpts(opts ...Option) grpc.UnaryServerInterceptor {\n\to := evaluateOpts(opts)\n\treturn func(ctx context.Context, req any, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (any, error) {\n\t\tip := getRemoteIP(ctx, o.trustedPeers, o.trustedProxies, o.headers, o.trustedProxiesCount)\n\t\tif ip != noIP {\n\t\t\tctx = context.WithValue(ctx, realipKey{}, ip)\n\t\t}\n\t\treturn handler(ctx, req)\n\t}\n}\n\n// StreamServerInterceptorOpts returns a new stream server interceptor that extracts the real client IP from request headers.\n// It checks if the request comes from a trusted peer, validates headers against trusted proxies list and trusted proxies count\n// then it extracts the IP from the configured headers.\n// The real IP is added to the request context.\nfunc StreamServerInterceptorOpts(opts ...Option) grpc.StreamServerInterceptor {\n\to := evaluateOpts(opts)\n\treturn func(srv any, stream grpc.ServerStream, info *grpc.StreamServerInfo, handler grpc.StreamHandler) error {\n\t\tip := getRemoteIP(stream.Context(), o.trustedPeers, o.trustedProxies, o.headers, o.trustedProxiesCount)\n\t\tif ip != noIP {\n\t\t\treturn handler(srv, &serverStream{\n\t\t\t\tServerStream: stream,\n\t\t\t\tctx:          context.WithValue(stream.Context(), realipKey{}, ip),\n\t\t\t})\n\t\t}\n\t\treturn handler(srv, stream)\n\t}\n}\n"
  },
  {
    "path": "interceptors/realip/realip_test.go",
    "content": "// Copyright (c) The go-grpc-middleware Authors.\n// Licensed under the Apache License 2.0.\n\npackage realip\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"net\"\n\t\"net/netip\"\n\t\"testing\"\n\n\t\"github.com/stretchr/testify/assert\"\n\t\"google.golang.org/grpc\"\n\t\"google.golang.org/grpc/metadata\"\n\t\"google.golang.org/grpc/peer\"\n)\n\nvar (\n\tlocalnet []netip.Prefix = []netip.Prefix{\n\t\tnetip.MustParsePrefix(\"127.0.0.1/8\"),\n\t\tnetip.MustParsePrefix(\"::1/128\"),\n\t}\n\n\tprivatenet []netip.Prefix = []netip.Prefix{\n\t\tnetip.MustParsePrefix(\"10.0.0.0/8\"),\n\t\tnetip.MustParsePrefix(\"172.16.0.0/12\"),\n\t\tnetip.MustParsePrefix(\"192.168.0.0/16\"),\n\t\tnetip.MustParsePrefix(\"2002:c0a8::/32\"),\n\t}\n\n\tprivateIP  netip.Addr = netip.MustParseAddr(\"192.168.0.1\")\n\tprivateIP6 netip.Addr = netip.MustParseAddr(\"::ffff:c0a8:1\")\n\tpublicIP   netip.Addr = netip.MustParseAddr(\"8.8.8.8\")\n\tpublicIP6  netip.Addr = netip.MustParseAddr(\"::ffff:808:808\")\n\tlocalhost  netip.Addr = netip.MustParseAddr(\"127.0.0.1\")\n\tlocalhost6 netip.Addr = netip.MustParseAddr(\"::1\")\n)\n\nfunc localhostPeer() *peer.Peer {\n\treturn &peer.Peer{\n\t\tAddr: &net.TCPAddr{\n\t\t\tIP: net.ParseIP(localhost.String()),\n\t\t},\n\t}\n}\n\nfunc localhost6Peer() *peer.Peer {\n\treturn &peer.Peer{\n\t\tAddr: &net.TCPAddr{\n\t\t\tIP: net.ParseIP(localhost6.String()),\n\t\t},\n\t}\n}\n\nfunc publicPeer() *peer.Peer {\n\treturn &peer.Peer{\n\t\tAddr: &net.TCPAddr{\n\t\t\tIP: net.ParseIP(publicIP.String()),\n\t\t},\n\t}\n}\n\nfunc privatePeer() *peer.Peer {\n\treturn &peer.Peer{\n\t\tAddr: &net.TCPAddr{\n\t\t\tIP: net.ParseIP(privateIP.String()),\n\t\t},\n\t}\n}\n\nfunc private6Peer() *peer.Peer {\n\treturn &peer.Peer{\n\t\tAddr: &net.TCPAddr{\n\t\t\tIP: net.ParseIP(privateIP6.String()),\n\t\t},\n\t}\n}\n\ntype testCase struct {\n\ttrustedPeers   []netip.Prefix\n\ttrustedProxies []netip.Prefix\n\tproxiesCount   uint\n\theaderKeys     []string\n\tinputHeaders   map[string]string\n\tpeer           *peer.Peer\n\texpectedIP     netip.Addr\n}\n\nfunc (c *testCase) optsFromTestCase() []Option {\n\treturn []Option{\n\t\tWithTrustedPeers(c.trustedPeers),\n\t\tWithTrustedProxies(c.trustedProxies),\n\t\tWithTrustedProxiesCount(c.proxiesCount),\n\t\tWithHeaders(c.headerKeys),\n\t}\n}\n\nfunc testUnaryServerInterceptor(t *testing.T, c *testCase) {\n\tinterceptor := UnaryServerInterceptorOpts(c.optsFromTestCase()...)\n\thandler := func(ctx context.Context, req any) (any, error) {\n\t\tip, _ := FromContext(ctx)\n\n\t\tassert.Equal(t, c.expectedIP, ip)\n\t\treturn nil, nil\n\t}\n\tinfo := &grpc.UnaryServerInfo{\n\t\tFullMethod: \"FakeMethod\",\n\t}\n\tctx := context.Background()\n\tif c.peer != nil {\n\t\tctx = peer.NewContext(ctx, c.peer)\n\t}\n\tif c.inputHeaders != nil {\n\t\tmd := metadata.New(c.inputHeaders)\n\t\tctx = metadata.NewIncomingContext(ctx, md)\n\t}\n\n\tresp, err := interceptor(ctx, nil, info, handler)\n\tassert.Nil(t, resp)\n\tassert.NoError(t, err)\n}\n\nfunc testStreamServerInterceptor(t *testing.T, c *testCase) {\n\tinterceptor := StreamServerInterceptorOpts(c.optsFromTestCase()...)\n\thandler := func(srv any, stream grpc.ServerStream) error {\n\t\tip, _ := FromContext(stream.Context())\n\n\t\tassert.Equal(t, c.expectedIP, ip)\n\t\treturn nil\n\t}\n\tinfo := &grpc.StreamServerInfo{\n\t\tFullMethod: \"FakeMethod\",\n\t}\n\tctx := context.Background()\n\tif c.peer != nil {\n\t\tctx = peer.NewContext(ctx, c.peer)\n\t}\n\tif c.inputHeaders != nil {\n\t\tmd := metadata.New(c.inputHeaders)\n\t\tctx = metadata.NewIncomingContext(ctx, md)\n\t}\n\n\terr := interceptor(nil, &serverStream{ctx: ctx}, info, handler)\n\tassert.NoError(t, err)\n}\n\nfunc TestInterceptor(t *testing.T) {\n\tt.Run(\"no peer\", func(t *testing.T) {\n\t\ttc := &testCase{\n\t\t\t// Test that if there is no peer, we don't get an IP.\n\t\t\ttrustedPeers: localnet,\n\t\t\theaderKeys:   []string{XForwardedFor},\n\t\t\tinputHeaders: map[string]string{\n\t\t\t\tXForwardedFor: localhost.String(),\n\t\t\t},\n\t\t\tpeer:       nil,\n\t\t\texpectedIP: netip.Addr{},\n\t\t}\n\t\tt.Run(\"unary\", func(t *testing.T) {\n\t\t\ttestUnaryServerInterceptor(t, tc)\n\t\t})\n\t\tt.Run(\"stream\", func(t *testing.T) {\n\t\t\ttestStreamServerInterceptor(t, tc)\n\t\t})\n\t})\n\tt.Run(\"trusted peer header csv\", func(t *testing.T) {\n\t\ttc := &testCase{\n\t\t\t// Test that if the remote peer is trusted and the header contains\n\t\t\t// a comma separated list of valid IPs, we get right most one.\n\t\t\ttrustedPeers: localnet,\n\t\t\theaderKeys:   []string{XForwardedFor},\n\t\t\tinputHeaders: map[string]string{\n\t\t\t\tXForwardedFor: fmt.Sprintf(\"%s,%s\", localhost.String(), publicIP.String()),\n\t\t\t},\n\t\t\tpeer:       localhostPeer(),\n\t\t\texpectedIP: publicIP,\n\t\t}\n\t\tt.Run(\"unary\", func(t *testing.T) {\n\t\t\ttestUnaryServerInterceptor(t, tc)\n\t\t})\n\t\tt.Run(\"stream\", func(t *testing.T) {\n\t\t\ttestStreamServerInterceptor(t, tc)\n\t\t})\n\t})\n\tt.Run(\"trusted proxy list with XForwardedFor\", func(t *testing.T) {\n\t\ttc := &testCase{\n\t\t\t// Test that if the remote peer is trusted and the header contains\n\t\t\t// a comma separated list of valid IPs,\n\t\t\t// we get the first going from right to left that is not in local net\n\t\t\ttrustedPeers:   localnet,\n\t\t\ttrustedProxies: localnet,\n\t\t\theaderKeys:     []string{XForwardedFor},\n\t\t\tinputHeaders: map[string]string{\n\t\t\t\tXForwardedFor: fmt.Sprintf(\"%s,%s\", publicIP.String(), localhost.String()),\n\t\t\t},\n\t\t\tpeer:       localhostPeer(),\n\t\t\texpectedIP: publicIP,\n\t\t}\n\t\tt.Run(\"unary\", func(t *testing.T) {\n\t\t\ttestUnaryServerInterceptor(t, tc)\n\t\t})\n\t\tt.Run(\"stream\", func(t *testing.T) {\n\t\t\ttestStreamServerInterceptor(t, tc)\n\t\t})\n\t})\n\tt.Run(\"trusted proxy list private net with XForwardedFor\", func(t *testing.T) {\n\t\ttc := &testCase{\n\t\t\t// Test that if the remote peer is trusted and the header contains\n\t\t\t// a comma separated list of valid IPs,\n\t\t\t// we get the first going from right to left that is not in private net\n\t\t\ttrustedPeers:   localnet,\n\t\t\ttrustedProxies: privatenet,\n\t\t\theaderKeys:     []string{XForwardedFor},\n\t\t\tinputHeaders: map[string]string{\n\t\t\t\tXForwardedFor: fmt.Sprintf(\"%s,%s\", publicIP.String(), localhost.String()),\n\t\t\t},\n\t\t\tpeer:       localhostPeer(),\n\t\t\texpectedIP: localhost,\n\t\t}\n\t\tt.Run(\"unary\", func(t *testing.T) {\n\t\t\ttestUnaryServerInterceptor(t, tc)\n\t\t})\n\t\tt.Run(\"stream\", func(t *testing.T) {\n\t\t\ttestStreamServerInterceptor(t, tc)\n\t\t})\n\t})\n\tt.Run(\"trusted proxy count with XForwardedFor\", func(t *testing.T) {\n\t\ttc := &testCase{\n\t\t\t// Test that if the remote peer is trusted and the header contains\n\t\t\t// a comma separated list of valid IPs, we get right most one -1 proxiesCount.\n\t\t\ttrustedPeers: localnet,\n\t\t\tproxiesCount: 1,\n\t\t\theaderKeys:   []string{XForwardedFor},\n\t\t\tinputHeaders: map[string]string{\n\t\t\t\tXForwardedFor: fmt.Sprintf(\"%s,%s\", publicIP.String(), localhost.String()),\n\t\t\t},\n\t\t\tpeer:       localhostPeer(),\n\t\t\texpectedIP: publicIP,\n\t\t}\n\t\tt.Run(\"unary\", func(t *testing.T) {\n\t\t\ttestUnaryServerInterceptor(t, tc)\n\t\t})\n\t\tt.Run(\"stream\", func(t *testing.T) {\n\t\t\ttestStreamServerInterceptor(t, tc)\n\t\t})\n\t})\n\tt.Run(\"wrong trusted proxy count with XForwardedFor\", func(t *testing.T) {\n\t\ttc := &testCase{\n\t\t\t// Test that if the remote peer is trusted and the header contains\n\t\t\t// a comma separated list of valid IPs,\n\t\t\t// we get peer ip as the proxiesCount is wrongly configured\n\t\t\ttrustedPeers: localnet,\n\t\t\tproxiesCount: 10,\n\t\t\theaderKeys:   []string{XForwardedFor},\n\t\t\tinputHeaders: map[string]string{\n\t\t\t\tXForwardedFor: fmt.Sprintf(\"%s,%s\", publicIP.String(), localhost.String()),\n\t\t\t},\n\t\t\tpeer:       localhostPeer(),\n\t\t\texpectedIP: localhost,\n\t\t}\n\t\tt.Run(\"unary\", func(t *testing.T) {\n\t\t\ttestUnaryServerInterceptor(t, tc)\n\t\t})\n\t\tt.Run(\"stream\", func(t *testing.T) {\n\t\t\ttestStreamServerInterceptor(t, tc)\n\t\t})\n\t})\n\tt.Run(\"trusted peer single\", func(t *testing.T) {\n\t\ttc := &testCase{\n\t\t\t// Test that if the remote peer is trusted and the header contains\n\t\t\t// a single valid IP, we get that IP.\n\t\t\ttrustedPeers: localnet,\n\t\t\theaderKeys:   []string{XRealIp},\n\t\t\tinputHeaders: map[string]string{\n\t\t\t\tXRealIp: privateIP.String(),\n\t\t\t},\n\t\t\tpeer:       localhostPeer(),\n\t\t\texpectedIP: privateIP,\n\t\t}\n\t\tt.Run(\"unary\", func(t *testing.T) {\n\t\t\ttestUnaryServerInterceptor(t, tc)\n\t\t})\n\t\tt.Run(\"stream\", func(t *testing.T) {\n\t\t\ttestStreamServerInterceptor(t, tc)\n\t\t})\n\t})\n\tt.Run(\"trusted peer multiple\", func(t *testing.T) {\n\t\ttc := &testCase{\n\t\t\t// Test that if the trusted peers list is larger than 1 network and\n\t\t\t// the remote peer is in the third network, we get the right IP.\n\t\t\ttrustedPeers: privatenet,\n\t\t\theaderKeys:   []string{TrueClientIp},\n\t\t\tinputHeaders: map[string]string{\n\t\t\t\tTrueClientIp: publicIP.String(),\n\t\t\t},\n\t\t\tpeer:       privatePeer(),\n\t\t\texpectedIP: publicIP,\n\t\t}\n\t\tt.Run(\"unary\", func(t *testing.T) {\n\t\t\ttestUnaryServerInterceptor(t, tc)\n\t\t})\n\t\tt.Run(\"stream\", func(t *testing.T) {\n\t\t\ttestStreamServerInterceptor(t, tc)\n\t\t})\n\t})\n\tt.Run(\"untrusted peer single\", func(t *testing.T) {\n\t\ttc := &testCase{\n\t\t\t// Test that if the remote peer is not trusted and the header\n\t\t\t// contains a single valid IP, we get that the peer IP.\n\t\t\ttrustedPeers: localnet,\n\t\t\theaderKeys:   []string{XRealIp},\n\t\t\tinputHeaders: map[string]string{\n\t\t\t\tXRealIp: privateIP.String(),\n\t\t\t},\n\t\t\tpeer:       publicPeer(),\n\t\t\texpectedIP: publicIP,\n\t\t}\n\t\tt.Run(\"unary\", func(t *testing.T) {\n\t\t\ttestUnaryServerInterceptor(t, tc)\n\t\t})\n\t\tt.Run(\"stream\", func(t *testing.T) {\n\t\t\ttestStreamServerInterceptor(t, tc)\n\t\t})\n\t})\n\tt.Run(\"trusted peer multiple headers\", func(t *testing.T) {\n\t\ttc := &testCase{\n\t\t\t// Test that if the peer is trusted and several headers are\n\t\t\t// provided, the interceptor reads the IP from the first header in\n\t\t\t// the list.\n\t\t\ttrustedPeers: localnet,\n\t\t\theaderKeys:   []string{XRealIp, TrueClientIp},\n\t\t\tinputHeaders: map[string]string{\n\t\t\t\tXRealIp:      privateIP.String(),\n\t\t\t\tTrueClientIp: publicIP.String(),\n\t\t\t},\n\t\t\tpeer:       localhostPeer(),\n\t\t\texpectedIP: privateIP,\n\t\t}\n\t\tt.Run(\"unary\", func(t *testing.T) {\n\t\t\ttestUnaryServerInterceptor(t, tc)\n\t\t})\n\t\tt.Run(\"stream\", func(t *testing.T) {\n\t\t\ttestStreamServerInterceptor(t, tc)\n\t\t})\n\t})\n\tt.Run(\"trusted peer multiple header configured single provided\", func(t *testing.T) {\n\t\ttc := &testCase{\n\t\t\t// Test that if the peer is trusted and several headers are\n\t\t\t// configured, but only one is provided, the interceptor reads the\n\t\t\t// IP from the provided header.\n\t\t\ttrustedPeers: localnet,\n\t\t\theaderKeys:   []string{XRealIp, TrueClientIp, XForwardedFor},\n\t\t\tinputHeaders: map[string]string{\n\t\t\t\tTrueClientIp: publicIP.String(),\n\t\t\t},\n\t\t\tpeer:       localhostPeer(),\n\t\t\texpectedIP: publicIP,\n\t\t}\n\t\tt.Run(\"unary\", func(t *testing.T) {\n\t\t\ttestUnaryServerInterceptor(t, tc)\n\t\t})\n\t\tt.Run(\"stream\", func(t *testing.T) {\n\t\t\ttestStreamServerInterceptor(t, tc)\n\t\t})\n\t})\n\tt.Run(\"trusted peer multiple header configured none provided\", func(t *testing.T) {\n\t\ttc := &testCase{\n\t\t\t// Test that if the peer is trusted and several headers are, but no\n\t\t\t// header is provided, the interceptor reads the IP from the peer.\n\t\t\t//\n\t\t\t// This indicates that the proxy is not configured to forward the\n\t\t\t// IP. Using the peer IP is better than nothing.\n\t\t\ttrustedPeers: localnet,\n\t\t\theaderKeys:   []string{XRealIp, TrueClientIp, XForwardedFor},\n\t\t\tpeer:         localhostPeer(),\n\t\t\texpectedIP:   localhost,\n\t\t}\n\t\tt.Run(\"unary\", func(t *testing.T) {\n\t\t\ttestUnaryServerInterceptor(t, tc)\n\t\t})\n\t\tt.Run(\"stream\", func(t *testing.T) {\n\t\t\ttestStreamServerInterceptor(t, tc)\n\t\t})\n\t})\n\tt.Run(\"untrusted peer multiple headers\", func(t *testing.T) {\n\t\ttc := &testCase{\n\t\t\t// Test that if the peer is not trusted, but several headers are\n\t\t\t// provided, the interceptor reads the IP from peer.\n\t\t\ttrustedPeers: nil,\n\t\t\tinputHeaders: map[string]string{\n\t\t\t\tXRealIp:      privateIP.String(),\n\t\t\t\tTrueClientIp: localhost.String(),\n\t\t\t},\n\t\t\tpeer:       publicPeer(),\n\t\t\texpectedIP: publicIP,\n\t\t}\n\t\tt.Run(\"unary\", func(t *testing.T) {\n\t\t\ttestUnaryServerInterceptor(t, tc)\n\t\t})\n\t\tt.Run(\"stream\", func(t *testing.T) {\n\t\t\ttestStreamServerInterceptor(t, tc)\n\t\t})\n\t})\n\tt.Run(\"untrusted peer multiple header configured single provided\", func(t *testing.T) {\n\t\ttc := &testCase{\n\t\t\t// Test that if the peer is not trusted and several headers are\n\t\t\t// configured, but only one is provided, the interceptor reads the\n\t\t\t// IP from the peer.\n\t\t\t//\n\t\t\t// This is because the peer is untrusted, and as such we cannot\n\t\t\t// trust the headers.\n\t\t\ttrustedPeers: nil,\n\t\t\theaderKeys:   []string{XRealIp, TrueClientIp, XForwardedFor},\n\t\t\tinputHeaders: map[string]string{\n\t\t\t\tTrueClientIp: publicIP.String(),\n\t\t\t},\n\t\t\tpeer:       publicPeer(),\n\t\t\texpectedIP: publicIP,\n\t\t}\n\t\tt.Run(\"unary\", func(t *testing.T) {\n\t\t\ttestUnaryServerInterceptor(t, tc)\n\t\t})\n\t\tt.Run(\"stream\", func(t *testing.T) {\n\t\t\ttestStreamServerInterceptor(t, tc)\n\t\t})\n\t})\n\tt.Run(\"trusted peer malformed header\", func(t *testing.T) {\n\t\ttc := &testCase{\n\t\t\t// Test that if the peer is trusted, but the provided headers\n\t\t\t// contain malformed IP addresses, the interceptor reads the IP\n\t\t\t// from the peer.\n\t\t\ttrustedPeers: localnet,\n\t\t\theaderKeys:   []string{XRealIp, TrueClientIp, XForwardedFor},\n\t\t\tinputHeaders: map[string]string{\n\t\t\t\tTrueClientIp: \"malformed\",\n\t\t\t},\n\t\t\tpeer:       localhostPeer(),\n\t\t\texpectedIP: localhost,\n\t\t}\n\t\tt.Run(\"unary\", func(t *testing.T) {\n\t\t\ttestUnaryServerInterceptor(t, tc)\n\t\t})\n\t\tt.Run(\"stream\", func(t *testing.T) {\n\t\t\ttestStreamServerInterceptor(t, tc)\n\t\t})\n\t})\n\tt.Run(\"ipv6 from grpc peer\", func(t *testing.T) {\n\t\ttc := &testCase{\n\t\t\ttrustedPeers: localnet,\n\t\t\theaderKeys:   []string{},\n\t\t\tpeer:         localhost6Peer(),\n\t\t\texpectedIP:   localhost6,\n\t\t}\n\t\tt.Run(\"unary\", func(t *testing.T) {\n\t\t\ttestUnaryServerInterceptor(t, tc)\n\t\t})\n\t\tt.Run(\"stream\", func(t *testing.T) {\n\t\t\ttestStreamServerInterceptor(t, tc)\n\t\t})\n\t})\n\tt.Run(\"ipv6 from header\", func(t *testing.T) {\n\t\ttc := &testCase{\n\t\t\ttrustedPeers: privatenet,\n\t\t\theaderKeys:   []string{XForwardedFor},\n\t\t\tinputHeaders: map[string]string{\n\t\t\t\tXForwardedFor: publicIP6.String(),\n\t\t\t},\n\t\t\tpeer:       private6Peer(),\n\t\t\texpectedIP: publicIP6,\n\t\t}\n\t\tt.Run(\"unary\", func(t *testing.T) {\n\t\t\ttestUnaryServerInterceptor(t, tc)\n\t\t})\n\t\tt.Run(\"stream\", func(t *testing.T) {\n\t\t\ttestStreamServerInterceptor(t, tc)\n\t\t})\n\t})\n\tt.Run(\"unix\", func(t *testing.T) {\n\t\ttc := &testCase{\n\t\t\ttrustedPeers: localnet,\n\t\t\theaderKeys:   []string{XRealIp},\n\t\t\tpeer: &peer.Peer{\n\t\t\t\tAddr: &net.UnixAddr{Name: \"unix\", Net: \"unix\"},\n\t\t\t},\n\t\t\texpectedIP: netip.Addr{},\n\t\t}\n\t\tt.Run(\"unary\", func(t *testing.T) {\n\t\t\ttestUnaryServerInterceptor(t, tc)\n\t\t})\n\t\tt.Run(\"stream\", func(t *testing.T) {\n\t\t\ttestStreamServerInterceptor(t, tc)\n\t\t})\n\t})\n\tt.Run(\"header casing\", func(t *testing.T) {\n\t\ttc := &testCase{\n\t\t\t// Test that header casing is ignored.\n\t\t\ttrustedPeers: localnet,\n\t\t\theaderKeys:   []string{XRealIp},\n\t\t\tinputHeaders: map[string]string{\n\t\t\t\t\"X-Real-IP\": privateIP.String(),\n\t\t\t},\n\t\t\tpeer:       localhostPeer(),\n\t\t\texpectedIP: privateIP,\n\t\t}\n\t\tt.Run(\"unary\", func(t *testing.T) {\n\t\t\ttestUnaryServerInterceptor(t, tc)\n\t\t})\n\t\tt.Run(\"stream\", func(t *testing.T) {\n\t\t\ttestStreamServerInterceptor(t, tc)\n\t\t})\n\t})\n}\n"
  },
  {
    "path": "interceptors/recovery/doc.go",
    "content": "// Copyright (c) The go-grpc-middleware Authors.\n// Licensed under the Apache License 2.0.\n\n// Copyright 2017 David Ackroyd. All Rights Reserved.\n// See LICENSE for licensing terms.\n\n/*\nPackage recovery is a middleware that recovers from panics and logs the panic message.\n\n`recovery` are interceptors that recover from gRPC handler panics.\n\n# Server Side Recovery Middleware\n\nBy default a panic will be converted into a gRPC error with `code.Internal`.\n\nHandling can be customised by providing an alternate recovery function.\n\nPlease see examples for simple examples of use.\n*/\npackage recovery\n"
  },
  {
    "path": "interceptors/recovery/examples_test.go",
    "content": "// Copyright (c) The go-grpc-middleware Authors.\n// Licensed under the Apache License 2.0.\n\n// Copyright 2017 David Ackroyd. All Rights Reserved.\n// See LICENSE for licensing terms.\n\npackage recovery_test\n\nimport (\n\t\"github.com/grpc-ecosystem/go-grpc-middleware/v2/interceptors/recovery\"\n\t\"google.golang.org/grpc\"\n\t\"google.golang.org/grpc/codes\"\n\t\"google.golang.org/grpc/status\"\n)\n\nvar customFunc recovery.RecoveryHandlerFunc\n\n// Initialization shows an initialization sequence with a custom recovery handler func.\nfunc Example_initialization() {\n\t// Define customfunc to handle panic\n\tcustomFunc = func(p any) (err error) {\n\t\treturn status.Errorf(codes.Unknown, \"panic triggered: %v\", p)\n\t}\n\t// Shared options for the logger, with a custom gRPC code to log level function.\n\topts := []recovery.Option{\n\t\trecovery.WithRecoveryHandler(customFunc),\n\t}\n\t// Create a server. Recovery handlers should typically be last in the chain so that other middleware\n\t// (e.g. logging) can operate on the recovered state instead of being directly affected by any panic\n\t_ = grpc.NewServer(\n\t\tgrpc.UnaryInterceptor(\n\t\t\trecovery.UnaryServerInterceptor(opts...),\n\t\t),\n\t\tgrpc.StreamInterceptor(\n\t\t\trecovery.StreamServerInterceptor(opts...),\n\t\t),\n\t)\n}\n"
  },
  {
    "path": "interceptors/recovery/interceptors.go",
    "content": "// Copyright (c) The go-grpc-middleware Authors.\n// Licensed under the Apache License 2.0.\n\n// Copyright 2017 David Ackroyd. All Rights Reserved.\n// See LICENSE for licensing terms.\n\npackage recovery\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"runtime\"\n\n\t\"google.golang.org/grpc\"\n)\n\n// RecoveryHandlerFunc is a function that recovers from the panic `p` by returning an `error`.\ntype RecoveryHandlerFunc func(p any) (err error)\n\n// RecoveryHandlerFuncContext is a function that recovers from the panic `p` by returning an `error`.\n// The context can be used to extract request scoped metadata and context values.\ntype RecoveryHandlerFuncContext func(ctx context.Context, p any) (err error)\n\n// UnaryServerInterceptor returns a new unary server interceptor for panic recovery.\nfunc UnaryServerInterceptor(opts ...Option) grpc.UnaryServerInterceptor {\n\to := evaluateOptions(opts)\n\treturn func(ctx context.Context, req any, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (_ any, err error) {\n\t\tdefer func() {\n\t\t\tif r := recover(); r != nil {\n\t\t\t\terr = recoverFrom(ctx, r, o.recoveryHandlerFunc)\n\t\t\t}\n\t\t}()\n\n\t\treturn handler(ctx, req)\n\t}\n}\n\n// StreamServerInterceptor returns a new streaming server interceptor for panic recovery.\nfunc StreamServerInterceptor(opts ...Option) grpc.StreamServerInterceptor {\n\to := evaluateOptions(opts)\n\treturn func(srv any, stream grpc.ServerStream, info *grpc.StreamServerInfo, handler grpc.StreamHandler) (err error) {\n\t\tdefer func() {\n\t\t\tif r := recover(); r != nil {\n\t\t\t\terr = recoverFrom(stream.Context(), r, o.recoveryHandlerFunc)\n\t\t\t}\n\t\t}()\n\n\t\treturn handler(srv, stream)\n\t}\n}\n\nfunc recoverFrom(ctx context.Context, p any, r RecoveryHandlerFuncContext) error {\n\tif r != nil {\n\t\treturn r(ctx, p)\n\t}\n\tstack := make([]byte, 64<<10)\n\tstack = stack[:runtime.Stack(stack, false)]\n\treturn &PanicError{Panic: p, Stack: stack}\n}\n\ntype PanicError struct {\n\tPanic any\n\tStack []byte\n}\n\nfunc (e *PanicError) Error() string {\n\treturn fmt.Sprintf(\"panic caught: %v\\n\\n%s\", e.Panic, e.Stack)\n}\n"
  },
  {
    "path": "interceptors/recovery/interceptors_test.go",
    "content": "// Copyright (c) The go-grpc-middleware Authors.\n// Licensed under the Apache License 2.0.\n\n// Copyright 2017 David Ackroyd. All Rights Reserved.\n// See LICENSE for licensing terms.\n\npackage recovery_test\n\nimport (\n\t\"context\"\n\t\"testing\"\n\n\t\"github.com/grpc-ecosystem/go-grpc-middleware/v2/interceptors/recovery\"\n\t\"github.com/grpc-ecosystem/go-grpc-middleware/v2/testing/testpb\"\n\t\"github.com/stretchr/testify/suite\"\n\t\"google.golang.org/grpc\"\n\t\"google.golang.org/grpc/codes\"\n\t\"google.golang.org/grpc/status\"\n)\n\ntype recoveryAssertService struct {\n\ttestpb.TestServiceServer\n}\n\nfunc (s *recoveryAssertService) Ping(ctx context.Context, ping *testpb.PingRequest) (*testpb.PingResponse, error) {\n\tif ping.Value == \"panic\" {\n\t\tpanic(\"very bad thing happened\")\n\t}\n\treturn s.TestServiceServer.Ping(ctx, ping)\n}\n\nfunc (s *recoveryAssertService) PingList(ping *testpb.PingListRequest, stream testpb.TestService_PingListServer) error {\n\tif ping.Value == \"panic\" {\n\t\tpanic(\"very bad thing happened\")\n\t}\n\treturn s.TestServiceServer.PingList(ping, stream)\n}\n\nfunc TestRecoverySuite(t *testing.T) {\n\ts := &RecoverySuite{\n\t\tInterceptorTestSuite: &testpb.InterceptorTestSuite{\n\t\t\tTestService: &recoveryAssertService{TestServiceServer: &testpb.TestPingService{}},\n\t\t\tServerOpts: []grpc.ServerOption{\n\t\t\t\tgrpc.StreamInterceptor(\n\t\t\t\t\trecovery.StreamServerInterceptor()),\n\t\t\t\tgrpc.UnaryInterceptor(\n\t\t\t\t\trecovery.UnaryServerInterceptor()),\n\t\t\t},\n\t\t},\n\t}\n\tsuite.Run(t, s)\n}\n\ntype RecoverySuite struct {\n\t*testpb.InterceptorTestSuite\n}\n\nfunc (s *RecoverySuite) TestUnary_SuccessfulRequest() {\n\t_, err := s.Client.Ping(s.SimpleCtx(), testpb.GoodPing)\n\ts.Require().NoError(err, \"no error must occur\")\n}\n\nfunc (s *RecoverySuite) TestUnary_PanickingRequest() {\n\t_, err := s.Client.Ping(s.SimpleCtx(), &testpb.PingRequest{Value: \"panic\"})\n\ts.Require().Error(err, \"there must be an error\")\n\ts.Assert().Equal(codes.Unknown, status.Code(err), \"must error with unknown\")\n\ts.Assert().Contains(status.Convert(err).Message(), \"panic caught\", \"must error with message\")\n\ts.Assert().Contains(status.Convert(err).Message(), \"recovery.recoverFrom\", \"must include stack trace\")\n}\n\nfunc (s *RecoverySuite) TestStream_SuccessfulReceive() {\n\tstream, err := s.Client.PingList(s.SimpleCtx(), testpb.GoodPingList)\n\ts.Require().NoError(err, \"should not fail on establishing the stream\")\n\tpong, err := stream.Recv()\n\ts.Require().NoError(err, \"no error must occur\")\n\ts.Require().NotNil(pong, \"pong must not be nil\")\n}\n\nfunc (s *RecoverySuite) TestStream_PanickingReceive() {\n\tstream, err := s.Client.PingList(s.SimpleCtx(), &testpb.PingListRequest{Value: \"panic\"})\n\ts.Require().NoError(err, \"should not fail on establishing the stream\")\n\t_, err = stream.Recv()\n\ts.Require().Error(err, \"there must be an error\")\n\ts.Assert().Equal(codes.Unknown, status.Code(err), \"must error with unknown\")\n\ts.Assert().Contains(status.Convert(err).Message(), \"panic caught\", \"must error with message\")\n\ts.Assert().Contains(status.Convert(err).Message(), \"recovery.recoverFrom\", \"must include stack trace\")\n}\n\nfunc TestRecoveryOverrideSuite(t *testing.T) {\n\topts := []recovery.Option{\n\t\trecovery.WithRecoveryHandler(func(p any) (err error) {\n\t\t\treturn status.Errorf(codes.Unknown, \"panic triggered: %v\", p)\n\t\t}),\n\t}\n\ts := &RecoveryOverrideSuite{\n\t\tInterceptorTestSuite: &testpb.InterceptorTestSuite{\n\t\t\tTestService: &recoveryAssertService{TestServiceServer: &testpb.TestPingService{}},\n\t\t\tServerOpts: []grpc.ServerOption{\n\t\t\t\tgrpc.StreamInterceptor(\n\t\t\t\t\trecovery.StreamServerInterceptor(opts...)),\n\t\t\t\tgrpc.UnaryInterceptor(\n\t\t\t\t\trecovery.UnaryServerInterceptor(opts...)),\n\t\t\t},\n\t\t},\n\t}\n\tsuite.Run(t, s)\n}\n\ntype RecoveryOverrideSuite struct {\n\t*testpb.InterceptorTestSuite\n}\n\nfunc (s *RecoveryOverrideSuite) TestUnary_SuccessfulRequest() {\n\t_, err := s.Client.Ping(s.SimpleCtx(), testpb.GoodPing)\n\ts.Require().NoError(err, \"no error must occur\")\n}\n\nfunc (s *RecoveryOverrideSuite) TestUnary_PanickingRequest() {\n\t_, err := s.Client.Ping(s.SimpleCtx(), &testpb.PingRequest{Value: \"panic\"})\n\ts.Require().Error(err, \"there must be an error\")\n\ts.Assert().Equal(codes.Unknown, status.Code(err), \"must error with unknown\")\n\ts.Assert().Equal(\"panic triggered: very bad thing happened\", status.Convert(err).Message(), \"must error with message\")\n}\n\nfunc (s *RecoveryOverrideSuite) TestStream_SuccessfulReceive() {\n\tstream, err := s.Client.PingList(s.SimpleCtx(), testpb.GoodPingList)\n\ts.Require().NoError(err, \"should not fail on establishing the stream\")\n\tpong, err := stream.Recv()\n\ts.Require().NoError(err, \"no error must occur\")\n\ts.Require().NotNil(pong, \"pong must not be nil\")\n}\n\nfunc (s *RecoveryOverrideSuite) TestStream_PanickingReceive() {\n\tstream, err := s.Client.PingList(s.SimpleCtx(), &testpb.PingListRequest{Value: \"panic\"})\n\ts.Require().NoError(err, \"should not fail on establishing the stream\")\n\t_, err = stream.Recv()\n\ts.Require().Error(err, \"there must be an error\")\n\ts.Assert().Equal(codes.Unknown, status.Code(err), \"must error with unknown\")\n\ts.Assert().Equal(\"panic triggered: very bad thing happened\", status.Convert(err).Message(), \"must error with message\")\n}\n"
  },
  {
    "path": "interceptors/recovery/options.go",
    "content": "// Copyright (c) The go-grpc-middleware Authors.\n// Licensed under the Apache License 2.0.\n\n// Copyright 2017 David Ackroyd. All Rights Reserved.\n// See LICENSE for licensing terms.\n\npackage recovery\n\nimport \"context\"\n\nvar defaultOptions = &options{\n\trecoveryHandlerFunc: nil,\n}\n\ntype options struct {\n\trecoveryHandlerFunc RecoveryHandlerFuncContext\n}\n\nfunc evaluateOptions(opts []Option) *options {\n\toptCopy := &options{}\n\t*optCopy = *defaultOptions\n\tfor _, o := range opts {\n\t\to(optCopy)\n\t}\n\treturn optCopy\n}\n\ntype Option func(*options)\n\n// WithRecoveryHandler customizes the function for recovering from a panic.\nfunc WithRecoveryHandler(f RecoveryHandlerFunc) Option {\n\treturn func(o *options) {\n\t\to.recoveryHandlerFunc = RecoveryHandlerFuncContext(func(ctx context.Context, p any) error {\n\t\t\treturn f(p)\n\t\t})\n\t}\n}\n\n// WithRecoveryHandlerContext customizes the function for recovering from a panic.\nfunc WithRecoveryHandlerContext(f RecoveryHandlerFuncContext) Option {\n\treturn func(o *options) {\n\t\to.recoveryHandlerFunc = f\n\t}\n}\n"
  },
  {
    "path": "interceptors/reporter.go",
    "content": "// Copyright (c) The go-grpc-middleware Authors.\n// Licensed under the Apache License 2.0.\n\npackage interceptors\n\nimport (\n\t\"context\"\n\t\"time\"\n\n\t\"google.golang.org/grpc/codes\"\n)\n\ntype GRPCType string\n\nconst (\n\tUnary        GRPCType = \"unary\"\n\tClientStream GRPCType = \"client_stream\"\n\tServerStream GRPCType = \"server_stream\"\n\tBidiStream   GRPCType = \"bidi_stream\"\n)\n\nvar AllCodes = []codes.Code{\n\tcodes.OK, codes.Canceled, codes.Unknown, codes.InvalidArgument, codes.DeadlineExceeded, codes.NotFound,\n\tcodes.AlreadyExists, codes.PermissionDenied, codes.Unauthenticated, codes.ResourceExhausted,\n\tcodes.FailedPrecondition, codes.Aborted, codes.OutOfRange, codes.Unimplemented, codes.Internal,\n\tcodes.Unavailable, codes.DataLoss,\n}\n\ntype ClientReportable interface {\n\tClientReporter(context.Context, CallMeta) (Reporter, context.Context)\n}\n\ntype ServerReportable interface {\n\tServerReporter(context.Context, CallMeta) (Reporter, context.Context)\n}\n\n// CommonReportableFunc helper allows an easy way to implement reporter with common client and server logic.\ntype CommonReportableFunc func(ctx context.Context, c CallMeta) (Reporter, context.Context)\n\nfunc (f CommonReportableFunc) ClientReporter(ctx context.Context, c CallMeta) (Reporter, context.Context) {\n\treturn f(ctx, c)\n}\n\nfunc (f CommonReportableFunc) ServerReporter(ctx context.Context, c CallMeta) (Reporter, context.Context) {\n\treturn f(ctx, c)\n}\n\ntype Reporter interface {\n\tPostCall(err error, rpcDuration time.Duration)\n\tPostMsgSend(reqProto any, err error, sendDuration time.Duration)\n\tPostMsgReceive(replyProto any, err error, recvDuration time.Duration)\n}\n\nvar _ Reporter = NoopReporter{}\n\ntype NoopReporter struct{}\n\nfunc (NoopReporter) PostCall(error, time.Duration)            {}\nfunc (NoopReporter) PostMsgSend(any, error, time.Duration)    {}\nfunc (NoopReporter) PostMsgReceive(any, error, time.Duration) {}\n\ntype report struct {\n\tcallMeta  CallMeta\n\tstartTime time.Time\n}\n\nfunc newReport(callMeta CallMeta) report {\n\tr := report{\n\t\tstartTime: time.Now(),\n\t\tcallMeta:  callMeta,\n\t}\n\treturn r\n}\n"
  },
  {
    "path": "interceptors/retry/README.md",
    "content": "## Retry Interceptor\n\nThe `retry` interceptor is a client-side middleware for gRPC that provides a generic mechanism to retry requests based on gRPC response codes.\n\n### Build Flags\n\nThe `retry` interceptor supports a build flag `retrynotrace` to disable tracing for retry attempts.\nThis can be useful to avoid importing `golang.org/x/net/trace`, which allows for more aggressive deadcode elimination. This can yield improvements in binary size when tracing is not needed.\n\nTo build your application with the `retrynotrace` flag, use the following command:\n\n```shell\ngo build -tags retrynotrace -o your_application\n```\n\n### Usage\n\nTo use the `retry` interceptor, you need to add it to your gRPC client interceptor chain:\n\n```go\nimport (\n    \"github.com/grpc-ecosystem/go-grpc-middleware/v2/interceptors/retry\"\n    \"google.golang.org/grpc\"\n)\n\nfunc main() {\n    opts := []grpc.DialOption{\n        grpc.WithUnaryInterceptor(retry.UnaryClientInterceptor(\n            retry.WithMax(3), // Maximum number of retries\n            retry.WithPerRetryTimeout(2*time.Second), // Timeout per retry\n        )),\n    }\n\n    conn, err := grpc.NewClient(\"your_grpc_server_address\", opts...)\n    if err != nil {\n        log.Fatalf(\"Failed to connect: %v\", err)\n    }\n    defer conn.Close()\n\n    // Your gRPC client code here\n}\n```\n\n### Configuration Options\n\n- `retry.WithMax(maxRetries int)`: Sets the maximum number of retry attempts.\n- `retry.WithPerRetryTimeout(timeout time.Duration)`: Sets the timeout for each retry attempt.\n- `retry.WithBackoff(backoffFunc retry.BackoffFunc)`: Sets a custom backoff strategy.\n- `retry.WithCodes(codes ...codes.Code)`: Specifies the gRPC response codes that should trigger a retry."
  },
  {
    "path": "interceptors/retry/backoff.go",
    "content": "// Copyright (c) The go-grpc-middleware Authors.\n// Licensed under the Apache License 2.0.\n\npackage retry\n\nimport (\n\t\"context\"\n\t\"math\"\n\t\"math/rand\"\n\t\"time\"\n)\n\n// BackoffLinear is very simple: it waits for a fixed period of time between calls.\nfunc BackoffLinear(waitBetween time.Duration) BackoffFunc {\n\treturn func(ctx context.Context, attempt uint) time.Duration {\n\t\treturn waitBetween\n\t}\n}\n\n// jitterUp adds random jitter to the duration.\n// This adds or subtracts time from the duration within a given jitter fraction.\n// For example for 10s and jitter 0.1, it will return a time within [9s, 11s])\nfunc jitterUp(duration time.Duration, jitter float64) time.Duration {\n\tmultiplier := jitter * (rand.Float64()*2 - 1)\n\treturn time.Duration(float64(duration) * (1 + multiplier))\n}\n\n// exponentBase2 computes 2^(a-1) where a >= 1. If a is 0, the result is 1.\n// if a is greater than 62, the result is 2^62 to avoid overflowing int64\nfunc exponentBase2(a uint) uint64 {\n\tif a == 0 {\n\t\treturn 1\n\t}\n\tif a > 62 {\n\t\treturn 1 << 62\n\t}\n\treturn (1 << a) >> 1\n}\n\n// BackoffLinearWithJitter waits a set period of time, allowing for jitter (fractional adjustment).\n// For example waitBetween=1s and jitter=0.10 can generate waits between 900ms and 1100ms.\nfunc BackoffLinearWithJitter(waitBetween time.Duration, jitterFraction float64) BackoffFunc {\n\treturn func(ctx context.Context, attempt uint) time.Duration {\n\t\treturn jitterUp(waitBetween, jitterFraction)\n\t}\n}\n\n// BackoffExponential produces increasing intervals for each attempt.\n// The scalar is multiplied times 2 raised to the current attempt. So the first\n// retry with a scalar of 100ms is 100ms, while the 5th attempt would be 1.6s.\nfunc BackoffExponential(scalar time.Duration) BackoffFunc {\n\treturn func(ctx context.Context, attempt uint) time.Duration {\n\t\treturn scalar * time.Duration(exponentBase2(attempt))\n\t}\n}\n\n// BackoffExponentialWithJitter creates an exponential backoff like\n// BackoffExponential does, but adds jitter.\nfunc BackoffExponentialWithJitter(scalar time.Duration, jitterFraction float64) BackoffFunc {\n\treturn func(ctx context.Context, attempt uint) time.Duration {\n\t\texp := exponentBase2(attempt)\n\t\tdur := scalar * time.Duration(exp)\n\t\t// Check for overflow in duration multiplication\n\t\tif exp != 0 && dur/scalar != time.Duration(exp) {\n\t\t\treturn time.Duration(math.MaxInt64)\n\t\t}\n\t\treturn jitterUp(scalar*time.Duration(exponentBase2(attempt)), jitterFraction)\n\t}\n}\n\nfunc BackoffExponentialWithJitterBounded(scalar time.Duration, jitterFrac float64, maxBound time.Duration) BackoffFunc {\n\treturn func(ctx context.Context, attempt uint) time.Duration {\n\t\texp := exponentBase2(attempt)\n\t\tdur := scalar * time.Duration(exp)\n\t\t// Check for overflow in duration multiplication\n\t\tif exp != 0 && dur/scalar != time.Duration(exp) {\n\t\t\treturn maxBound\n\t\t}\n\t\t// Apply random jitter between -jitterFrac and +jitterFrac\n\t\tjitter := 1 + jitterFrac*(rand.Float64()*2-1)\n\t\tjitteredDuration := time.Duration(float64(dur) * jitter)\n\t\t// Check for overflow in jitter multiplication\n\t\tif float64(dur)*jitter > float64(math.MaxInt64) {\n\t\t\treturn maxBound\n\t\t}\n\t\treturn min(jitteredDuration, maxBound)\n\t}\n}\n"
  },
  {
    "path": "interceptors/retry/backoff_test.go",
    "content": "// Copyright (c) The go-grpc-middleware Authors.\n// Licensed under the Apache License 2.0.\npackage retry\n\nimport (\n\t\"context\"\n\t\"testing\"\n\t\"time\"\n)\n\nfunc TestBackoffExponentialWithJitter(t *testing.T) {\n\tscalar := 100 * time.Millisecond\n\tjitterFrac := 0.10\n\tbackoffFunc := BackoffExponentialWithJitter(scalar, jitterFrac)\n\t// use 64 so we are past number of attempts where exponentBase2 would overflow\n\tfor i := 0; i < 64; i++ {\n\t\twaitFor := backoffFunc(nil, uint(i))\n\t\tif waitFor < 0 {\n\t\t\tt.Errorf(\"BackoffExponentialWithJitter(%d) = %d; want >= 0\", i, waitFor)\n\t\t}\n\t}\n}\n\nfunc TestBackoffExponentialWithJitterBounded(t *testing.T) {\n\tscalar := 100 * time.Millisecond\n\tjitterFrac := 0.10\n\tmaxBound := 10 * time.Second\n\tbackoff := BackoffExponentialWithJitterBounded(scalar, jitterFrac, maxBound)\n\t// use 64 so we are past number of attempts where exponentBase2 would overflow\n\tfor i := 0; i < 64; i++ {\n\t\twaitFor := backoff(context.Background(), uint(i))\n\t\tif waitFor > maxBound {\n\t\t\tt.Fatalf(\"expected dur to be less than %v, got %v for %d\", maxBound, waitFor, i)\n\t\t}\n\t\tif waitFor < 0 {\n\t\t\tt.Fatalf(\"expected dur to be greater than 0, got %v for %d\", waitFor, i)\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "interceptors/retry/doc.go",
    "content": "// Copyright (c) The go-grpc-middleware Authors.\n// Licensed under the Apache License 2.0.\n\n/*\nPackage retry provides client-side request retry logic for gRPC.\n\n# Client-Side Request Retry Interceptor\n\nIt allows for automatic retry, inside the generated gRPC code of requests based on the gRPC status\nof the reply. It supports unary (1:1), and server stream (1:n) requests.\n\nBy default the interceptors *are disabled*, preventing accidental use of retries. You can easily\noverride the number of retries (setting them to more than 0) with a `grpc.ClientOption`, e.g.:\n\n\tmyclient.Ping(ctx, goodPing, grpc_retry.WithMax(5))\n\nOther default options are: retry on `ResourceExhausted` and `Unavailable` gRPC codes, use a 50ms\nlinear backoff with 10% jitter.\n\nFor chained interceptors, the retry interceptor will call every interceptor that follows it\nwhenever when a retry happens.\n\nPlease see examples for more advanced use.\n*/\npackage retry\n"
  },
  {
    "path": "interceptors/retry/examples_test.go",
    "content": "// Copyright (c) The go-grpc-middleware Authors.\n// Licensed under the Apache License 2.0.\n\npackage retry\n\nimport (\n\t\"context\"\n\t\"errors\"\n\t\"io\"\n\t\"time\"\n\n\t\"github.com/grpc-ecosystem/go-grpc-middleware/v2/testing/testpb\"\n\t\"google.golang.org/grpc\"\n\t\"google.golang.org/grpc/codes\"\n)\n\nvar cc *grpc.ClientConn\n\n// Simple example of using the default interceptor configuration.\nfunc Example_initialization() {\n\t_, _ = grpc.NewClient(\"myservice.example.com\",\n\t\tgrpc.WithStreamInterceptor(StreamClientInterceptor()),\n\t\tgrpc.WithUnaryInterceptor(UnaryClientInterceptor()),\n\t)\n}\n\n// Complex example with a 100ms linear backoff interval, and retry only on NotFound and Unavailable.\nfunc Example_initializationWithOptions() {\n\topts := []CallOption{\n\t\tWithBackoff(BackoffLinear(100 * time.Millisecond)),\n\t\tWithCodes(codes.NotFound, codes.Aborted),\n\t}\n\t_, _ = grpc.NewClient(\"myservice.example.com\",\n\t\tgrpc.WithStreamInterceptor(StreamClientInterceptor(opts...)),\n\t\tgrpc.WithUnaryInterceptor(UnaryClientInterceptor(opts...)),\n\t)\n}\n\n// Example with an exponential backoff starting with 100ms.\n//\n// Each next interval is the previous interval multiplied by 2.\nfunc Example_initializationWithExponentialBackoff() {\n\topts := []CallOption{\n\t\tWithBackoff(BackoffExponential(100 * time.Millisecond)),\n\t}\n\t_, _ = grpc.NewClient(\"myservice.example.com\",\n\t\tgrpc.WithStreamInterceptor(StreamClientInterceptor(opts...)),\n\t\tgrpc.WithUnaryInterceptor(UnaryClientInterceptor(opts...)),\n\t)\n}\n\n// Simple example of an idempotent `ServerStream` call, that will be retried automatically 3 times.\nfunc Example_simpleCall() {\n\tctx, cancel := context.WithTimeout(context.TODO(), 1*time.Second)\n\tdefer cancel()\n\n\tclient := testpb.NewTestServiceClient(cc)\n\tstream, _ := client.PingList(ctx, &testpb.PingListRequest{}, WithMax(3))\n\n\tfor {\n\t\t_, err := stream.Recv() // retries happen here\n\t\tif errors.Is(err, io.EOF) {\n\t\t\tbreak\n\t\t} else if err != nil {\n\t\t\treturn\n\t\t}\n\t}\n}\n\n// This is an example of an `Unary` call that will also retry on deadlines.\n//\n// Because the passed in context has a `5s` timeout, the whole `Ping` invocation should finish\n// within that time. However, by default all retried calls will use the parent context for their\n// deadlines. This means, that unless you shorten the deadline of each call of the retry, you won't\n// be able to retry the first call at all.\n//\n// `WithPerRetryTimeout` allows you to shorten the deadline of each retry call, allowing you to fit\n// multiple retries in the single parent deadline.\nfunc ExampleWithPerRetryTimeout() {\n\tctx, cancel := context.WithTimeout(context.TODO(), 5*time.Second)\n\tdefer cancel()\n\n\tclient := testpb.NewTestServiceClient(cc)\n\t_, _ = client.Ping(\n\t\tctx,\n\t\t&testpb.PingRequest{},\n\t\tWithMax(3),\n\t\tWithPerRetryTimeout(1*time.Second))\n}\n\n// Scale duration by a factor.\nfunc scaleDuration(d time.Duration, factor float64) time.Duration {\n\treturn time.Duration(float64(d) * factor)\n}\n"
  },
  {
    "path": "interceptors/retry/options.go",
    "content": "// Copyright (c) The go-grpc-middleware Authors.\n// Licensed under the Apache License 2.0.\n\npackage retry\n\nimport (\n\t\"context\"\n\t\"time\"\n\n\t\"google.golang.org/grpc\"\n\t\"google.golang.org/grpc/codes\"\n\t\"google.golang.org/grpc/status\"\n)\n\nvar (\n\t// DefaultRetriableCodes is a set of well known types gRPC codes that should be retri-able.\n\t//\n\t// `ResourceExhausted` means that the user quota, e.g. per-RPC limits, have been reached.\n\t// `Unavailable` means that system is currently unavailable and the client should retry again.\n\tDefaultRetriableCodes = []codes.Code{codes.ResourceExhausted, codes.Unavailable}\n\n\tdefaultOptions = &options{\n\t\tmax:            0, // disabled\n\t\tperCallTimeout: 0, // disabled\n\t\tincludeHeader:  true,\n\t\tbackoffFunc:    BackoffLinearWithJitter(50*time.Millisecond /*jitter*/, 0.10),\n\t\tonRetryCallback: OnRetryCallback(func(ctx context.Context, attempt uint, err error) {\n\t\t\tlogTrace(ctx, \"grpc_retry attempt: %d, backoff for %v\", attempt, err)\n\t\t}),\n\t\tretriableFunc: newRetriableFuncForCodes(DefaultRetriableCodes),\n\t}\n)\n\n// BackoffFunc denotes a family of functions that control the backoff duration between call retries.\n//\n// They are called with an identifier of the attempt, and should return a time the system client should\n// hold off for. If the time returned is longer than the `context.Context.Deadline` of the request\n// the deadline of the request takes precedence and the wait will be interrupted before proceeding\n// with the next iteration. The context can be used to extract request scoped metadata and context values.\ntype BackoffFunc func(ctx context.Context, attempt uint) time.Duration\n\n// OnRetryCallback is the type of function called when a retry occurs.\ntype OnRetryCallback func(ctx context.Context, attempt uint, err error)\n\n// RetriableFunc denotes a family of functions that control which error should be retried.\ntype RetriableFunc func(err error) bool\n\n// Disable disables the retry behaviour on this call, or this interceptor.\n//\n// Its semantically the same to `WithMax`\nfunc Disable() CallOption {\n\treturn WithMax(0)\n}\n\n// WithMax sets the maximum number of retries on this call, or this interceptor.\nfunc WithMax(maxRetries uint) CallOption {\n\treturn CallOption{applyFunc: func(o *options) {\n\t\to.max = maxRetries\n\t}}\n}\n\n// WithBackoff sets the `BackoffFunc` used to control time between retries.\nfunc WithBackoff(bf BackoffFunc) CallOption {\n\treturn CallOption{applyFunc: func(o *options) {\n\t\to.backoffFunc = bf\n\t}}\n}\n\n// WithOnRetryCallback sets the callback to use when a retry occurs.\n//\n// By default, when no callback function provided, we will just print a log to trace\nfunc WithOnRetryCallback(fn OnRetryCallback) CallOption {\n\treturn CallOption{applyFunc: func(o *options) {\n\t\to.onRetryCallback = fn\n\t}}\n}\n\n// WithCodes sets which codes should be retried.\n//\n// Please *use with care*, as you may be retrying non-idempotent calls.\n//\n// You cannot automatically retry on Cancelled and Deadline, please use `WithPerRetryTimeout` for these.\nfunc WithCodes(retryCodes ...codes.Code) CallOption {\n\treturn CallOption{applyFunc: func(o *options) {\n\t\to.retriableFunc = newRetriableFuncForCodes(retryCodes)\n\t}}\n}\n\n// WithPerRetryTimeout sets the RPC timeout per call (including initial call) on this call, or this interceptor.\n//\n// The context.Deadline of the call takes precedence and sets the maximum time the whole invocation\n// will take, but WithPerRetryTimeout can be used to limit the RPC time per each call.\n//\n// For example, with context.Deadline = now + 10s, and WithPerRetryTimeout(3 * time.Seconds), each\n// of the retry calls (including the initial one) will have a deadline of now + 3s.\n//\n// A value of 0 disables the timeout overrides completely and returns to each retry call using the\n// parent `context.Deadline`.\n//\n// Note that when this is enabled, any DeadlineExceeded errors that are propagated up will be retried.\nfunc WithPerRetryTimeout(timeout time.Duration) CallOption {\n\treturn CallOption{applyFunc: func(o *options) {\n\t\to.perCallTimeout = timeout\n\t}}\n}\n\n// WithRetriable sets which error should be retried.\nfunc WithRetriable(retriableFunc RetriableFunc) CallOption {\n\treturn CallOption{applyFunc: func(o *options) {\n\t\to.retriableFunc = retriableFunc\n\t}}\n}\n\ntype options struct {\n\tmax             uint\n\tperCallTimeout  time.Duration\n\tincludeHeader   bool\n\tbackoffFunc     BackoffFunc\n\tonRetryCallback OnRetryCallback\n\tretriableFunc   RetriableFunc\n}\n\n// CallOption is a grpc.CallOption that is local to grpc_retry.\ntype CallOption struct {\n\tgrpc.EmptyCallOption // make sure we implement private after() and before() fields so we don't panic.\n\tapplyFunc            func(opt *options)\n}\n\nfunc reuseOrNewWithCallOptions(opt *options, callOptions []CallOption) *options {\n\tif len(callOptions) == 0 {\n\t\treturn opt\n\t}\n\toptCopy := &options{}\n\t*optCopy = *opt\n\tfor _, f := range callOptions {\n\t\tf.applyFunc(optCopy)\n\t}\n\treturn optCopy\n}\n\nfunc filterCallOptions(callOptions []grpc.CallOption) (grpcOptions []grpc.CallOption, retryOptions []CallOption) {\n\tfor _, opt := range callOptions {\n\t\tif co, ok := opt.(CallOption); ok {\n\t\t\tretryOptions = append(retryOptions, co)\n\t\t} else {\n\t\t\tgrpcOptions = append(grpcOptions, opt)\n\t\t}\n\t}\n\treturn grpcOptions, retryOptions\n}\n\n// newRetriableFuncForCodes returns retriable function for specific Codes.\nfunc newRetriableFuncForCodes(codes []codes.Code) func(err error) bool {\n\treturn func(err error) bool {\n\t\terrCode := status.Code(err)\n\t\tif isContextError(err) {\n\t\t\t// context errors are not retriable based on user settings.\n\t\t\treturn false\n\t\t}\n\t\tfor _, code := range codes {\n\t\t\tif code == errCode {\n\t\t\t\treturn true\n\t\t\t}\n\t\t}\n\t\treturn false\n\t}\n}\n"
  },
  {
    "path": "interceptors/retry/retry.go",
    "content": "// Copyright (c) The go-grpc-middleware Authors.\n// Licensed under the Apache License 2.0.\n\npackage retry\n\nimport (\n\t\"context\"\n\t\"errors\"\n\t\"fmt\"\n\t\"io\"\n\t\"sync\"\n\t\"time\"\n\n\t\"github.com/grpc-ecosystem/go-grpc-middleware/v2/metadata\"\n\t\"google.golang.org/grpc\"\n\t\"google.golang.org/grpc/codes\"\n\tgrpcMetadata \"google.golang.org/grpc/metadata\"\n\t\"google.golang.org/grpc/status\"\n)\n\nconst (\n\tAttemptMetadataKey = \"x-retry-attempt\"\n)\n\n// UnaryClientInterceptor returns a new retrying unary client interceptor.\n//\n// The default configuration of the interceptor is to not retry *at all*. This behaviour can be\n// changed through options (e.g. WithMax) on creation of the interceptor or on call (through grpc.CallOptions).\nfunc UnaryClientInterceptor(optFuncs ...CallOption) grpc.UnaryClientInterceptor {\n\tintOpts := reuseOrNewWithCallOptions(defaultOptions, optFuncs)\n\treturn func(parentCtx context.Context, method string, req, reply any, cc *grpc.ClientConn, invoker grpc.UnaryInvoker, opts ...grpc.CallOption) error {\n\t\tgrpcOpts, retryOpts := filterCallOptions(opts)\n\t\tcallOpts := reuseOrNewWithCallOptions(intOpts, retryOpts)\n\t\t// short circuit for simplicity, and avoiding allocations.\n\t\tif callOpts.max == 0 {\n\t\t\treturn invoker(parentCtx, method, req, reply, cc, grpcOpts...)\n\t\t}\n\t\tvar lastErr error\n\t\tfor attempt := uint(0); attempt < callOpts.max; attempt++ {\n\t\t\tif err := waitRetryBackoff(attempt, parentCtx, callOpts); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\tif attempt > 0 {\n\t\t\t\tcallOpts.onRetryCallback(parentCtx, attempt, lastErr)\n\t\t\t}\n\t\t\tcallCtx, cancel := perCallContext(parentCtx, callOpts, attempt)\n\t\t\tlastErr = invoker(callCtx, method, req, reply, cc, grpcOpts...)\n\t\t\t// Cancel the context immediately after invoking the next call in the chain to avoid\n\t\t\t// holing onto its memory until this function returns.\n\t\t\tcancel()\n\t\t\t// TODO(mwitkow): Maybe dial and transport errors should be retriable?\n\t\t\tif lastErr == nil {\n\t\t\t\treturn nil\n\t\t\t}\n\t\t\tif isContextError(lastErr) {\n\t\t\t\tif parentCtx.Err() != nil {\n\t\t\t\t\tlogTrace(parentCtx, \"grpc_retry attempt: %d, parent context error: %v\", attempt, parentCtx.Err())\n\t\t\t\t\t// its the parent context deadline or cancellation.\n\t\t\t\t\treturn lastErr\n\t\t\t\t} else if callOpts.perCallTimeout != 0 {\n\t\t\t\t\t// We have set a perCallTimeout in the retry middleware, which would result in a context error if\n\t\t\t\t\t// the deadline was exceeded, in which case try again.\n\t\t\t\t\tlogTrace(parentCtx, \"grpc_retry attempt: %d, context error from retry call\", attempt)\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t}\n\t\t\tif !isRetriable(lastErr, callOpts) {\n\t\t\t\treturn lastErr\n\t\t\t}\n\t\t}\n\t\treturn lastErr\n\t}\n}\n\n// StreamClientInterceptor returns a new retrying stream client interceptor for server side streaming calls.\n//\n// The default configuration of the interceptor is to not retry *at all*. This behaviour can be\n// changed through options (e.g. WithMax) on creation of the interceptor or on call (through grpc.CallOptions).\n//\n// Retry logic is available *only for ServerStreams*, i.e. 1:n streams, as the internal logic needs\n// to buffer the messages sent by the client. If retry is enabled on any other streams (ClientStreams,\n// BidiStreams), the retry interceptor will fail the call.\nfunc StreamClientInterceptor(optFuncs ...CallOption) grpc.StreamClientInterceptor {\n\tintOpts := reuseOrNewWithCallOptions(defaultOptions, optFuncs)\n\treturn func(parentCtx context.Context, desc *grpc.StreamDesc, cc *grpc.ClientConn, method string, streamer grpc.Streamer, opts ...grpc.CallOption) (grpc.ClientStream, error) {\n\t\tgrpcOpts, retryOpts := filterCallOptions(opts)\n\t\tcallOpts := reuseOrNewWithCallOptions(intOpts, retryOpts)\n\t\t// short circuit for simplicity, and avoiding allocations.\n\t\tif callOpts.max == 0 {\n\t\t\treturn streamer(parentCtx, desc, cc, method, grpcOpts...)\n\t\t}\n\t\tif desc.ClientStreams {\n\t\t\treturn nil, status.Error(codes.Unimplemented, \"grpc_retry: cannot retry on ClientStreams, set grpc_retry.Disable()\")\n\t\t}\n\n\t\tvar lastErr error\n\t\tfor attempt := uint(0); attempt < callOpts.max; attempt++ {\n\t\t\tif err := waitRetryBackoff(attempt, parentCtx, callOpts); err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\tif attempt > 0 {\n\t\t\t\tcallOpts.onRetryCallback(parentCtx, attempt, lastErr)\n\t\t\t}\n\t\t\tvar newStreamer grpc.ClientStream\n\t\t\tnewStreamer, lastErr = streamer(perStreamContext(parentCtx, callOpts, attempt), desc, cc, method, grpcOpts...)\n\t\t\tif lastErr == nil {\n\t\t\t\tretryingStreamer := &serverStreamingRetryingStream{\n\t\t\t\t\tClientStream: newStreamer,\n\t\t\t\t\tcallOpts:     callOpts,\n\t\t\t\t\tparentCtx:    parentCtx,\n\t\t\t\t\tstreamerCall: func(ctx context.Context) (grpc.ClientStream, error) {\n\t\t\t\t\t\tattempt++\n\t\t\t\t\t\treturn streamer(perStreamContext(ctx, callOpts, attempt), desc, cc, method, grpcOpts...)\n\t\t\t\t\t},\n\t\t\t\t}\n\t\t\t\treturn retryingStreamer, nil\n\t\t\t}\n\t\t\tif isContextError(lastErr) {\n\t\t\t\tif parentCtx.Err() != nil {\n\t\t\t\t\tlogTrace(parentCtx, \"grpc_retry attempt: %d, parent context error: %v\", attempt, parentCtx.Err())\n\t\t\t\t\t// its the parent context deadline or cancellation.\n\t\t\t\t\treturn nil, lastErr\n\t\t\t\t} else if callOpts.perCallTimeout != 0 {\n\t\t\t\t\t// We have set a perCallTimeout in the retry middleware, which would result in a context error if\n\t\t\t\t\t// the deadline was exceeded, in which case try again.\n\t\t\t\t\tlogTrace(parentCtx, \"grpc_retry attempt: %d, context error from retry call\", attempt)\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t}\n\t\t\tif !isRetriable(lastErr, callOpts) {\n\t\t\t\treturn nil, lastErr\n\t\t\t}\n\t\t}\n\t\treturn nil, lastErr\n\t}\n}\n\n// type serverStreamingRetryingStream is the implementation of grpc.ClientStream that acts as a\n// proxy to the underlying call. If any of the RecvMsg() calls fail, it will try to reestablish\n// a new ClientStream according to the retry policy.\ntype serverStreamingRetryingStream struct {\n\tgrpc.ClientStream\n\tbufferedSends []any // single message that the client can sen\n\twasClosedSend bool  // indicates that CloseSend was closed\n\tparentCtx     context.Context\n\tcallOpts      *options\n\tstreamerCall  func(ctx context.Context) (grpc.ClientStream, error)\n\tmu            sync.RWMutex\n}\n\nfunc (s *serverStreamingRetryingStream) setStream(clientStream grpc.ClientStream) {\n\ts.mu.Lock()\n\ts.ClientStream = clientStream\n\ts.mu.Unlock()\n}\n\nfunc (s *serverStreamingRetryingStream) getStream() grpc.ClientStream {\n\ts.mu.RLock()\n\tdefer s.mu.RUnlock()\n\treturn s.ClientStream\n}\n\nfunc (s *serverStreamingRetryingStream) SendMsg(m any) error {\n\ts.mu.Lock()\n\ts.bufferedSends = append(s.bufferedSends, m)\n\ts.mu.Unlock()\n\treturn s.getStream().SendMsg(m)\n}\n\nfunc (s *serverStreamingRetryingStream) CloseSend() error {\n\ts.mu.Lock()\n\ts.wasClosedSend = true\n\ts.mu.Unlock()\n\treturn s.getStream().CloseSend()\n}\n\nfunc (s *serverStreamingRetryingStream) Header() (grpcMetadata.MD, error) {\n\treturn s.getStream().Header()\n}\n\nfunc (s *serverStreamingRetryingStream) Trailer() grpcMetadata.MD {\n\treturn s.getStream().Trailer()\n}\n\nfunc (s *serverStreamingRetryingStream) RecvMsg(m any) error {\n\tattemptRetry, lastErr := s.receiveMsgAndIndicateRetry(m)\n\tif !attemptRetry {\n\t\treturn lastErr // success or hard failure\n\t}\n\t// We start off from attempt 1, because zeroth was already made on normal SendMsg().\n\tfor attempt := uint(1); attempt < s.callOpts.max; attempt++ {\n\t\tif err := waitRetryBackoff(attempt, s.parentCtx, s.callOpts); err != nil {\n\t\t\treturn err\n\t\t}\n\t\ts.callOpts.onRetryCallback(s.parentCtx, attempt, lastErr)\n\t\tnewStream, err := s.reestablishStreamAndResendBuffer(s.parentCtx)\n\t\tif err != nil {\n\t\t\t// Retry dial and transport errors of establishing stream as grpc doesn't retry.\n\t\t\tif isRetriable(err, s.callOpts) {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\treturn err\n\t\t}\n\n\t\ts.setStream(newStream)\n\t\tattemptRetry, lastErr = s.receiveMsgAndIndicateRetry(m)\n\n\t\tif !attemptRetry {\n\t\t\treturn lastErr\n\t\t}\n\t}\n\treturn lastErr\n}\n\nfunc (s *serverStreamingRetryingStream) receiveMsgAndIndicateRetry(m any) (bool, error) {\n\terr := s.getStream().RecvMsg(m)\n\tif err == nil || errors.Is(err, io.EOF) {\n\t\treturn false, err\n\t}\n\tif isContextError(err) {\n\t\tif s.parentCtx.Err() != nil {\n\t\t\tlogTrace(s.parentCtx, \"grpc_retry parent context error: %v\", s.parentCtx.Err())\n\t\t\treturn false, err\n\t\t} else if s.callOpts.perCallTimeout != 0 {\n\t\t\t// We have set a perCallTimeout in the retry middleware, which would result in a context error if\n\t\t\t// the deadline was exceeded, in which case try again.\n\t\t\tlogTrace(s.parentCtx, \"grpc_retry context error from retry call\")\n\t\t\treturn true, err\n\t\t}\n\t}\n\treturn isRetriable(err, s.callOpts), err\n}\n\nfunc (s *serverStreamingRetryingStream) reestablishStreamAndResendBuffer(callCtx context.Context) (grpc.ClientStream, error) {\n\ts.mu.RLock()\n\tbufferedSends := s.bufferedSends\n\ts.mu.RUnlock()\n\tnewStream, err := s.streamerCall(callCtx)\n\tif err != nil {\n\t\tlogTrace(callCtx, \"grpc_retry failed redialing new stream: %v\", err)\n\t\treturn nil, err\n\t}\n\tfor _, msg := range bufferedSends {\n\t\tif err := newStream.SendMsg(msg); err != nil {\n\t\t\tlogTrace(callCtx, \"grpc_retry failed resending message: %v\", err)\n\t\t\treturn nil, err\n\t\t}\n\t}\n\tif err := newStream.CloseSend(); err != nil {\n\t\tlogTrace(callCtx, \"grpc_retry failed CloseSend on new stream %v\", err)\n\t\treturn nil, err\n\t}\n\treturn newStream, nil\n}\n\nfunc waitRetryBackoff(attempt uint, parentCtx context.Context, callOpts *options) error {\n\tvar waitTime time.Duration = 0\n\tif attempt > 0 {\n\t\twaitTime = callOpts.backoffFunc(parentCtx, attempt)\n\t}\n\tif waitTime > 0 {\n\t\tlogTrace(parentCtx, \"grpc_retry attempt: %d, backoff for %v\", attempt, waitTime)\n\t\ttimer := time.NewTimer(waitTime)\n\t\tselect {\n\t\tcase <-parentCtx.Done():\n\t\t\tif !timer.Stop() {\n\t\t\t\t<-timer.C\n\t\t\t}\n\t\t\treturn contextErrToGrpcErr(parentCtx.Err())\n\t\tcase <-timer.C:\n\t\t}\n\t}\n\treturn nil\n}\n\nfunc isRetriable(err error, callOpts *options) bool {\n\tif callOpts.retriableFunc != nil {\n\t\treturn callOpts.retriableFunc(err)\n\t}\n\treturn false\n}\n\nfunc isContextError(err error) bool {\n\tcode := status.Code(err)\n\treturn code == codes.DeadlineExceeded || code == codes.Canceled\n}\n\nfunc perCallContext(parentCtx context.Context, callOpts *options, attempt uint) (context.Context, context.CancelFunc) {\n\tcancel := context.CancelFunc(func() {})\n\n\tctx := parentCtx\n\tif callOpts.perCallTimeout != 0 {\n\t\tctx, cancel = context.WithTimeout(ctx, callOpts.perCallTimeout)\n\t}\n\tif attempt > 0 && callOpts.includeHeader {\n\t\tmdClone := metadata.ExtractOutgoing(ctx).Clone().Set(AttemptMetadataKey, fmt.Sprintf(\"%d\", attempt))\n\t\tctx = mdClone.ToOutgoing(ctx)\n\t}\n\treturn ctx, cancel\n}\n\nfunc perStreamContext(parentCtx context.Context, callOpts *options, attempt uint) context.Context {\n\tctx := parentCtx\n\tif attempt > 0 && callOpts.includeHeader {\n\t\tmdClone := metadata.ExtractOutgoing(ctx).Clone().Set(AttemptMetadataKey, fmt.Sprintf(\"%d\", attempt))\n\t\tctx = mdClone.ToOutgoing(ctx)\n\t}\n\treturn ctx\n}\n\nfunc contextErrToGrpcErr(err error) error {\n\tswitch {\n\tcase errors.Is(err, context.DeadlineExceeded):\n\t\treturn status.Error(codes.DeadlineExceeded, err.Error())\n\tcase errors.Is(err, context.Canceled):\n\t\treturn status.Error(codes.Canceled, err.Error())\n\tdefault:\n\t\treturn status.Error(codes.Unknown, err.Error())\n\t}\n}\n\nfunc logTrace(ctx context.Context, format string, a ...any) {\n\ttr, ok := traceFromCtx(ctx)\n\tif !ok {\n\t\treturn\n\t}\n\ttr.LazyPrintf(format, a...)\n}\n"
  },
  {
    "path": "interceptors/retry/retry_test.go",
    "content": "// Copyright (c) The go-grpc-middleware Authors.\n// Licensed under the Apache License 2.0.\n\npackage retry\n\nimport (\n\t\"context\"\n\t\"errors\"\n\t\"io\"\n\t\"strconv\"\n\t\"strings\"\n\t\"sync\"\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/grpc-ecosystem/go-grpc-middleware/v2/testing/testpb\"\n\t\"github.com/stretchr/testify/assert\"\n\t\"github.com/stretchr/testify/require\"\n\t\"github.com/stretchr/testify/suite\"\n\t\"google.golang.org/grpc\"\n\t\"google.golang.org/grpc/codes\"\n\t\"google.golang.org/grpc/metadata\"\n\t\"google.golang.org/grpc/status\"\n)\n\nvar (\n\tretriableErrors = []codes.Code{codes.Unavailable, codes.DataLoss}\n\tnoSleep         = 0 * time.Second\n\tretryTimeout    = 50 * time.Millisecond\n)\n\ntype failingService struct {\n\ttestpb.TestServiceServer\n\tmu sync.Mutex\n\n\treqCounter uint\n\treqModulo  uint\n\treqSleep   time.Duration\n\treqError   codes.Code\n}\n\nfunc (s *failingService) resetFailingConfiguration(modulo uint, errorCode codes.Code, sleepTime time.Duration) {\n\ts.mu.Lock()\n\tdefer s.mu.Unlock()\n\n\ts.reqCounter = 0\n\ts.reqModulo = modulo\n\ts.reqError = errorCode\n\ts.reqSleep = sleepTime\n}\n\nfunc (s *failingService) requestCount() uint {\n\ts.mu.Lock()\n\tdefer s.mu.Unlock()\n\treturn s.reqCounter\n}\n\nfunc (s *failingService) maybeFailRequest() error {\n\ts.mu.Lock()\n\ts.reqCounter += 1\n\treqModulo := s.reqModulo\n\treqCounter := s.reqCounter\n\treqSleep := s.reqSleep\n\treqError := s.reqError\n\ts.mu.Unlock()\n\tif (reqModulo > 0) && (reqCounter%reqModulo == 0) {\n\t\treturn nil\n\t}\n\ttime.Sleep(reqSleep)\n\treturn status.Error(reqError, \"maybeFailRequest: failing it\")\n}\n\nfunc (s *failingService) Ping(ctx context.Context, ping *testpb.PingRequest) (*testpb.PingResponse, error) {\n\tif err := s.maybeFailRequest(); err != nil {\n\t\treturn nil, err\n\t}\n\treturn s.TestServiceServer.Ping(ctx, ping)\n}\n\nfunc (s *failingService) PingList(ping *testpb.PingListRequest, stream testpb.TestService_PingListServer) error {\n\tif err := s.maybeFailRequest(); err != nil {\n\t\treturn err\n\t}\n\treturn s.TestServiceServer.PingList(ping, stream)\n}\n\nfunc (s *failingService) PingStream(stream testpb.TestService_PingStreamServer) error {\n\tif err := s.maybeFailRequest(); err != nil {\n\t\treturn err\n\t}\n\treturn s.TestServiceServer.PingStream(stream)\n}\n\nfunc TestRetrySuite(t *testing.T) {\n\tservice := &failingService{\n\t\tTestServiceServer: &testpb.TestPingService{},\n\t}\n\tunaryInterceptor := UnaryClientInterceptor(\n\t\tWithCodes(retriableErrors...),\n\t\tWithMax(3),\n\t\tWithBackoff(BackoffLinear(retryTimeout)),\n\t)\n\tstreamInterceptor := StreamClientInterceptor(\n\t\tWithCodes(retriableErrors...),\n\t\tWithMax(3),\n\t\tWithBackoff(BackoffLinear(retryTimeout)),\n\t)\n\ts := &RetrySuite{\n\t\tsrv: service,\n\t\tInterceptorTestSuite: &testpb.InterceptorTestSuite{\n\t\t\tTestService: service,\n\t\t\tClientOpts: []grpc.DialOption{\n\t\t\t\tgrpc.WithStreamInterceptor(streamInterceptor),\n\t\t\t\tgrpc.WithUnaryInterceptor(unaryInterceptor),\n\t\t\t},\n\t\t},\n\t}\n\tsuite.Run(t, s)\n}\n\ntype RetrySuite struct {\n\t*testpb.InterceptorTestSuite\n\tsrv *failingService\n}\n\nfunc (s *RetrySuite) SetupTest() {\n\ts.srv.resetFailingConfiguration( /* don't fail */ 0, codes.OK, noSleep)\n}\n\nfunc (s *RetrySuite) TestUnary_FailsOnNonRetriableError() {\n\ts.srv.resetFailingConfiguration(5, codes.Internal, noSleep)\n\t_, err := s.Client.Ping(s.SimpleCtx(), testpb.GoodPing)\n\ts.Require().Error(err, \"error must occur from the failing service\")\n\ts.Require().Equal(codes.Internal, status.Code(err), \"failure code must come from retrier\")\n\ts.Require().EqualValues(1, s.srv.requestCount(), \"one request should have been made\")\n}\n\nfunc (s *RetrySuite) TestUnary_FailsOnNonRetriableContextError() {\n\ts.srv.resetFailingConfiguration(5, codes.Canceled, noSleep)\n\t_, err := s.Client.Ping(s.SimpleCtx(), testpb.GoodPing)\n\ts.Require().Error(err, \"error must occur from the failing service\")\n\ts.Require().Equal(codes.Canceled, status.Code(err), \"failure code must come from retrier\")\n\ts.Require().EqualValues(1, s.srv.requestCount(), \"one request should have been made\")\n}\n\nfunc (s *RetrySuite) TestCallOptionsDontPanicWithoutInterceptor() {\n\t// Fix for https://github.com/grpc-ecosystem/go-grpc-middleware/issues/37\n\t// If this code doesn't panic, that's good.\n\ts.srv.resetFailingConfiguration(100, codes.DataLoss, noSleep) // doesn't matter all requests should fail\n\tnonMiddlewareClient := s.NewClient()\n\t_, err := nonMiddlewareClient.Ping(s.SimpleCtx(), testpb.GoodPing,\n\t\tWithMax(5),\n\t\tWithBackoff(BackoffLinear(1*time.Millisecond)),\n\t\tWithCodes(codes.DataLoss),\n\t\tWithPerRetryTimeout(1*time.Millisecond),\n\t)\n\ts.Require().Error(err)\n}\n\nfunc (s *RetrySuite) TestServerStream_FailsOnNonRetriableError() {\n\ts.srv.resetFailingConfiguration(5, codes.Internal, noSleep)\n\tstream, err := s.Client.PingList(s.SimpleCtx(), testpb.GoodPingList)\n\ts.Require().NoError(err, \"should not fail on establishing the stream\")\n\t_, err = stream.Recv()\n\ts.Require().Error(err, \"error must occur from the failing service\")\n\ts.Require().Equal(codes.Internal, status.Code(err), \"failure code must come from retrier\")\n}\n\nfunc (s *RetrySuite) TestUnary_SucceedsOnRetriableError() {\n\ts.srv.resetFailingConfiguration(3, codes.DataLoss, noSleep) // see retriable_errors\n\tout, err := s.Client.Ping(s.SimpleCtx(), testpb.GoodPing)\n\ts.Require().NoError(err, \"the third invocation should succeed\")\n\ts.Require().NotNil(out, \"Pong must be not nil\")\n\ts.Require().EqualValues(3, s.srv.requestCount(), \"three requests should have been made\")\n}\n\nfunc (s *RetrySuite) TestUnary_OverrideFromDialOpts() {\n\ts.srv.resetFailingConfiguration(5, codes.ResourceExhausted, noSleep) // default is 3 and retriable_errors\n\tout, err := s.Client.Ping(s.SimpleCtx(), testpb.GoodPing, WithCodes(codes.ResourceExhausted), WithMax(5))\n\ts.Require().NoError(err, \"the fifth invocation should succeed\")\n\ts.Require().NotNil(out, \"Pong must be not nil\")\n\ts.Require().EqualValues(5, s.srv.requestCount(), \"five requests should have been made\")\n}\n\nfunc (s *RetrySuite) TestUnary_OverrideFromDialOpts2() {\n\ts.srv.resetFailingConfiguration(5, codes.ResourceExhausted, noSleep) // default is 3 and retriable_errors\n\tout, err := s.Client.Ping(s.SimpleCtx(), testpb.GoodPing, WithRetriable(func(err error) bool {\n\t\treturn strings.Contains(err.Error(), \"maybeFailRequest\")\n\t}), WithMax(5))\n\ts.Require().NoError(err, \"the fifth invocation should succeed\")\n\ts.Require().NotNil(out, \"Pong must be not nil\")\n\ts.Require().EqualValues(5, s.srv.requestCount(), \"five requests should have been made\")\n}\n\nfunc (s *RetrySuite) TestUnary_OnRetryCallbackCalled() {\n\tretryCallbackCount := 0\n\n\ts.srv.resetFailingConfiguration(3, codes.Unavailable, noSleep) // see retriable_errors\n\tout, err := s.Client.Ping(s.SimpleCtx(), testpb.GoodPing,\n\t\tWithOnRetryCallback(func(ctx context.Context, attempt uint, err error) {\n\t\t\tretryCallbackCount++\n\t\t}),\n\t)\n\n\ts.Require().NoError(err, \"the third invocation should succeed\")\n\ts.Require().NotNil(out, \"Pong must be not nil\")\n\ts.Require().Equal(2, retryCallbackCount, \"two retry callbacks should be called\")\n}\n\nfunc (s *RetrySuite) TestUnary_OnRetryCallbackNotCalledOnNonRetriableError() {\n\tretryCallbackCount := 0\n\n\ts.srv.resetFailingConfiguration(3, codes.Internal, noSleep) // see retriable_errors\n\tout, err := s.Client.Ping(s.SimpleCtx(), testpb.GoodPing,\n\t\tWithOnRetryCallback(func(ctx context.Context, attempt uint, err error) {\n\t\t\tretryCallbackCount++\n\t\t}),\n\t)\n\n\ts.Require().Error(err, \"should result in an error\")\n\ts.Require().Nil(out, \"out should be nil\")\n\ts.Require().Equal(0, retryCallbackCount, \"no retry callbacks should be called\")\n}\n\nfunc (s *RetrySuite) TestServerStream_SucceedsOnRetriableError() {\n\ts.srv.resetFailingConfiguration(3, codes.DataLoss, noSleep) // see retriable_errors\n\tstream, err := s.Client.PingList(s.SimpleCtx(), testpb.GoodPingList)\n\ts.Require().NoError(err, \"establishing the connection must always succeed\")\n\ts.assertPingListWasCorrect(stream)\n\ts.Require().EqualValues(3, s.srv.requestCount(), \"three requests should have been made\")\n}\n\nfunc (s *RetrySuite) TestServerStream_OverrideFromContext() {\n\ts.srv.resetFailingConfiguration(5, codes.ResourceExhausted, noSleep) // default is 3 and retriable_errors\n\tstream, err := s.Client.PingList(s.SimpleCtx(), testpb.GoodPingList, WithCodes(codes.ResourceExhausted), WithMax(5))\n\ts.Require().NoError(err, \"establishing the connection must always succeed\")\n\ts.assertPingListWasCorrect(stream)\n\ts.Require().EqualValues(5, s.srv.requestCount(), \"three requests should have been made\")\n}\n\nfunc (s *RetrySuite) TestServerStream_OverrideFromContext2() {\n\ts.srv.resetFailingConfiguration(5, codes.ResourceExhausted, noSleep) // default is 3 and retriable_errors\n\tstream, err := s.Client.PingList(s.SimpleCtx(), testpb.GoodPingList, WithRetriable(func(err error) bool {\n\t\treturn strings.Contains(err.Error(), \"maybeFailRequest\")\n\t}), WithMax(5))\n\ts.Require().NoError(err, \"establishing the connection must always succeed\")\n\ts.assertPingListWasCorrect(stream)\n\ts.Require().EqualValues(5, s.srv.requestCount(), \"three requests should have been made\")\n}\n\nfunc (s *RetrySuite) TestServerStream_OnRetryCallbackCalled() {\n\tretryCallbackCount := 0\n\n\ts.srv.resetFailingConfiguration(3, codes.Unavailable, noSleep) // see retriable_errors\n\tstream, err := s.Client.PingList(s.SimpleCtx(), testpb.GoodPingList,\n\t\tWithOnRetryCallback(func(ctx context.Context, attempt uint, err error) {\n\t\t\tretryCallbackCount++\n\t\t}),\n\t)\n\n\ts.Require().NoError(err, \"establishing the connection must always succeed\")\n\ts.assertPingListWasCorrect(stream)\n\ts.Require().Equal(2, retryCallbackCount, \"two retry callbacks should be called\")\n}\n\nfunc (s *RetrySuite) TestServerStream_CallFailsOnOutOfRetries() {\n\trestarted := s.RestartServer(3 * retryTimeout)\n\t_, err := s.Client.PingList(s.SimpleCtx(), testpb.GoodPingList)\n\n\ts.Require().Error(err, \"establishing the connection should not succeed\")\n\ts.Assert().Equal(codes.Unavailable, status.Code(err))\n\n\t<-restarted\n}\n\nfunc (s *RetrySuite) TestServerStream_CallFailsOnDeadlineExceeded() {\n\trestarted := s.RestartServer(3 * retryTimeout)\n\tctx, cancel := context.WithTimeout(context.TODO(), retryTimeout)\n\tdefer cancel()\n\t_, err := s.Client.PingList(ctx, testpb.GoodPingList)\n\n\ts.Require().Error(err, \"establishing the connection should not succeed\")\n\ts.Assert().Equal(codes.DeadlineExceeded, status.Code(err))\n\n\t<-restarted\n}\n\nfunc (s *RetrySuite) TestServerStream_CallRetrySucceeds() {\n\trestarted := s.RestartServer(retryTimeout)\n\n\t_, err := s.Client.PingList(s.SimpleCtx(), testpb.GoodPingList,\n\t\tWithMax(40),\n\t)\n\n\ts.Assert().NoError(err, \"establishing the connection should succeed\")\n\t<-restarted\n}\n\nfunc (s *RetrySuite) assertPingListWasCorrect(stream testpb.TestService_PingListClient) {\n\ts.T().Helper()\n\n\tcount := 0\n\tfor {\n\t\tpong, err := stream.Recv()\n\t\tif errors.Is(err, io.EOF) {\n\t\t\tbreak\n\t\t}\n\t\ts.Require().NoError(err, \"no errors during receive on client side\")\n\t\ts.Require().NotNil(pong, \"received values must not be nil\")\n\t\ts.Require().Equal(testpb.GoodPingList.Value, pong.Value, \"the returned pong contained the outgoing ping\")\n\t\tcount += 1\n\t}\n\ts.Require().Equal(testpb.ListResponseCount, count, \"should have received all ping items\")\n}\n\ntype trackedInterceptor struct {\n\tcalled int\n}\n\nfunc (ti *trackedInterceptor) UnaryClientInterceptor(ctx context.Context, method string, req, reply any, cc *grpc.ClientConn, invoker grpc.UnaryInvoker, opts ...grpc.CallOption) error {\n\tti.called++\n\treturn invoker(ctx, method, req, reply, cc, opts...)\n}\n\nfunc (ti *trackedInterceptor) StreamClientInterceptor(ctx context.Context, desc *grpc.StreamDesc, cc *grpc.ClientConn, method string, streamer grpc.Streamer, opts ...grpc.CallOption) (grpc.ClientStream, error) {\n\tti.called++\n\treturn streamer(ctx, desc, cc, method, opts...)\n}\n\nfunc TestChainedRetrySuite(t *testing.T) {\n\tservice := &failingService{\n\t\tTestServiceServer: &testpb.TestPingService{},\n\t}\n\tpreRetryInterceptor := &trackedInterceptor{}\n\tpostRetryInterceptor := &trackedInterceptor{}\n\ts := &ChainedRetrySuite{\n\t\tsrv:                  service,\n\t\tpreRetryInterceptor:  preRetryInterceptor,\n\t\tpostRetryInterceptor: postRetryInterceptor,\n\t\tInterceptorTestSuite: &testpb.InterceptorTestSuite{\n\t\t\tTestService: service,\n\t\t\tClientOpts: []grpc.DialOption{\n\t\t\t\tgrpc.WithChainUnaryInterceptor(\n\t\t\t\t\tpreRetryInterceptor.UnaryClientInterceptor,\n\t\t\t\t\tUnaryClientInterceptor(),\n\t\t\t\t\tpostRetryInterceptor.UnaryClientInterceptor,\n\t\t\t\t),\n\t\t\t\tgrpc.WithChainStreamInterceptor(\n\t\t\t\t\tpreRetryInterceptor.StreamClientInterceptor,\n\t\t\t\t\tStreamClientInterceptor(),\n\t\t\t\t\tpostRetryInterceptor.StreamClientInterceptor,\n\t\t\t\t),\n\t\t\t},\n\t\t},\n\t}\n\tsuite.Run(t, s)\n}\n\ntype ChainedRetrySuite struct {\n\t*testpb.InterceptorTestSuite\n\tsrv                  *failingService\n\tpreRetryInterceptor  *trackedInterceptor\n\tpostRetryInterceptor *trackedInterceptor\n}\n\nfunc (s *ChainedRetrySuite) SetupTest() {\n\ts.srv.resetFailingConfiguration( /* don't fail */ 0, codes.OK, noSleep)\n\ts.preRetryInterceptor.called = 0\n\ts.postRetryInterceptor.called = 0\n}\n\nfunc (s *ChainedRetrySuite) TestUnaryWithChainedInterceptors_NoFailure() {\n\t_, err := s.Client.Ping(s.SimpleCtx(), testpb.GoodPing, WithMax(2))\n\ts.Require().NoError(err, \"the invocation should succeed\")\n\ts.Require().EqualValues(1, s.srv.requestCount(), \"one request should have been made\")\n\ts.Require().Equal(1, s.preRetryInterceptor.called, \"pre-retry interceptor should be called once\")\n\ts.Require().Equal(1, s.postRetryInterceptor.called, \"post-retry interceptor should be called once\")\n}\n\nfunc (s *ChainedRetrySuite) TestUnaryWithChainedInterceptors_WithRetry() {\n\ts.srv.resetFailingConfiguration(2, codes.Unavailable, noSleep)\n\t_, err := s.Client.Ping(s.SimpleCtx(), testpb.GoodPing, WithMax(2))\n\ts.Require().NoError(err, \"the second invocation should succeed\")\n\ts.Require().EqualValues(2, s.srv.requestCount(), \"two requests should have been made\")\n\ts.Require().Equal(1, s.preRetryInterceptor.called, \"pre-retry interceptor should be called once\")\n\ts.Require().Equal(2, s.postRetryInterceptor.called, \"post-retry interceptor should be called twice\")\n}\n\nfunc (s *ChainedRetrySuite) TestStreamWithChainedInterceptors_NoFailure() {\n\tstream, err := s.Client.PingList(s.SimpleCtx(), testpb.GoodPingList, WithMax(2))\n\ts.Require().NoError(err, \"the invocation should succeed\")\n\t_, err = stream.Recv()\n\ts.Require().NoError(err, \"the Recv should succeed\")\n\ts.Require().EqualValues(1, s.srv.requestCount(), \"one request should have been made\")\n\ts.Require().Equal(1, s.preRetryInterceptor.called, \"pre-retry interceptor should be called once\")\n\ts.Require().Equal(1, s.postRetryInterceptor.called, \"post-retry interceptor should be called once\")\n}\n\nfunc (s *ChainedRetrySuite) TestStreamWithChainedInterceptors_WithRetry() {\n\ts.srv.resetFailingConfiguration(2, codes.Unavailable, noSleep)\n\tstream, err := s.Client.PingList(s.SimpleCtx(), testpb.GoodPingList, WithMax(2))\n\ts.Require().NoError(err, \"the second invocation should succeed\")\n\t_, err = stream.Recv()\n\ts.Require().NoError(err, \"the Recv should succeed\")\n\ts.Require().EqualValues(2, s.srv.requestCount(), \"two requests should have been made\")\n\ts.Require().Equal(1, s.preRetryInterceptor.called, \"pre-retry interceptor should be called once\")\n\ts.Require().Equal(2, s.postRetryInterceptor.called, \"post-retry interceptor should be called twice\")\n}\n\nfunc TestJitterUp(t *testing.T) {\n\t// Arguments to jitterup.\n\tduration := 10 * time.Second\n\tvariance := 0.10\n\n\t// Bound to check.\n\tmax := 11000 * time.Millisecond\n\tmin := 9000 * time.Millisecond\n\thigh := scaleDuration(max, 0.98)\n\tlow := scaleDuration(min, 1.02)\n\n\thighCount := 0\n\tlowCount := 0\n\n\tfor i := 0; i < 1000; i++ {\n\t\tout := jitterUp(duration, variance)\n\t\tassert.LessOrEqual(t, out, max, \"value %s must be <= %s\", out, max)\n\t\tassert.GreaterOrEqual(t, out, min, \"value %s must be >= %s\", out, min)\n\n\t\tif out > high {\n\t\t\thighCount++\n\t\t}\n\t\tif out < low {\n\t\t\tlowCount++\n\t\t}\n\t}\n\n\tassert.NotEqual(t, 0, highCount, \"at least one sample should reach to >%s\", high)\n\tassert.NotEqual(t, 0, lowCount, \"at least one sample should to <%s\", low)\n}\n\ntype failingClientStream struct {\n\tRecvMsgErr error\n}\n\nfunc (s *failingClientStream) Header() (metadata.MD, error) {\n\treturn nil, nil\n}\n\nfunc (s *failingClientStream) Trailer() metadata.MD {\n\treturn nil\n}\n\nfunc (s *failingClientStream) CloseSend() error {\n\treturn nil\n}\n\nfunc (s *failingClientStream) Context() context.Context {\n\treturn context.Background()\n}\n\nfunc (s *failingClientStream) SendMsg(m any) error {\n\treturn nil\n}\n\nfunc (s *failingClientStream) RecvMsg(m any) error {\n\treturn s.RecvMsgErr\n}\n\nfunc TestStreamClientInterceptorAttemptMetadata(t *testing.T) {\n\tretryCount := 5\n\tattempt := 0\n\trecvMsgErr := status.Error(codes.Unavailable, \"unavailable\")\n\n\tvar testStreamer grpc.Streamer = func(\n\t\tctx context.Context,\n\t\tdesc *grpc.StreamDesc,\n\t\tcc *grpc.ClientConn,\n\t\tmethod string,\n\t\topts ...grpc.CallOption,\n\t) (grpc.ClientStream, error) {\n\t\tif attempt > 0 {\n\t\t\tmd, ok := metadata.FromOutgoingContext(ctx)\n\t\t\trequire.True(t, ok)\n\n\t\t\traw := md.Get(AttemptMetadataKey)\n\t\t\trequire.Len(t, raw, 1)\n\n\t\t\tattemptMetadataValue, err := strconv.Atoi(raw[0])\n\t\t\trequire.NoError(t, err)\n\n\t\t\trequire.Equal(t, attempt, attemptMetadataValue)\n\t\t}\n\n\t\tattempt++\n\n\t\treturn &failingClientStream{\n\t\t\tRecvMsgErr: recvMsgErr,\n\t\t}, nil\n\t}\n\n\tstreamClientInterceptor := StreamClientInterceptor(WithCodes(codes.Unavailable), WithMax(uint(retryCount)))\n\tclientStream, err := streamClientInterceptor(context.Background(), &grpc.StreamDesc{}, nil, \"some_method\", testStreamer)\n\trequire.NoError(t, err)\n\n\terr = clientStream.RecvMsg(nil)\n\trequire.ErrorIs(t, err, recvMsgErr)\n\n\trequire.Equal(t, retryCount, attempt)\n}\n"
  },
  {
    "path": "interceptors/retry/trace_notrace.go",
    "content": "// Copyright (c) The go-grpc-middleware Authors.\n// Licensed under the Apache License 2.0.\n\n//go:build retrynotrace\n\npackage retry\n\n// retrynotrace can be used to avoid importing golang.org/x/net/trace,\n// which allows for more aggressive deadcode elimination, which can\n// yield improvements in binary size when tracing is not needed.\n\nimport (\n\t\"context\"\n\t\"fmt\"\n)\n\ntype notrace struct{}\n\nfunc (notrace) LazyLog(x fmt.Stringer, sensitive bool) {}\nfunc (notrace) LazyPrintf(format string, a ...any)     {}\nfunc (notrace) SetError()                              {}\nfunc (notrace) SetRecycler(f func(any))                {}\nfunc (notrace) SetTraceInfo(traceID, spanID uint64)    {}\nfunc (notrace) SetMaxEvents(m int)                     {}\nfunc (notrace) Finish()                                {}\n\nfunc traceFromCtx(ctx context.Context) (notrace, bool) {\n\treturn notrace{}, true\n}\n"
  },
  {
    "path": "interceptors/retry/trace_notrace_test.go",
    "content": "// Copyright (c) The go-grpc-middleware Authors.\n// Licensed under the Apache License 2.0.\n\n//go:build retrynotrace\n\npackage retry\n\nimport (\n\t\"context\"\n\t\"testing\"\n\n\t\"github.com/stretchr/testify/assert\"\n)\n\nfunc Test_traceFromCtx(t *testing.T) {\n\ttr := notrace{}\n\tctx := context.Background()\n\n\ttype args struct {\n\t\tctx context.Context\n\t}\n\ttests := []struct {\n\t\tname  string\n\t\targs  args\n\t\twant  notrace\n\t\twant1 bool\n\t}{\n\t\t{\n\t\t\tname:  \"should return notrace\",\n\t\t\targs:  args{ctx: ctx},\n\t\t\twant:  tr,\n\t\t\twant1: true,\n\t\t},\n\t}\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tgot, got1 := traceFromCtx(tt.args.ctx)\n\t\t\tassert.Equalf(t, tt.want, got, \"traceFromCtx(%v)\", tt.args.ctx)\n\t\t\tassert.Equalf(t, tt.want1, got1, \"traceFromCtx(%v)\", tt.args.ctx)\n\t\t})\n\t}\n}\n"
  },
  {
    "path": "interceptors/retry/trace_withtrace.go",
    "content": "// Copyright (c) The go-grpc-middleware Authors.\n// Licensed under the Apache License 2.0.\n\n//go:build !retrynotrace\n\npackage retry\n\nimport (\n\t\"context\"\n\n\tt \"golang.org/x/net/trace\"\n)\n\nfunc traceFromCtx(ctx context.Context) (t.Trace, bool) {\n\treturn t.FromContext(ctx)\n}\n"
  },
  {
    "path": "interceptors/retry/trace_withtrace_test.go",
    "content": "// Copyright (c) The go-grpc-middleware Authors.\n// Licensed under the Apache License 2.0.\n\n//go:build !retrynotrace\n\npackage retry\n\nimport (\n\t\"context\"\n\t\"testing\"\n\n\t\"github.com/stretchr/testify/assert\"\n\t\"golang.org/x/net/trace\"\n)\n\nfunc Test_traceFromCtx(t *testing.T) {\n\ttr := trace.New(\"test\", \"with trace\")\n\tctx := trace.NewContext(context.Background(), tr)\n\n\ttype args struct {\n\t\tctx context.Context\n\t}\n\ttests := []struct {\n\t\tname  string\n\t\targs  args\n\t\twant  trace.Trace\n\t\twant1 bool\n\t}{\n\t\t{\n\t\t\tname:  \"should return trace\",\n\t\t\targs:  args{ctx: ctx},\n\t\t\twant:  tr,\n\t\t\twant1: true,\n\t\t},\n\t\t{\n\t\t\tname:  \"should return false if trace not found in ctx\",\n\t\t\targs:  args{ctx: context.Background()},\n\t\t\twant:  nil,\n\t\t\twant1: false,\n\t\t},\n\t}\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tgot, got1 := traceFromCtx(tt.args.ctx)\n\t\t\tassert.Equalf(t, tt.want, got, \"traceFromCtx(%v)\", tt.args.ctx)\n\t\t\tassert.Equalf(t, tt.want1, got1, \"traceFromCtx(%v)\", tt.args.ctx)\n\t\t})\n\t}\n}\n"
  },
  {
    "path": "interceptors/selector/doc.go",
    "content": "// Copyright (c) The go-grpc-middleware Authors.\n// Licensed under the Apache License 2.0.\n\n/*\nPackage selector\n\n`selector` a generic server-side selector middleware for gRPC.\n\n# Server Side Selector Middleware\nIt allows to set check rules to allowlist or blocklist middleware such as Auth\ninterceptors to toggle behavior on or off based on the request path.\n\nPlease see examples for simple examples of use.\n*/\npackage selector\n"
  },
  {
    "path": "interceptors/selector/selector.go",
    "content": "// Copyright (c) The go-grpc-middleware Authors.\n// Licensed under the Apache License 2.0.\n\npackage selector\n\nimport (\n\t\"context\"\n\n\t\"github.com/grpc-ecosystem/go-grpc-middleware/v2/interceptors\"\n\t\"google.golang.org/grpc\"\n)\n\n// Matcher allows matching.\ntype Matcher interface {\n\t// Match returns true, if given context and gRPC call metadata like type, service and method are matching.\n\tMatch(ctx context.Context, callMeta interceptors.CallMeta) bool\n}\n\n// MatchFunc return Matcher from closure.\nfunc MatchFunc(f func(ctx context.Context, callMeta interceptors.CallMeta) bool) Matcher {\n\treturn funcSelector{f: f}\n}\n\ntype funcSelector struct {\n\tf func(ctx context.Context, callMeta interceptors.CallMeta) bool\n}\n\nfunc (s funcSelector) Match(ctx context.Context, callMeta interceptors.CallMeta) bool {\n\treturn s.f(ctx, callMeta)\n}\n\n// UnaryServerInterceptor returns a new unary server interceptor that will decide whether to call\n// the interceptor based on the return argument from the Matcher.\nfunc UnaryServerInterceptor(i grpc.UnaryServerInterceptor, matcher Matcher) grpc.UnaryServerInterceptor {\n\treturn func(ctx context.Context, req any, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (resp any, err error) {\n\t\tc := interceptors.NewServerCallMeta(info.FullMethod, nil, req)\n\t\tif matcher.Match(ctx, c) {\n\t\t\treturn i(ctx, req, info, handler)\n\t\t}\n\t\treturn handler(ctx, req)\n\t}\n}\n\n// StreamServerInterceptor returns a new stream server interceptor that will decide whether to call\n// the interceptor based on the return argument from the Matcher.\nfunc StreamServerInterceptor(i grpc.StreamServerInterceptor, matcher Matcher) grpc.StreamServerInterceptor {\n\treturn func(srv any, ss grpc.ServerStream, info *grpc.StreamServerInfo, handler grpc.StreamHandler) error {\n\t\tc := interceptors.NewServerCallMeta(info.FullMethod, info, nil)\n\t\tif matcher.Match(ss.Context(), c) {\n\t\t\treturn i(srv, ss, info, handler)\n\t\t}\n\t\treturn handler(srv, ss)\n\t}\n}\n\n// UnaryClientInterceptor returns a new unary client interceptor that will decide whether to call\n// the interceptor based on the return argument from the Matcher.\n// TODO(bwplotka): Write unit test.\nfunc UnaryClientInterceptor(i grpc.UnaryClientInterceptor, matcher Matcher) grpc.UnaryClientInterceptor {\n\treturn func(ctx context.Context, method string, req, reply any, cc *grpc.ClientConn, invoker grpc.UnaryInvoker, opts ...grpc.CallOption) error {\n\t\tc := interceptors.NewClientCallMeta(method, nil, req)\n\t\tif matcher.Match(ctx, c) {\n\t\t\treturn i(ctx, method, req, reply, cc, invoker, opts...)\n\t\t}\n\t\treturn invoker(ctx, method, req, reply, cc, opts...)\n\t}\n}\n\n// StreamClientInterceptor returns a new stream client interceptor that will decide whether to call\n// the interceptor based on the return argument from the Matcher.\n// TODO(bwplotka): Write unit test.\nfunc StreamClientInterceptor(i grpc.StreamClientInterceptor, matcher Matcher) grpc.StreamClientInterceptor {\n\treturn func(ctx context.Context, desc *grpc.StreamDesc, cc *grpc.ClientConn, method string, streamer grpc.Streamer, opts ...grpc.CallOption) (grpc.ClientStream, error) {\n\t\tc := interceptors.NewClientCallMeta(method, desc, nil)\n\t\tif matcher.Match(ctx, c) {\n\t\t\treturn i(ctx, desc, cc, method, streamer, opts...)\n\t\t}\n\t\treturn streamer(ctx, desc, cc, method, opts...)\n\t}\n}\n"
  },
  {
    "path": "interceptors/selector/selector_example_test.go",
    "content": "// Copyright (c) The go-grpc-middleware Authors.\n// Licensed under the Apache License 2.0.\n\npackage selector_test\n\nimport (\n\t\"context\"\n\n\t\"github.com/grpc-ecosystem/go-grpc-middleware/v2/interceptors\"\n\t\"github.com/grpc-ecosystem/go-grpc-middleware/v2/interceptors/auth\"\n\t\"github.com/grpc-ecosystem/go-grpc-middleware/v2/interceptors/logging\"\n\t\"github.com/grpc-ecosystem/go-grpc-middleware/v2/interceptors/ratelimit\"\n\t\"github.com/grpc-ecosystem/go-grpc-middleware/v2/interceptors/selector\"\n\t\"google.golang.org/grpc\"\n\t\"google.golang.org/grpc/codes\"\n\t\"google.golang.org/grpc/status\"\n)\n\n// alwaysPassLimiter is an example limiter which implements Limiter interface.\n// It does not limit any request because Limit function always returns false.\ntype alwaysPassLimiter struct{}\n\nfunc (*alwaysPassLimiter) Limit(_ context.Context) error {\n\treturn nil\n}\n\nfunc healthSkip(_ context.Context, c interceptors.CallMeta) bool {\n\treturn c.FullMethod() != \"/ping.v1.PingService/Health\"\n}\n\nfunc Example_ratelimit() {\n\tlimiter := &alwaysPassLimiter{}\n\t_ = grpc.NewServer(\n\t\tgrpc.ChainUnaryInterceptor(\n\t\t\tselector.UnaryServerInterceptor(ratelimit.UnaryServerInterceptor(limiter), selector.MatchFunc(healthSkip)),\n\t\t),\n\t\tgrpc.ChainStreamInterceptor(\n\t\t\tselector.StreamServerInterceptor(ratelimit.StreamServerInterceptor(limiter), selector.MatchFunc(healthSkip)),\n\t\t),\n\t)\n}\n\ntype tokenInfoKey struct{}\n\nfunc parseToken(token string) (struct{}, error) {\n\treturn struct{}{}, nil\n}\n\nfunc userClaimFromToken(struct{}) string {\n\treturn \"foobar\"\n}\n\n// exampleAuthFunc is used by a middleware to authenticate requests\nfunc exampleAuthFunc(ctx context.Context) (context.Context, error) {\n\ttoken, err := auth.AuthFromMD(ctx, \"bearer\")\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\ttokenInfo, err := parseToken(token)\n\tif err != nil {\n\t\treturn nil, status.Errorf(codes.Unauthenticated, \"invalid auth token: %v\", err)\n\t}\n\n\tctx = logging.InjectFields(ctx, logging.Fields{\"auth.sub\", userClaimFromToken(tokenInfo)})\n\n\t// WARNING: In production define your own type to avoid context collisions.\n\treturn context.WithValue(ctx, tokenInfoKey{}, tokenInfo), nil\n}\n\nfunc loginSkip(_ context.Context, c interceptors.CallMeta) bool {\n\treturn c.FullMethod() != \"/auth.v1.AuthService/Login\"\n}\n\nfunc Example_login() {\n\t_ = grpc.NewServer(\n\t\tgrpc.ChainUnaryInterceptor(\n\t\t\tselector.UnaryServerInterceptor(auth.UnaryServerInterceptor(exampleAuthFunc), selector.MatchFunc(loginSkip)),\n\t\t),\n\t\tgrpc.ChainStreamInterceptor(\n\t\t\tselector.StreamServerInterceptor(auth.StreamServerInterceptor(exampleAuthFunc), selector.MatchFunc(loginSkip)),\n\t\t),\n\t)\n}\n"
  },
  {
    "path": "interceptors/selector/selector_test.go",
    "content": "// Copyright (c) The go-grpc-middleware Authors.\n// Licensed under the Apache License 2.0.\n\npackage selector\n\nimport (\n\t\"context\"\n\t\"errors\"\n\t\"testing\"\n\n\t\"github.com/grpc-ecosystem/go-grpc-middleware/v2/interceptors\"\n\t\"github.com/stretchr/testify/assert\"\n\t\"github.com/stretchr/testify/require\"\n\t\"google.golang.org/grpc\"\n)\n\n// allow matches only given methods.\nfunc allow(methods []string) Matcher {\n\treturn MatchFunc(func(ctx context.Context, c interceptors.CallMeta) bool {\n\t\tfor _, s := range methods {\n\t\t\tif s == c.FullMethod() {\n\t\t\t\treturn true\n\t\t\t}\n\t\t}\n\t\treturn false\n\t})\n}\n\ntype mockGRPCServerStream struct {\n\tgrpc.ServerStream\n\n\tctx context.Context\n}\n\nfunc (m *mockGRPCServerStream) Context() context.Context {\n\treturn m.ctx\n}\n\nconst svcMethod = \"/v1beta1.SomeService/NeedsAuth\"\n\nfunc TestUnaryServerInterceptor(t *testing.T) {\n\tinterceptor := UnaryServerInterceptor(\n\t\tfunc(context.Context, any, *grpc.UnaryServerInfo, grpc.UnaryHandler) (any, error) {\n\t\t\treturn nil, errors.New(\"always error\")\n\t\t}, allow([]string{svcMethod}),\n\t)\n\n\thandler := func(ctx context.Context, req any) (any, error) {\n\t\treturn \"good\", nil\n\t}\n\n\tt.Run(\"not-selected\", func(t *testing.T) {\n\t\tinfo := &grpc.UnaryServerInfo{\n\t\t\tFullMethod: \"FakeMethod\",\n\t\t}\n\t\tresp, err := interceptor(context.Background(), nil, info, handler)\n\t\trequire.NoError(t, err)\n\t\tassert.Equal(t, \"good\", resp)\n\t})\n\n\tt.Run(\"selected\", func(t *testing.T) {\n\t\tinfo := &grpc.UnaryServerInfo{\n\t\t\tFullMethod: svcMethod,\n\t\t}\n\t\tresp, err := interceptor(context.Background(), nil, info, handler)\n\t\tassert.Nil(t, resp)\n\t\tassert.EqualError(t, err, \"always error\")\n\t})\n}\n\nfunc TestStreamServerInterceptor(t *testing.T) {\n\tinterceptor := StreamServerInterceptor(\n\t\tfunc(srv any, ss grpc.ServerStream, info *grpc.StreamServerInfo, handler grpc.StreamHandler) error {\n\t\t\treturn errors.New(\"always error\")\n\t\t},\n\t\tallow([]string{svcMethod}),\n\t)\n\n\thandler := func(srv any, stream grpc.ServerStream) error {\n\t\treturn nil\n\t}\n\n\tt.Run(\"not-selected\", func(t *testing.T) {\n\t\tinfo := &grpc.StreamServerInfo{\n\t\t\tFullMethod: \"FakeMethod\",\n\t\t}\n\n\t\terr := interceptor(nil, &mockGRPCServerStream{ctx: context.Background()}, info, handler)\n\t\tassert.NoError(t, err)\n\t})\n\n\tt.Run(\"selected\", func(t *testing.T) {\n\t\tinfo := &grpc.StreamServerInfo{\n\t\t\tFullMethod: svcMethod,\n\t\t}\n\t\terr := interceptor(nil, &mockGRPCServerStream{ctx: context.Background()}, info, handler)\n\t\tassert.EqualError(t, err, \"always error\")\n\t})\n}\n\nfunc TestAllow(t *testing.T) {\n\ttype args struct {\n\t\tmethods []string\n\t}\n\ttests := []struct {\n\t\tname   string\n\t\targs   args\n\t\tmethod string\n\t\twant   bool\n\t}{\n\t\t{\n\t\t\tname: \"false\",\n\t\t\targs: args{\n\t\t\t\tmethods: []string{\"/auth.v1beta1.AuthService/Login\"},\n\t\t\t},\n\t\t\tmethod: \"/testing.testpb.v1.TestService/PingList\",\n\t\t\twant:   false,\n\t\t},\n\t\t{\n\t\t\tname: \"true\",\n\t\t\targs: args{\n\t\t\t\tmethods: []string{\"/auth.v1beta1.AuthService/Login\"},\n\t\t\t},\n\t\t\tmethod: \"/auth.v1beta1.AuthService/Login\",\n\t\t\twant:   true,\n\t\t},\n\t}\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tallow := allow(tt.args.methods)\n\t\t\twant := allow.Match(context.Background(), interceptors.NewServerCallMeta(tt.method, nil, nil))\n\t\t\tassert.Equalf(t, tt.want, want, \"Allow(%v)(ctx, %v)\", tt.args.methods, tt.method)\n\t\t})\n\t}\n}\n"
  },
  {
    "path": "interceptors/server.go",
    "content": "// Copyright (c) The go-grpc-middleware Authors.\n// Licensed under the Apache License 2.0.\n\n// Go gRPC Middleware monitoring interceptors for server-side gRPC.\n\npackage interceptors\n\nimport (\n\t\"context\"\n\t\"time\"\n\n\t\"google.golang.org/grpc\"\n)\n\n// UnaryServerInterceptor is a gRPC server-side interceptor that provides reporting for Unary RPCs.\nfunc UnaryServerInterceptor(reportable ServerReportable) grpc.UnaryServerInterceptor {\n\treturn func(ctx context.Context, req any, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (any, error) {\n\t\tr := newReport(NewServerCallMeta(info.FullMethod, nil, req))\n\t\treporter, newCtx := reportable.ServerReporter(ctx, r.callMeta)\n\n\t\treporter.PostMsgReceive(req, nil, time.Since(r.startTime))\n\t\tresp, err := handler(newCtx, req)\n\t\treporter.PostMsgSend(resp, err, time.Since(r.startTime))\n\n\t\treporter.PostCall(err, time.Since(r.startTime))\n\t\treturn resp, err\n\t}\n}\n\n// StreamServerInterceptor is a gRPC server-side interceptor that provides reporting for Streaming RPCs.\nfunc StreamServerInterceptor(reportable ServerReportable) grpc.StreamServerInterceptor {\n\treturn func(srv any, ss grpc.ServerStream, info *grpc.StreamServerInfo, handler grpc.StreamHandler) error {\n\t\tr := newReport(NewServerCallMeta(info.FullMethod, info, nil))\n\t\treporter, newCtx := reportable.ServerReporter(ss.Context(), r.callMeta)\n\t\terr := handler(srv, &monitoredServerStream{ServerStream: ss, newCtx: newCtx, reporter: reporter})\n\t\treporter.PostCall(err, time.Since(r.startTime))\n\t\treturn err\n\t}\n}\n\n// monitoredStream wraps grpc.ServerStream allowing each Sent/Recv of message to report.\ntype monitoredServerStream struct {\n\tgrpc.ServerStream\n\n\tnewCtx   context.Context\n\treporter Reporter\n}\n\nfunc (s *monitoredServerStream) Context() context.Context {\n\treturn s.newCtx\n}\n\nfunc (s *monitoredServerStream) SendMsg(m any) error {\n\tstart := time.Now()\n\terr := s.ServerStream.SendMsg(m)\n\ts.reporter.PostMsgSend(m, err, time.Since(start))\n\treturn err\n}\n\nfunc (s *monitoredServerStream) RecvMsg(m any) error {\n\tstart := time.Now()\n\terr := s.ServerStream.RecvMsg(m)\n\ts.reporter.PostMsgReceive(m, err, time.Since(start))\n\treturn err\n}\n"
  },
  {
    "path": "interceptors/server_test.go",
    "content": "// Copyright (c) The go-grpc-middleware Authors.\n// Licensed under the Apache License 2.0.\n\npackage interceptors\n\nimport (\n\t\"context\"\n\t\"errors\"\n\t\"io\"\n\t\"net\"\n\t\"sync\"\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/grpc-ecosystem/go-grpc-middleware/v2/testing/testpb\"\n\t\"github.com/stretchr/testify/suite\"\n\t\"google.golang.org/grpc\"\n\t\"google.golang.org/grpc/codes\"\n\t\"google.golang.org/grpc/credentials/insecure\"\n\t\"google.golang.org/grpc/status\"\n)\n\nfunc TestServerInterceptorSuite(t *testing.T) {\n\tsuite.Run(t, &ServerInterceptorTestSuite{})\n}\n\ntype ServerInterceptorTestSuite struct {\n\tsuite.Suite\n\n\tserverListener net.Listener\n\tserver         *grpc.Server\n\tclientConn     *grpc.ClientConn\n\ttestClient     testpb.TestServiceClient\n\tctx            context.Context\n\tcancel         context.CancelFunc\n\n\tmock *mockReportable\n}\n\nfunc (s *ServerInterceptorTestSuite) SetupSuite() {\n\tvar err error\n\n\ts.mock = &mockReportable{}\n\n\ts.serverListener, err = net.Listen(\"tcp\", \"127.0.0.1:0\")\n\ts.Require().NoError(err, \"must be able to allocate a port for serverListener\")\n\n\t// This is the point where we hook up the interceptor\n\ts.server = grpc.NewServer(\n\t\tgrpc.StreamInterceptor(StreamServerInterceptor(s.mock)),\n\t\tgrpc.UnaryInterceptor(UnaryServerInterceptor(s.mock)),\n\t)\n\ttestpb.RegisterTestServiceServer(s.server, &testpb.TestPingService{})\n\n\tgo func() {\n\t\t_ = s.server.Serve(s.serverListener)\n\t}()\n\n\ts.clientConn, err = grpc.NewClient(s.serverListener.Addr().String(), grpc.WithTransportCredentials(insecure.NewCredentials()))\n\ts.Require().NoError(err, \"must not error on client Dial\")\n\ts.testClient = testpb.NewTestServiceClient(s.clientConn)\n}\n\nfunc (s *ServerInterceptorTestSuite) SetupTest() {\n\t// Make all RPC calls last at most 2 sec, meaning all async issues or deadlock will not kill tests.\n\ts.ctx, s.cancel = context.WithTimeout(context.TODO(), 2*time.Second)\n\n\ts.mock.reports = s.mock.reports[:0]\n}\n\nfunc (s *ServerInterceptorTestSuite) TearDownSuite() {\n\tif s.serverListener != nil {\n\t\ts.server.Stop()\n\t\ts.T().Logf(\"stopped grpc.Server at: %v\", s.serverListener.Addr().String())\n\t\t_ = s.serverListener.Close()\n\n\t}\n\tif s.clientConn != nil {\n\t\t_ = s.clientConn.Close()\n\t}\n}\n\nfunc (s *ServerInterceptorTestSuite) TearDownTest() {\n\ts.cancel()\n}\n\nfunc (s *ServerInterceptorTestSuite) TestUnaryReporting() {\n\t_, err := s.testClient.PingEmpty(s.ctx, &testpb.PingEmptyRequest{}) // should return with code=OK\n\ts.Require().NoError(err)\n\ts.mock.Equal(s.T(), []*mockReport{{\n\t\tCallMeta:        CallMeta{Typ: Unary, Service: testpb.TestServiceFullName, Method: \"PingEmpty\"},\n\t\tpostCalls:       []error{nil},\n\t\tpostMsgReceives: []error{nil},\n\t\tpostMsgSends:    []error{nil},\n\t}})\n\ts.mock.reports = s.mock.reports[:0] // Reset.\n\n\t_, err = s.testClient.PingError(s.ctx, &testpb.PingErrorRequest{ErrorCodeReturned: uint32(codes.FailedPrecondition)}) // should return with code=FailedPrecondition\n\ts.Require().Error(err)\n\ts.mock.Equal(s.T(), []*mockReport{{\n\t\tCallMeta:        CallMeta{Typ: Unary, Service: testpb.TestServiceFullName, Method: \"PingError\"},\n\t\tpostCalls:       []error{status.Error(codes.FailedPrecondition, \"Userspace error\")},\n\t\tpostMsgReceives: []error{nil},\n\t\tpostMsgSends:    []error{status.Error(codes.FailedPrecondition, \"Userspace error\")},\n\t}})\n}\n\nfunc (s *ServerInterceptorTestSuite) TestStreamingReports() {\n\tss, _ := s.testClient.PingList(s.ctx, &testpb.PingListRequest{}) // should return with code=OK\n\t// Do a read, just for kicks.\n\tcount := 0\n\tfor {\n\t\t_, err := ss.Recv()\n\t\tif errors.Is(err, io.EOF) {\n\t\t\tbreak\n\t\t}\n\t\ts.Require().NoError(err, \"reading pingList shouldn't fail\")\n\t\tcount++\n\t}\n\ts.Require().Equal(testpb.ListResponseCount, count, \"Number of received msg on the wire must match\")\n\ts.mock.Equal(s.T(), []*mockReport{{\n\t\tCallMeta:        CallMeta{Typ: ServerStream, Service: testpb.TestServiceFullName, Method: \"PingList\"},\n\t\tpostCalls:       []error{nil},\n\t\tpostMsgReceives: []error{nil},\n\t\tpostMsgSends:    make([]error, testpb.ListResponseCount),\n\t}})\n\ts.mock.reports = s.mock.reports[:0] // Reset.\n\n\t_, err := s.testClient.PingList(s.ctx, &testpb.PingListRequest{ErrorCodeReturned: uint32(codes.FailedPrecondition)}) // should return with code=FailedPrecondition\n\ts.Require().NoError(err, \"PingList must not fail immediately\")\n\n\ts.mock.requireOneReportWithRetry(s.ctx, s.T(), &mockReport{\n\t\tCallMeta:        CallMeta{Typ: ServerStream, Service: testpb.TestServiceFullName, Method: \"PingList\"},\n\t\tpostCalls:       []error{status.Error(codes.FailedPrecondition, \"foobar\")},\n\t\tpostMsgReceives: []error{nil},\n\t})\n}\n\nfunc (s *ServerInterceptorTestSuite) TestBiStreamingReporting() {\n\tss, err := s.testClient.PingStream(s.ctx)\n\ts.Require().NoError(err)\n\twg := sync.WaitGroup{}\n\n\tdefer func() {\n\t\t_ = ss.CloseSend()\n\t\twg.Wait()\n\t}()\n\n\tcount := 0\n\twg.Add(1)\n\tgo func() {\n\t\tdefer wg.Done()\n\t\tfor s.ctx.Err() == nil {\n\n\t\t\t_, err := ss.Recv()\n\t\t\tif errors.Is(err, io.EOF) {\n\t\t\t\tbreak\n\t\t\t}\n\t\t\ts.Require().NoError(err, \"reading pingStream shouldn't fail\")\n\t\t\tcount++\n\t\t}\n\t}()\n\tfor i := 0; i < 100; i++ {\n\t\ts.Require().NoError(ss.Send(&testpb.PingStreamRequest{}), \"sending shouldn't fail\")\n\t}\n\n\ts.Require().NoError(ss.CloseSend())\n\twg.Wait()\n\n\ts.Require().Equal(100, count, \"Number of received msg on the wire must match\")\n\n\ts.mock.Equal(s.T(), []*mockReport{{\n\t\tCallMeta:        CallMeta{Typ: BidiStream, Service: testpb.TestServiceFullName, Method: \"PingStream\"},\n\t\tpostCalls:       []error{nil},\n\t\tpostMsgReceives: append(make([]error, 100), io.EOF),\n\t\tpostMsgSends:    make([]error, 100),\n\t}})\n}\n"
  },
  {
    "path": "interceptors/timeout/doc.go",
    "content": "// Copyright (c) The go-grpc-middleware Authors.\n// Licensed under the Apache License 2.0.\n\n/*\nPackage timeout is a middleware that responds with a timeout error after the given duration.\n\n`grpc_timeout` are interceptors that timeout for gRPC client calls.\n\n# Client Side Timeout Middleware\n\nPlease see examples for simple examples of use.\n*/\npackage timeout\n"
  },
  {
    "path": "interceptors/timeout/examples_test.go",
    "content": "// Copyright (c) The go-grpc-middleware Authors.\n// Licensed under the Apache License 2.0.\n\npackage timeout_test\n\nimport (\n\t\"context\"\n\t\"log\"\n\t\"time\"\n\n\t\"github.com/grpc-ecosystem/go-grpc-middleware/v2/interceptors/timeout\"\n\t\"github.com/grpc-ecosystem/go-grpc-middleware/v2/testing/testpb\"\n\t\"google.golang.org/grpc\"\n)\n\n// Initialization shows an initialization sequence with a custom client request timeout.\nfunc Example_initialization() {\n\tclientConn, err := grpc.NewClient(\n\t\t\"ServerAddr\",\n\t\tgrpc.WithUnaryInterceptor(\n\t\t\t// Set your client request timeout.\n\t\t\ttimeout.UnaryClientInterceptor(20*time.Millisecond),\n\t\t),\n\t)\n\tif err != nil {\n\t\tlog.Fatal(err)\n\t}\n\n\t// Initialize your grpc service with connection.\n\ttestServiceClient := testpb.NewTestServiceClient(clientConn)\n\tresp, err := testServiceClient.Ping(context.TODO(), &testpb.PingRequest{Value: \"my_example_value\"})\n\tif err != nil {\n\t\tlog.Fatal(err)\n\t}\n\n\t// Use grpc response value.\n\tlog.Println(resp.Value)\n}\n"
  },
  {
    "path": "interceptors/timeout/timeout.go",
    "content": "// Copyright (c) The go-grpc-middleware Authors.\n// Licensed under the Apache License 2.0.\n\npackage timeout\n\nimport (\n\t\"context\"\n\t\"time\"\n\n\t\"google.golang.org/grpc\"\n)\n\n// UnaryClientInterceptor returns a new unary client interceptor that sets a timeout on the request context.\nfunc UnaryClientInterceptor(timeout time.Duration) grpc.UnaryClientInterceptor {\n\treturn func(ctx context.Context, method string, req, reply any, cc *grpc.ClientConn, invoker grpc.UnaryInvoker, opts ...grpc.CallOption) error {\n\t\ttimedCtx, cancel := context.WithTimeout(ctx, timeout)\n\t\tdefer cancel()\n\t\treturn invoker(timedCtx, method, req, reply, cc, opts...)\n\t}\n}\n"
  },
  {
    "path": "interceptors/timeout/timeout_test.go",
    "content": "// Copyright (c) The go-grpc-middleware Authors.\n// Licensed under the Apache License 2.0.\n\npackage timeout_test\n\nimport (\n\t\"context\"\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/grpc-ecosystem/go-grpc-middleware/v2/interceptors/timeout\"\n\t\"github.com/grpc-ecosystem/go-grpc-middleware/v2/testing/testpb\"\n\t\"github.com/stretchr/testify/assert\"\n\t\"github.com/stretchr/testify/require\"\n\t\"google.golang.org/grpc\"\n\t\"google.golang.org/grpc/codes\"\n\t\"google.golang.org/grpc/status\"\n)\n\ntype TimeoutTestServiceServer struct {\n\tsleepTime time.Duration\n\ttestpb.TestPingService\n}\n\nfunc (t *TimeoutTestServiceServer) Ping(ctx context.Context, req *testpb.PingRequest) (*testpb.PingResponse, error) {\n\tif t.sleepTime > 0 {\n\t\ttime.Sleep(t.sleepTime)\n\t}\n\treturn t.TestPingService.Ping(ctx, req)\n}\n\nfunc TestTimeoutUnaryClientInterceptor(t *testing.T) {\n\tserver := &TimeoutTestServiceServer{}\n\n\tits := &testpb.InterceptorTestSuite{\n\t\tClientOpts: []grpc.DialOption{\n\t\t\tgrpc.WithUnaryInterceptor(timeout.UnaryClientInterceptor(100 * time.Millisecond)),\n\t\t},\n\t\tTestService: server,\n\t}\n\tits.SetT(t)\n\tits.SetupSuite()\n\tdefer its.TearDownSuite()\n\n\t// This call will take 0/100ms for respond, so the client timeout NOT exceed.\n\tresp, err := its.Client.Ping(context.TODO(), &testpb.PingRequest{Value: \"default_response_value\"})\n\trequire.NoError(t, err)\n\tassert.NotNil(t, resp)\n\tassert.Equal(t, \"default_response_value\", resp.Value)\n\n\t// server will sleep 300ms before respond\n\tserver.sleepTime = 300 * time.Millisecond\n\n\t// This call will take 300/100ms for respond, so the client timeout exceed.\n\tresp2, err2 := its.Client.Ping(context.TODO(), &testpb.PingRequest{})\n\tassert.Nil(t, resp2)\n\tst, ok := status.FromError(err2)\n\tassert.True(t, ok)\n\tassert.Equal(t, codes.DeadlineExceeded, st.Code())\n}\n"
  },
  {
    "path": "interceptors/validator/doc.go",
    "content": "// Copyright (c) The go-grpc-middleware Authors.\n// Licensed under the Apache License 2.0.\n\n/*\nPackage validator\n\n`validator` is a generic request contents validator server-side middleware for gRPC.\n\n# Request Validator Middleware\n\nValidating input is important, and hard. It also causes a lot of boilerplate code. This middleware\nchecks for the existence of a `Validate` method on each of the messages of a gRPC request. This\nincludes the single request of the `Unary` calls, as well as each message of the inbound Stream calls.\nIn case of a validation failure, an `InvalidArgument` gRPC status is returned, along with a\ndescription of the validation failure.\n\nWhile it is generic, it was intended to be used with https://github.com/mwitkow/go-proto-validators,\na Go protocol buffers codegen plugin that creates the `Validate` methods (including nested messages)\nbased on declarative options in the `.proto` files themselves. For example:\n\n\tsyntax = \"proto3\";\n\tpackage validator.examples;\n\timport \"github.com/mwitkow/go-proto-validators/validator.proto\";\n\n\tmessage InnerMessage {\n\t  // some_integer can only be in range (1, 100).\n\t  int32 some_integer = 1 [(validator.field) = {int_gt: 0, int_lt: 100}];\n\t  // some_float can only be in range (0;1).\n\t  double some_float = 2 [(validator.field) = {float_gte: 0, float_lte: 1}];\n\t}\n\n\tmessage OuterMessage {\n\t  // important_string must be a lowercase alpha-numeric of 5 to 30 characters (RE2 syntax).\n\t  string important_string = 1 [(validator.field) = {regex: \"^[a-z]{2,5}$\"}];\n\t  // proto3 doesn't have `required`, the `msg_exist` enforces presence of InnerMessage.\n\t  InnerMessage inner = 2 [(validator.field) = {msg_exists : true}];\n\t}\n\nThe `OuterMessage.Validate` would include validation of regexes, existence of the InnerMessage and\nthe range values within it. The `grpc_validator` middleware would then automatically use that to\ncheck all messages processed by the server.\n\nPlease consult https://github.com/mwitkow/go-proto-validators for details on `protoc` invocation and\nother parameters of customization.\n*/\npackage validator\n"
  },
  {
    "path": "interceptors/validator/interceptors.go",
    "content": "// Copyright (c) The go-grpc-middleware Authors.\n// Licensed under the Apache License 2.0.\n\npackage validator\n\nimport (\n\t\"context\"\n\n\t\"google.golang.org/grpc\"\n)\n\n// UnaryServerInterceptor returns a new unary server interceptor that validates incoming messages.\n//\n// Invalid messages will be rejected with `InvalidArgument` before reaching any userspace handlers.\n// Note that generated codes prior to protoc-gen-validate v0.6.0 do not provide an all-validation\n// interface. In this case the interceptor fallbacks to legacy validation and `all` is ignored.\nfunc UnaryServerInterceptor(opts ...Option) grpc.UnaryServerInterceptor {\n\to := evaluateOpts(opts)\n\treturn func(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (interface{}, error) {\n\t\tif err := validate(ctx, req, o.shouldFailFast, o.onValidationErrCallback); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\treturn handler(ctx, req)\n\t}\n}\n\n// UnaryClientInterceptor returns a new unary client interceptor that validates outgoing messages.\n//\n// Invalid messages will be rejected with `InvalidArgument` before sending the request to server.\n// Note that generated codes prior to protoc-gen-validate v0.6.0 do not provide an all-validation\n// interface. In this case the interceptor fallbacks to legacy validation and `all` is ignored.\nfunc UnaryClientInterceptor(opts ...Option) grpc.UnaryClientInterceptor {\n\to := evaluateOpts(opts)\n\treturn func(ctx context.Context, method string, req, reply interface{}, cc *grpc.ClientConn, invoker grpc.UnaryInvoker, opts ...grpc.CallOption) error {\n\t\tif err := validate(ctx, req, o.shouldFailFast, o.onValidationErrCallback); err != nil {\n\t\t\treturn err\n\t\t}\n\t\treturn invoker(ctx, method, req, reply, cc, opts...)\n\t}\n}\n\n// StreamServerInterceptor returns a new streaming server interceptor that validates incoming messages.\n//\n// Note that generated codes prior to protoc-gen-validate v0.6.0 do not provide an all-validation\n// interface. In this case the interceptor fallbacks to legacy validation and `all` is ignored.\n// The stage at which invalid messages will be rejected with `InvalidArgument` varies based on the\n// type of the RPC. For `ServerStream` (1:m) requests, it will happen before reaching any userspace\n// handlers. For `ClientStream` (n:1) or `BidiStream` (n:m) RPCs, the messages will be rejected on\n// calls to `stream.Recv()`.\nfunc StreamServerInterceptor(opts ...Option) grpc.StreamServerInterceptor {\n\to := evaluateOpts(opts)\n\treturn func(srv interface{}, stream grpc.ServerStream, info *grpc.StreamServerInfo, handler grpc.StreamHandler) error {\n\t\twrapper := &recvWrapper{\n\t\t\toptions:      o,\n\t\t\tServerStream: stream,\n\t\t}\n\n\t\treturn handler(srv, wrapper)\n\t}\n}\n\ntype recvWrapper struct {\n\t*options\n\tgrpc.ServerStream\n}\n\nfunc (s *recvWrapper) RecvMsg(m any) error {\n\tif err := s.ServerStream.RecvMsg(m); err != nil {\n\t\treturn err\n\t}\n\tif err := validate(s.Context(), m, s.shouldFailFast, s.onValidationErrCallback); err != nil {\n\t\treturn err\n\t}\n\treturn nil\n}\n"
  },
  {
    "path": "interceptors/validator/interceptors_test.go",
    "content": "// Copyright (c) The go-grpc-middleware Authors.\n// Licensed under the Apache License 2.0.\n\npackage validator_test\n\nimport (\n\t\"context\"\n\t\"errors\"\n\t\"io\"\n\t\"testing\"\n\n\t\"github.com/grpc-ecosystem/go-grpc-middleware/v2/interceptors/validator\"\n\t\"github.com/grpc-ecosystem/go-grpc-middleware/v2/testing/testpb\"\n\t\"github.com/stretchr/testify/require\"\n\t\"github.com/stretchr/testify/suite\"\n\t\"google.golang.org/grpc\"\n\t\"google.golang.org/grpc/codes\"\n\t\"google.golang.org/grpc/status\"\n)\n\ntype ValidatorTestSuite struct {\n\t*testpb.InterceptorTestSuite\n}\n\nfunc (s *ValidatorTestSuite) TestValidPasses_Unary() {\n\t_, err := s.Client.Ping(s.SimpleCtx(), testpb.GoodPing)\n\ts.Assert().NoError(err, \"no error expected\")\n}\n\nfunc (s *ValidatorTestSuite) TestInvalidErrors_Unary() {\n\t_, err := s.Client.Ping(s.SimpleCtx(), testpb.BadPing)\n\ts.Require().Error(err, \"no error expected\")\n\ts.Assert().Equal(codes.InvalidArgument, status.Code(err), \"gRPC status must be InvalidArgument\")\n}\n\nfunc (s *ValidatorTestSuite) TestValidPasses_ServerStream() {\n\tstream, err := s.Client.PingList(s.SimpleCtx(), testpb.GoodPingList)\n\ts.Require().NoError(err, \"no error on stream establishment expected\")\n\tfor {\n\t\t_, err := stream.Recv()\n\t\tif errors.Is(err, io.EOF) {\n\t\t\tbreak\n\t\t}\n\t\ts.Assert().NoError(err, \"no error on messages sent occurred\")\n\t}\n}\n\ntype ClientValidatorTestSuite struct {\n\t*testpb.InterceptorTestSuite\n}\n\nfunc (s *ClientValidatorTestSuite) TestValidPasses_Unary() {\n\t_, err := s.Client.Ping(s.SimpleCtx(), testpb.GoodPing)\n\ts.Assert().NoError(err, \"no error expected\")\n}\n\nfunc (s *ClientValidatorTestSuite) TestInvalidErrors_Unary() {\n\t_, err := s.Client.Ping(s.SimpleCtx(), testpb.BadPing)\n\ts.Require().Error(err, \"error expected\")\n\ts.Assert().Equal(codes.InvalidArgument, status.Code(err), \"gRPC status must be InvalidArgument\")\n}\n\nfunc (s *ValidatorTestSuite) TestInvalidErrors_ServerStream() {\n\tstream, err := s.Client.PingList(s.SimpleCtx(), testpb.BadPingList)\n\ts.Require().NoError(err, \"no error on stream establishment expected\")\n\t_, err = stream.Recv()\n\ts.Require().Error(err, \"error should be received on first message\")\n\ts.Assert().Equal(codes.InvalidArgument, status.Code(err), \"gRPC status must be InvalidArgument\")\n}\n\nfunc (s *ValidatorTestSuite) TestInvalidErrors_BidiStream() {\n\tstream, err := s.Client.PingStream(s.SimpleCtx())\n\ts.Require().NoError(err, \"no error on stream establishment expected\")\n\n\ts.Require().NoError(stream.Send(testpb.GoodPingStream))\n\t_, err = stream.Recv()\n\ts.Assert().NoError(err, \"receiving a good ping should return a good pong\")\n\ts.Require().NoError(stream.Send(testpb.GoodPingStream))\n\t_, err = stream.Recv()\n\ts.Assert().NoError(err, \"receiving a good ping should return a good pong\")\n\n\ts.Require().NoError(stream.Send(testpb.BadPingStream))\n\t_, err = stream.Recv()\n\ts.Require().Error(err, \"receiving a bad ping should return a bad pong\")\n\ts.Assert().Equal(codes.InvalidArgument, status.Code(err), \"gRPC status must be InvalidArgument\")\n\n\terr = stream.CloseSend()\n\ts.Assert().NoError(err, \"there should be no error closing the stream on send\")\n}\n\nfunc TestValidatorTestSuite(t *testing.T) {\n\tsWithNoArgs := &ValidatorTestSuite{\n\t\tInterceptorTestSuite: &testpb.InterceptorTestSuite{\n\t\t\tServerOpts: []grpc.ServerOption{\n\t\t\t\tgrpc.StreamInterceptor(validator.StreamServerInterceptor()),\n\t\t\t\tgrpc.UnaryInterceptor(validator.UnaryServerInterceptor()),\n\t\t\t},\n\t\t},\n\t}\n\tsuite.Run(t, sWithNoArgs)\n\n\tsWithFailFastArgs := &ValidatorTestSuite{\n\t\tInterceptorTestSuite: &testpb.InterceptorTestSuite{\n\t\t\tServerOpts: []grpc.ServerOption{\n\t\t\t\tgrpc.StreamInterceptor(validator.StreamServerInterceptor(validator.WithFailFast())),\n\t\t\t\tgrpc.UnaryInterceptor(validator.UnaryServerInterceptor(validator.WithFailFast())),\n\t\t\t},\n\t\t},\n\t}\n\tsuite.Run(t, sWithFailFastArgs)\n\n\tvar gotErrMsgs []string\n\tonErr := func(ctx context.Context, err error) {\n\t\tgotErrMsgs = append(gotErrMsgs, err.Error())\n\t}\n\tsWithOnErrFuncArgs := &ValidatorTestSuite{\n\t\tInterceptorTestSuite: &testpb.InterceptorTestSuite{\n\t\t\tServerOpts: []grpc.ServerOption{\n\t\t\t\tgrpc.StreamInterceptor(validator.StreamServerInterceptor(validator.WithOnValidationErrCallback(onErr))),\n\t\t\t\tgrpc.UnaryInterceptor(validator.UnaryServerInterceptor(validator.WithOnValidationErrCallback(onErr))),\n\t\t\t},\n\t\t},\n\t}\n\tsuite.Run(t, sWithOnErrFuncArgs)\n\trequire.Equal(t, []string{\"cannot sleep for more than 10s\", \"cannot sleep for more than 10s\", \"cannot sleep for more than 10s\"}, gotErrMsgs)\n\n\tgotErrMsgs = gotErrMsgs[:0]\n\tsAll := &ValidatorTestSuite{\n\t\tInterceptorTestSuite: &testpb.InterceptorTestSuite{\n\t\t\tServerOpts: []grpc.ServerOption{\n\t\t\t\tgrpc.StreamInterceptor(validator.StreamServerInterceptor(validator.WithFailFast(), validator.WithOnValidationErrCallback(onErr))),\n\t\t\t\tgrpc.UnaryInterceptor(validator.UnaryServerInterceptor(validator.WithFailFast(), validator.WithOnValidationErrCallback(onErr))),\n\t\t\t},\n\t\t},\n\t}\n\tsuite.Run(t, sAll)\n\trequire.Equal(t, []string{\"cannot sleep for more than 10s\", \"cannot sleep for more than 10s\", \"cannot sleep for more than 10s\"}, gotErrMsgs)\n\n\tcsWithNoArgs := &ClientValidatorTestSuite{\n\t\tInterceptorTestSuite: &testpb.InterceptorTestSuite{\n\t\t\tClientOpts: []grpc.DialOption{\n\t\t\t\tgrpc.WithUnaryInterceptor(validator.UnaryClientInterceptor()),\n\t\t\t},\n\t\t},\n\t}\n\tsuite.Run(t, csWithNoArgs)\n\n\tcsWithFailFastArgs := &ClientValidatorTestSuite{\n\t\tInterceptorTestSuite: &testpb.InterceptorTestSuite{\n\t\t\tServerOpts: []grpc.ServerOption{\n\t\t\t\tgrpc.UnaryInterceptor(validator.UnaryServerInterceptor(validator.WithFailFast())),\n\t\t\t},\n\t\t},\n\t}\n\tsuite.Run(t, csWithFailFastArgs)\n\n\tgotErrMsgs = gotErrMsgs[:0]\n\tcsWithOnErrFuncArgs := &ClientValidatorTestSuite{\n\t\tInterceptorTestSuite: &testpb.InterceptorTestSuite{\n\t\t\tServerOpts: []grpc.ServerOption{\n\t\t\t\tgrpc.UnaryInterceptor(validator.UnaryServerInterceptor(validator.WithOnValidationErrCallback(onErr))),\n\t\t\t},\n\t\t},\n\t}\n\tsuite.Run(t, csWithOnErrFuncArgs)\n\trequire.Equal(t, []string{\"cannot sleep for more than 10s\"}, gotErrMsgs)\n\n\tgotErrMsgs = gotErrMsgs[:0]\n\tcsAll := &ClientValidatorTestSuite{\n\t\tInterceptorTestSuite: &testpb.InterceptorTestSuite{\n\t\t\tClientOpts: []grpc.DialOption{\n\t\t\t\tgrpc.WithUnaryInterceptor(validator.UnaryClientInterceptor(validator.WithFailFast(), validator.WithOnValidationErrCallback(onErr))),\n\t\t\t},\n\t\t},\n\t}\n\tsuite.Run(t, csAll)\n\trequire.Equal(t, []string{\"cannot sleep for more than 10s\"}, gotErrMsgs)\n}\n"
  },
  {
    "path": "interceptors/validator/options.go",
    "content": "// Copyright (c) The go-grpc-middleware Authors.\n// Licensed under the Apache License 2.0.\n\npackage validator\n\nimport (\n\t\"context\"\n)\n\ntype options struct {\n\tshouldFailFast          bool\n\tonValidationErrCallback OnValidationErrCallback\n}\ntype Option func(*options)\n\nfunc evaluateOpts(opts []Option) *options {\n\toptCopy := &options{}\n\tfor _, o := range opts {\n\t\to(optCopy)\n\t}\n\treturn optCopy\n}\n\ntype OnValidationErrCallback func(ctx context.Context, err error)\n\n// WithOnValidationErrCallback registers function that will be invoked on validation error(s).\nfunc WithOnValidationErrCallback(onValidationErrCallback OnValidationErrCallback) Option {\n\treturn func(o *options) {\n\t\to.onValidationErrCallback = onValidationErrCallback\n\t}\n}\n\n// WithFailFast tells validator to immediately stop doing further validation after first validation error.\n// This option is ignored if message is only supporting validator.validatorLegacy interface.\nfunc WithFailFast() Option {\n\treturn func(o *options) {\n\t\to.shouldFailFast = true\n\t}\n}\n"
  },
  {
    "path": "interceptors/validator/validator.go",
    "content": "// Copyright (c) The go-grpc-middleware Authors.\n// Licensed under the Apache License 2.0.\n\npackage validator\n\nimport (\n\t\"context\"\n\n\t\"google.golang.org/grpc/codes\"\n\t\"google.golang.org/grpc/status\"\n)\n\n// The validateAller interface at protoc-gen-validate main branch.\n// See https://github.com/envoyproxy/protoc-gen-validate/pull/468.\ntype validateAller interface {\n\tValidateAll() error\n}\n\n// The validate interface starting with protoc-gen-validate v0.6.0.\n// See https://github.com/envoyproxy/protoc-gen-validate/pull/455.\ntype validator interface {\n\tValidate(all bool) error\n}\n\n// The validate interface prior to protoc-gen-validate v0.6.0.\ntype validatorLegacy interface {\n\tValidate() error\n}\n\nfunc validate(ctx context.Context, reqOrRes interface{}, shouldFailFast bool, onValidationErrCallback OnValidationErrCallback) (err error) {\n\tif shouldFailFast {\n\t\tswitch v := reqOrRes.(type) {\n\t\tcase validatorLegacy:\n\t\t\terr = v.Validate()\n\t\tcase validator:\n\t\t\terr = v.Validate(false)\n\t\t}\n\t} else {\n\t\tswitch v := reqOrRes.(type) {\n\t\tcase validateAller:\n\t\t\terr = v.ValidateAll()\n\t\tcase validator:\n\t\t\terr = v.Validate(true)\n\t\tcase validatorLegacy:\n\t\t\terr = v.Validate()\n\t\t}\n\t}\n\n\tif err == nil {\n\t\treturn nil\n\t}\n\n\tif onValidationErrCallback != nil {\n\t\tonValidationErrCallback(ctx, err)\n\t}\n\treturn status.Error(codes.InvalidArgument, err.Error())\n}\n"
  },
  {
    "path": "interceptors/validator/validator_test.go",
    "content": "// Copyright (c) The go-grpc-middleware Authors.\n// Licensed under the Apache License 2.0.\n\npackage validator\n\nimport (\n\t\"context\"\n\t\"testing\"\n\n\t\"github.com/grpc-ecosystem/go-grpc-middleware/v2/testing/testpb\"\n\t\"github.com/stretchr/testify/assert\"\n\t\"github.com/stretchr/testify/require\"\n)\n\nfunc TestValidateWrapper(t *testing.T) {\n\tctx := context.Background()\n\n\trequire.NoError(t, validate(ctx, testpb.GoodPing, false, nil))\n\trequire.Error(t, validate(ctx, testpb.BadPing, false, nil))\n\trequire.NoError(t, validate(ctx, testpb.GoodPing, true, nil))\n\trequire.Error(t, validate(ctx, testpb.BadPing, true, nil))\n\n\trequire.NoError(t, validate(ctx, testpb.GoodPingError, false, nil))\n\trequire.Error(t, validate(ctx, testpb.BadPingError, false, nil))\n\trequire.NoError(t, validate(ctx, testpb.GoodPingError, true, nil))\n\trequire.Error(t, validate(ctx, testpb.BadPingError, true, nil))\n\n\tassert.NoError(t, validate(ctx, testpb.GoodPingResponse, false, nil))\n\tassert.NoError(t, validate(ctx, testpb.GoodPingResponse, true, nil))\n\trequire.Error(t, validate(ctx, testpb.BadPingResponse, false, nil))\n\tassert.Error(t, validate(ctx, testpb.BadPingResponse, true, nil))\n}\n"
  },
  {
    "path": "metadata/doc.go",
    "content": "// Copyright (c) The go-grpc-middleware Authors.\n// Licensed under the Apache License 2.0.\n\n/*\nPackage `metadata` provides convenience functions for dealing with gRPC metadata.MD objects inside\nContext handlers.\n\nWhile the upstream grpc-go package contains decent functionality (see https://github.com/grpc/grpc-go/blob/master/Documentation/grpc-metadata.md)\nthey are hard to use.\n\nThe majority of functions center around the MD, which is a convenience wrapper around metadata.MD. For example\nthe following code allows you to easily extract incoming metadata (server handler) and put it into a new client context\nmetadata.\n\n  md := metadata.ExtractIncoming(serverCtx).Clone(\":authorization\", \":custom\")\n  clientCtx := md.Set(\"x-client-header\", \"2\").Set(\"x-another\", \"3\").ToOutgoing(ctx)\n*/\n\npackage metadata\n"
  },
  {
    "path": "metadata/metadata.go",
    "content": "// Copyright (c) The go-grpc-middleware Authors.\n// Licensed under the Apache License 2.0.\n\npackage metadata\n\nimport (\n\t\"context\"\n\t\"strings\"\n\n\tgrpcMetadata \"google.golang.org/grpc/metadata\"\n)\n\n// MD is a convenience wrapper defining extra functions on the metadata.\ntype MD grpcMetadata.MD\n\n// ExtractIncoming extracts an inbound metadata from the server-side context.\n//\n// This function always returns a MD wrapper of the grpcMetadata.MD, in case the context doesn't have metadata it returns\n// a new empty MD.\nfunc ExtractIncoming(ctx context.Context) MD {\n\tmd, ok := grpcMetadata.FromIncomingContext(ctx)\n\tif !ok {\n\t\treturn MD(grpcMetadata.Pairs())\n\t}\n\treturn MD(md)\n}\n\n// ExtractOutgoing extracts an outbound metadata from the client-side context.\n//\n// This function always returns a MD wrapper of the grpcMetadata.MD, in case the context doesn't have metadata it returns\n// a new empty MD.\nfunc ExtractOutgoing(ctx context.Context) MD {\n\tmd, ok := grpcMetadata.FromOutgoingContext(ctx)\n\tif !ok {\n\t\treturn MD(grpcMetadata.Pairs())\n\t}\n\treturn MD(md)\n}\n\n// Clone performs a *deep* copy of the grpcMetadata.MD.\n//\n// You can specify the lower-case copiedKeys to only copy certain whitelisted keys. If no keys are explicitly whitelisted\n// all keys get copied.\nfunc (m MD) Clone(copiedKeys ...string) MD {\n\tnewMd := MD(grpcMetadata.Pairs())\n\tfor k, vv := range m {\n\t\tfound := false\n\t\tif len(copiedKeys) == 0 {\n\t\t\tfound = true\n\t\t} else {\n\t\t\tfor _, allowedKey := range copiedKeys {\n\t\t\t\tif strings.EqualFold(allowedKey, k) {\n\t\t\t\t\tfound = true\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif !found {\n\t\t\tcontinue\n\t\t}\n\t\tnewMd[k] = make([]string, len(vv))\n\t\tcopy(newMd[k], vv)\n\t}\n\treturn newMd\n}\n\n// ToOutgoing sets the given MD as a client-side context for dispatching.\nfunc (m MD) ToOutgoing(ctx context.Context) context.Context {\n\treturn grpcMetadata.NewOutgoingContext(ctx, grpcMetadata.MD(m))\n}\n\n// ToIncoming sets the given MD as a server-side context for dispatching.\n//\n// This is mostly useful in ServerInterceptors.\nfunc (m MD) ToIncoming(ctx context.Context) context.Context {\n\treturn grpcMetadata.NewIncomingContext(ctx, grpcMetadata.MD(m))\n}\n\n// Get retrieves a single value from the metadata.\n//\n// It works analogously to http.Header.Get, returning the first value if there are many set. If the value is not set,\n// an empty string is returned.\n//\n// The function is binary-key safe.\nfunc (m MD) Get(key string) string {\n\tk, _ := encodeKeyValue(key, \"\")\n\tvv, ok := m[k]\n\tif !ok {\n\t\treturn \"\"\n\t}\n\treturn vv[0]\n}\n\n// Del retrieves a single value from the metadata.\n//\n// It works analogously to http.Header.Del, deleting all values if they exist.\n//\n// The function is binary-key safe.\n\nfunc (m MD) Del(key string) MD {\n\tk, _ := encodeKeyValue(key, \"\")\n\tdelete(m, k)\n\treturn m\n}\n\n// Set sets the given value in a metadata.\n//\n// It works analogously to http.Header.Set, overwriting all previous metadata values.\n//\n// The function is binary-key safe.\nfunc (m MD) Set(key, value string) MD {\n\tk, v := encodeKeyValue(key, value)\n\tm[k] = []string{v}\n\treturn m\n}\n\n// Add retrieves a single value from the metadata.\n//\n// It works analogously to http.Header.Add, as it appends to any existing values associated with key.\n//\n// The function is binary-key safe.\nfunc (m MD) Add(key, value string) MD {\n\tk, v := encodeKeyValue(key, value)\n\tm[k] = append(m[k], v)\n\treturn m\n}\n"
  },
  {
    "path": "metadata/metadata_test.go",
    "content": "// Copyright (c) The go-grpc-middleware Authors.\n// Licensed under the Apache License 2.0.\n\npackage metadata_test\n\nimport (\n\t\"context\"\n\t\"testing\"\n\n\t\"github.com/grpc-ecosystem/go-grpc-middleware/v2/metadata\"\n\t\"github.com/stretchr/testify/assert\"\n\tgrpcMetadata \"google.golang.org/grpc/metadata\"\n)\n\ntype parentKey struct{}\n\nvar (\n\ttestPairs = []string{\"singlekey\", \"uno\", \"multikey\", \"one\", \"multikey\", \"two\", \"multikey\", \"three\"}\n\tparentCtx = context.WithValue(context.TODO(), parentKey{}, \"parentValue\")\n)\n\nfunc assertRetainsParentContext(t *testing.T, ctx context.Context) {\n\tx := ctx.Value(parentKey{})\n\tassert.EqualValues(t, \"parentValue\", x, \"context must contain parentCtx\")\n}\n\nfunc TestNiceMD_Get(t *testing.T) {\n\tmd := metadata.MD(grpcMetadata.Pairs(testPairs...))\n\tassert.Equal(t, \"uno\", md.Get(\"singlekey\"), \"for present single-key value it should return it\")\n\tassert.Equal(t, \"one\", md.Get(\"multikey\"), \"for present multi-key should return first value\")\n\tassert.Empty(t, md.Get(\"nokey\"), \"for non existing key should return stuff\")\n}\n\nfunc TestNiceMD_Del(t *testing.T) {\n\tmd := metadata.MD(grpcMetadata.Pairs(testPairs...))\n\tassert.Equal(t, \"uno\", md.Get(\"singlekey\"), \"for present single-key value it should return it\")\n\tmd.Del(\"singlekey\").Del(\"doesnt exist\")\n\tassert.Empty(t, md.Get(\"singlekey\"), \"after deletion singlekey shouldn't exist\")\n}\n\nfunc TestNiceMD_Add(t *testing.T) {\n\tmd := metadata.MD(grpcMetadata.Pairs(testPairs...))\n\tmd.Add(\"multikey\", \"four\").Add(\"newkey\", \"something\")\n\tassert.Equal(t, []string{\"one\", \"two\", \"three\", \"four\"}, md[\"multikey\"], \"append should add a new four at the end\")\n\tassert.Equal(t, []string{\"something\"}, md[\"newkey\"], \"append should be able to create new keys\")\n}\n\nfunc TestNiceMD_Set(t *testing.T) {\n\tmd := metadata.MD(grpcMetadata.Pairs(testPairs...))\n\tmd.Set(\"multikey\", \"one\").Set(\"newkey\", \"something\").Set(\"newkey\", \"another\")\n\tassert.Equal(t, []string{\"one\"}, md[\"multikey\"], \"set should override existing multi keys\")\n\tassert.Equal(t, []string{\"another\"}, md[\"newkey\"], \"set should override new keys\")\n}\n\nfunc TestNiceMD_Clone(t *testing.T) {\n\tmd := metadata.MD(grpcMetadata.Pairs(testPairs...))\n\tfullCopied := md.Clone()\n\tassert.Len(t, md, len(fullCopied), \"clone full should copy all keys\")\n\tassert.Equal(t, \"uno\", fullCopied.Get(\"singlekey\"), \"full copied should have content\")\n\tsubCopied := md.Clone(\"multikey\")\n\tassert.Len(t, subCopied, 1, \"sub copied clone should only have one key\")\n\tassert.Empty(t, subCopied.Get(\"singlekey\"), \"there shouldn't be a singlekey in the subcopied\")\n\n\t// Test side effects and full copying:\n\tassert.Equal(t, subCopied[\"multikey\"], md[\"multikey\"], \"before overwrites multikey should have the same values\")\n\tsubCopied[\"multikey\"][1] = \"modifiedtwo\"\n\tassert.NotEqual(t, subCopied[\"multikey\"], md[\"multikey\"], \"before overwrites multikey should have the same values\")\n}\n\nfunc TestNiceMD_ToOutgoing(t *testing.T) {\n\tmd := metadata.MD(grpcMetadata.Pairs(testPairs...))\n\tnCtx := md.ToOutgoing(parentCtx)\n\tassertRetainsParentContext(t, nCtx)\n\n\teCtx := metadata.ExtractOutgoing(nCtx).Clone().Set(\"newvalue\", \"something\").ToOutgoing(nCtx)\n\tassertRetainsParentContext(t, eCtx)\n\tassert.NotEqual(t, metadata.ExtractOutgoing(nCtx), metadata.ExtractOutgoing(eCtx), \"the niceMD pointed to by ectx and nctx are different.\")\n}\n\nfunc TestNiceMD_ToIncoming(t *testing.T) {\n\tmd := metadata.MD(grpcMetadata.Pairs(testPairs...))\n\tnCtx := md.ToIncoming(parentCtx)\n\tassertRetainsParentContext(t, nCtx)\n\n\teCtx := metadata.ExtractIncoming(nCtx).Clone().Set(\"newvalue\", \"something\").ToIncoming(nCtx)\n\tassertRetainsParentContext(t, eCtx)\n\tassert.NotEqual(t, metadata.ExtractIncoming(nCtx), metadata.ExtractIncoming(eCtx), \"the niceMD pointed to by ectx and nctx are different.\")\n}\n"
  },
  {
    "path": "metadata/single_key.go",
    "content": "// Copyright (c) The go-grpc-middleware Authors.\n// Licensed under the Apache License 2.0.\n\npackage metadata\n\nimport (\n\t\"encoding/base64\"\n\t\"strings\"\n)\n\nconst (\n\tbinHdrSuffix = \"-bin\"\n)\n\nfunc encodeKeyValue(k, v string) (string, string) {\n\tk = strings.ToLower(k)\n\tif strings.HasSuffix(k, binHdrSuffix) {\n\t\treturn k, base64.StdEncoding.EncodeToString([]byte(v))\n\t}\n\treturn k, v\n}\n"
  },
  {
    "path": "providers/prometheus/client_metrics.go",
    "content": "// Copyright (c) The go-grpc-middleware Authors.\n// Licensed under the Apache License 2.0.\n\npackage prometheus\n\nimport (\n\t\"github.com/grpc-ecosystem/go-grpc-middleware/v2/interceptors\"\n\t\"github.com/prometheus/client_golang/prometheus\"\n\t\"google.golang.org/grpc\"\n)\n\n// ClientMetrics represents a collection of metrics to be registered on a\n// Prometheus metrics registry for a gRPC client.\ntype ClientMetrics struct {\n\tclientStartedCounter    *prometheus.CounterVec\n\tclientHandledCounter    *prometheus.CounterVec\n\tclientStreamMsgReceived *prometheus.CounterVec\n\tclientStreamMsgSent     *prometheus.CounterVec\n\n\t// clientHandledHistogram can be nil\n\tclientHandledHistogram *prometheus.HistogramVec\n\t// clientStreamRecvHistogram can be nil\n\tclientStreamRecvHistogram *prometheus.HistogramVec\n\t// clientStreamSendHistogram can be nil\n\tclientStreamSendHistogram *prometheus.HistogramVec\n\n\t// contextLabelNames stores the names of context labels\n\tcontextLabelNames []string\n}\n\n// NewClientMetrics returns a new ClientMetrics object.\n// NOTE: Remember to register ClientMetrics object using prometheus registry\n// e.g. prometheus.MustRegister(myClientMetrics).\nfunc NewClientMetrics(opts ...ClientMetricsOption) *ClientMetrics {\n\tconfig := &clientMetricsConfig{\n\t\tclientHandledHistogramFn:    func() *prometheus.HistogramVec { return nil },\n\t\tclientStreamRecvHistogramFn: func() *prometheus.HistogramVec { return nil },\n\t\tclientStreamSendHistogramFn: func() *prometheus.HistogramVec { return nil },\n\t}\n\tconfig.apply(opts)\n\n\t// Build label names by combining default labels with context labels\n\tdefaultLabels := []string{\"grpc_type\", \"grpc_service\", \"grpc_method\"}\n\tdefaultLabelsWithCode := []string{\"grpc_type\", \"grpc_service\", \"grpc_method\", \"grpc_code\"}\n\n\tstartedLabels := append(defaultLabels, config.contextLabels...)\n\thandledLabels := append(defaultLabelsWithCode, config.contextLabels...)\n\tstreamLabels := append(defaultLabels, config.contextLabels...)\n\n\treturn &ClientMetrics{\n\t\tclientStartedCounter: prometheus.NewCounterVec(\n\t\t\tconfig.counterOpts.apply(prometheus.CounterOpts{\n\t\t\t\tName: \"grpc_client_started_total\",\n\t\t\t\tHelp: \"Total number of RPCs started on the client.\",\n\t\t\t}), startedLabels),\n\n\t\tclientHandledCounter: prometheus.NewCounterVec(\n\t\t\tconfig.counterOpts.apply(prometheus.CounterOpts{\n\t\t\t\tName: \"grpc_client_handled_total\",\n\t\t\t\tHelp: \"Total number of RPCs completed by the client, regardless of success or failure.\",\n\t\t\t}), handledLabels),\n\n\t\tclientStreamMsgReceived: prometheus.NewCounterVec(\n\t\t\tconfig.counterOpts.apply(prometheus.CounterOpts{\n\t\t\t\tName: \"grpc_client_msg_received_total\",\n\t\t\t\tHelp: \"Total number of RPC stream messages received by the client.\",\n\t\t\t}), streamLabels),\n\n\t\tclientStreamMsgSent: prometheus.NewCounterVec(\n\t\t\tconfig.counterOpts.apply(prometheus.CounterOpts{\n\t\t\t\tName: \"grpc_client_msg_sent_total\",\n\t\t\t\tHelp: \"Total number of gRPC stream messages sent by the client.\",\n\t\t\t}), streamLabels),\n\n\t\tclientHandledHistogram:    config.clientHandledHistogramFn(),\n\t\tclientStreamRecvHistogram: config.clientStreamRecvHistogramFn(),\n\t\tclientStreamSendHistogram: config.clientStreamSendHistogramFn(),\n\n\t\tcontextLabelNames: config.contextLabels,\n\t}\n}\n\n// Describe sends the super-set of all possible descriptors of metrics\n// collected by this Collector to the provided channel and returns once\n// the last descriptor has been sent.\nfunc (m *ClientMetrics) Describe(ch chan<- *prometheus.Desc) {\n\tm.clientStartedCounter.Describe(ch)\n\tm.clientHandledCounter.Describe(ch)\n\tm.clientStreamMsgReceived.Describe(ch)\n\tm.clientStreamMsgSent.Describe(ch)\n\tif m.clientHandledHistogram != nil {\n\t\tm.clientHandledHistogram.Describe(ch)\n\t}\n\tif m.clientStreamRecvHistogram != nil {\n\t\tm.clientStreamRecvHistogram.Describe(ch)\n\t}\n\tif m.clientStreamSendHistogram != nil {\n\t\tm.clientStreamSendHistogram.Describe(ch)\n\t}\n}\n\n// Collect is called by the Prometheus registry when collecting\n// metrics. The implementation sends each collected metric via the\n// provided channel and returns once the last metric has been sent.\nfunc (m *ClientMetrics) Collect(ch chan<- prometheus.Metric) {\n\tm.clientStartedCounter.Collect(ch)\n\tm.clientHandledCounter.Collect(ch)\n\tm.clientStreamMsgReceived.Collect(ch)\n\tm.clientStreamMsgSent.Collect(ch)\n\tif m.clientHandledHistogram != nil {\n\t\tm.clientHandledHistogram.Collect(ch)\n\t}\n\tif m.clientStreamRecvHistogram != nil {\n\t\tm.clientStreamRecvHistogram.Collect(ch)\n\t}\n\tif m.clientStreamSendHistogram != nil {\n\t\tm.clientStreamSendHistogram.Collect(ch)\n\t}\n}\n\n// UnaryClientInterceptor is a gRPC client-side interceptor that provides Prometheus monitoring for Unary RPCs.\nfunc (m *ClientMetrics) UnaryClientInterceptor(opts ...Option) grpc.UnaryClientInterceptor {\n\treturn interceptors.UnaryClientInterceptor(&reportable{\n\t\topts:          opts,\n\t\tclientMetrics: m,\n\t})\n}\n\n// StreamClientInterceptor is a gRPC client-side interceptor that provides Prometheus monitoring for Streaming RPCs.\nfunc (m *ClientMetrics) StreamClientInterceptor(opts ...Option) grpc.StreamClientInterceptor {\n\treturn interceptors.StreamClientInterceptor(&reportable{\n\t\topts:          opts,\n\t\tclientMetrics: m,\n\t})\n}\n"
  },
  {
    "path": "providers/prometheus/client_options.go",
    "content": "// Copyright (c) The go-grpc-middleware Authors.\n// Licensed under the Apache License 2.0.\n\npackage prometheus\n\nimport (\n\t\"github.com/prometheus/client_golang/prometheus\"\n)\n\ntype clientMetricsConfig struct {\n\tcounterOpts counterOptions\n\t// clientHandledHistogramFn can be nil.\n\tclientHandledHistogramFn func() *prometheus.HistogramVec\n\t// clientStreamRecvHistogramFn can be nil.\n\tclientStreamRecvHistogramFn func() *prometheus.HistogramVec\n\t// clientStreamSendHistogramFn can be nil.\n\tclientStreamSendHistogramFn func() *prometheus.HistogramVec\n\t// contextLabels defines the names of dynamic labels to be extracted from context\n\tcontextLabels []string\n}\n\ntype ClientMetricsOption func(*clientMetricsConfig)\n\nfunc (c *clientMetricsConfig) apply(opts []ClientMetricsOption) {\n\tfor _, o := range opts {\n\t\to(c)\n\t}\n}\n\nfunc WithClientCounterOptions(opts ...CounterOption) ClientMetricsOption {\n\treturn func(o *clientMetricsConfig) {\n\t\to.counterOpts = opts\n\t}\n}\n\n// WithClientHandlingTimeHistogram turns on recording of handling time of RPCs.\n// Histogram metrics can be very expensive for Prometheus to retain and query.\nfunc WithClientHandlingTimeHistogram(opts ...HistogramOption) ClientMetricsOption {\n\treturn func(o *clientMetricsConfig) {\n\t\to.clientHandledHistogramFn = func() *prometheus.HistogramVec {\n\t\t\tdefaultLabels := []string{\"grpc_type\", \"grpc_service\", \"grpc_method\"}\n\t\t\tallLabels := append(defaultLabels, o.contextLabels...)\n\n\t\t\treturn prometheus.NewHistogramVec(\n\t\t\t\thistogramOptions(opts).apply(&prometheus.HistogramOpts{\n\t\t\t\t\tName:    \"grpc_client_handling_seconds\",\n\t\t\t\t\tHelp:    \"Histogram of response latency (seconds) of the gRPC until it is finished by the application.\",\n\t\t\t\t\tBuckets: prometheus.DefBuckets,\n\t\t\t\t}),\n\t\t\t\tallLabels,\n\t\t\t)\n\t\t}\n\t}\n}\n\n// WithClientStreamRecvHistogram turns on recording of single message receive time of streaming RPCs.\n// Histogram metrics can be very expensive for Prometheus to retain and query.\nfunc WithClientStreamRecvHistogram(opts ...HistogramOption) ClientMetricsOption {\n\treturn func(o *clientMetricsConfig) {\n\t\to.clientStreamRecvHistogramFn = func() *prometheus.HistogramVec {\n\t\t\tdefaultLabels := []string{\"grpc_type\", \"grpc_service\", \"grpc_method\"}\n\t\t\tallLabels := append(defaultLabels, o.contextLabels...)\n\n\t\t\treturn prometheus.NewHistogramVec(\n\t\t\t\thistogramOptions(opts).apply(&prometheus.HistogramOpts{\n\t\t\t\t\tName:    \"grpc_client_msg_recv_handling_seconds\",\n\t\t\t\t\tHelp:    \"Histogram of response latency (seconds) of the gRPC single message receive.\",\n\t\t\t\t\tBuckets: prometheus.DefBuckets,\n\t\t\t\t}),\n\t\t\t\tallLabels,\n\t\t\t)\n\t\t}\n\t}\n}\n\n// WithClientStreamSendHistogram turns on recording of single message send time of streaming RPCs.\n// Histogram metrics can be very expensive for Prometheus to retain and query.\nfunc WithClientStreamSendHistogram(opts ...HistogramOption) ClientMetricsOption {\n\treturn func(o *clientMetricsConfig) {\n\t\to.clientStreamSendHistogramFn = func() *prometheus.HistogramVec {\n\t\t\tdefaultLabels := []string{\"grpc_type\", \"grpc_service\", \"grpc_method\"}\n\t\t\tallLabels := append(defaultLabels, o.contextLabels...)\n\n\t\t\treturn prometheus.NewHistogramVec(\n\t\t\t\thistogramOptions(opts).apply(&prometheus.HistogramOpts{\n\t\t\t\t\tName:    \"grpc_client_msg_send_handling_seconds\",\n\t\t\t\t\tHelp:    \"Histogram of response latency (seconds) of the gRPC single message send.\",\n\t\t\t\t\tBuckets: prometheus.DefBuckets,\n\t\t\t\t}),\n\t\t\t\tallLabels,\n\t\t\t)\n\t\t}\n\t}\n}\n\n// WithClientContextLabels configures the server metrics to include dynamic labels extracted from context.\n// The provided label names will be added to all server metrics as dynamic labels.\n// Use WithLabelsFromContext in the interceptor options to specify how to extract these labels from context.\nfunc WithClientContextLabels(labelNames ...string) ClientMetricsOption {\n\treturn func(o *clientMetricsConfig) {\n\t\to.contextLabels = labelNames\n\t}\n}\n"
  },
  {
    "path": "providers/prometheus/client_test.go",
    "content": "// Copyright (c) The go-grpc-middleware Authors.\n// Licensed under the Apache License 2.0.\n\npackage prometheus\n\nimport (\n\t\"errors\"\n\t\"io\"\n\t\"testing\"\n\n\t\"github.com/grpc-ecosystem/go-grpc-middleware/v2/testing/testpb\"\n\t\"github.com/stretchr/testify/suite\"\n\t\"google.golang.org/grpc\"\n\t\"google.golang.org/grpc/codes\"\n\t\"google.golang.org/grpc/status\"\n)\n\nfunc TestClientInterceptorSuite(t *testing.T) {\n\tc := NewClientMetrics(WithClientHandlingTimeHistogram())\n\tsuite.Run(t, &ClientInterceptorTestSuite{\n\t\tInterceptorTestSuite: &testpb.InterceptorTestSuite{\n\t\t\tTestService: &testpb.TestPingService{},\n\t\t\tClientOpts: []grpc.DialOption{\n\t\t\t\tgrpc.WithUnaryInterceptor(c.UnaryClientInterceptor()),\n\t\t\t\tgrpc.WithStreamInterceptor(c.StreamClientInterceptor()),\n\t\t\t},\n\t\t},\n\t\tclientMetrics: c,\n\t})\n}\n\ntype ClientInterceptorTestSuite struct {\n\t*testpb.InterceptorTestSuite\n\tclientMetrics *ClientMetrics\n}\n\nfunc (s *ClientInterceptorTestSuite) SetupTest() {\n\ts.clientMetrics.clientStartedCounter.Reset()\n\ts.clientMetrics.clientHandledCounter.Reset()\n\ts.clientMetrics.clientHandledHistogram.Reset()\n\ts.clientMetrics.clientStreamMsgReceived.Reset()\n\ts.clientMetrics.clientStreamMsgSent.Reset()\n}\n\nfunc (s *ClientInterceptorTestSuite) TestUnaryIncrementsMetrics() {\n\t_, err := s.Client.PingEmpty(s.SimpleCtx(), &testpb.PingEmptyRequest{})\n\ts.Require().NoError(err)\n\n\trequireValue(s.T(), 1, s.clientMetrics.clientStartedCounter.WithLabelValues(\"unary\", testpb.TestServiceFullName, \"PingEmpty\"))\n\trequireValue(s.T(), 1, s.clientMetrics.clientHandledCounter.WithLabelValues(\"unary\", testpb.TestServiceFullName, \"PingEmpty\", \"OK\"))\n\trequireValueHistCount(s.T(), 1, s.clientMetrics.clientHandledHistogram.WithLabelValues(\"unary\", testpb.TestServiceFullName, \"PingEmpty\"))\n\n\t_, err = s.Client.PingError(s.SimpleCtx(), &testpb.PingErrorRequest{ErrorCodeReturned: uint32(codes.FailedPrecondition)})\n\ts.Require().Error(err)\n\trequireValue(s.T(), 1, s.clientMetrics.clientStartedCounter.WithLabelValues(\"unary\", testpb.TestServiceFullName, \"PingError\"))\n\trequireValue(s.T(), 1, s.clientMetrics.clientHandledCounter.WithLabelValues(\"unary\", testpb.TestServiceFullName, \"PingError\", \"FailedPrecondition\"))\n\trequireValueHistCount(s.T(), 1, s.clientMetrics.clientHandledHistogram.WithLabelValues(\"unary\", testpb.TestServiceFullName, \"PingError\"))\n}\n\nfunc (s *ClientInterceptorTestSuite) TestStartedStreamingIncrementsStarted() {\n\t_, err := s.Client.PingList(s.SimpleCtx(), &testpb.PingListRequest{})\n\ts.Require().NoError(err)\n\trequireValue(s.T(), 1, s.clientMetrics.clientStartedCounter.WithLabelValues(\"server_stream\", testpb.TestServiceFullName, \"PingList\"))\n\n\t_, err = s.Client.PingList(s.SimpleCtx(), &testpb.PingListRequest{ErrorCodeReturned: uint32(codes.FailedPrecondition)})\n\ts.Require().NoError(err, \"PingList must not fail immediately\")\n\trequireValue(s.T(), 2, s.clientMetrics.clientStartedCounter.WithLabelValues(\"server_stream\", testpb.TestServiceFullName, \"PingList\"))\n}\n\nfunc (s *ClientInterceptorTestSuite) TestStreamingIncrementsMetrics() {\n\tss, err := s.Client.PingList(s.SimpleCtx(), &testpb.PingListRequest{})\n\ts.Require().NoError(err)\n\t// Do a read, just for kicks.\n\tcount := 0\n\tfor {\n\t\t_, err = ss.Recv()\n\t\tif errors.Is(err, io.EOF) {\n\t\t\tbreak\n\t\t}\n\t\ts.Require().NoError(err, \"reading pingList shouldn't fail\")\n\t\tcount++\n\t}\n\ts.Require().Equal(testpb.ListResponseCount, count, \"Number of received msg on the wire must match\")\n\n\trequireValue(s.T(), 1, s.clientMetrics.clientStartedCounter.WithLabelValues(\"server_stream\", testpb.TestServiceFullName, \"PingList\"))\n\trequireValue(s.T(), 1, s.clientMetrics.clientHandledCounter.WithLabelValues(\"server_stream\", testpb.TestServiceFullName, \"PingList\", \"OK\"))\n\trequireValue(s.T(), testpb.ListResponseCount+1 /* + EOF */, s.clientMetrics.clientStreamMsgReceived.WithLabelValues(\"server_stream\", testpb.TestServiceFullName, \"PingList\"))\n\trequireValue(s.T(), 1, s.clientMetrics.clientStreamMsgSent.WithLabelValues(\"server_stream\", testpb.TestServiceFullName, \"PingList\"))\n\trequireValueHistCount(s.T(), 1, s.clientMetrics.clientHandledHistogram.WithLabelValues(\"server_stream\", testpb.TestServiceFullName, \"PingList\"))\n\n\tss, err = s.Client.PingList(s.SimpleCtx(), &testpb.PingListRequest{ErrorCodeReturned: uint32(codes.FailedPrecondition)})\n\ts.Require().NoError(err, \"PingList must not fail immediately\")\n\n\t// Do a read, just to propagate errors.\n\t_, err = ss.Recv()\n\tst, _ := status.FromError(err)\n\ts.Require().Equal(codes.FailedPrecondition, st.Code(), \"Recv must return FailedPrecondition, otherwise the test is wrong\")\n\n\trequireValue(s.T(), 2, s.clientMetrics.clientStartedCounter.WithLabelValues(\"server_stream\", testpb.TestServiceFullName, \"PingList\"))\n\trequireValue(s.T(), 1, s.clientMetrics.clientHandledCounter.WithLabelValues(\"server_stream\", testpb.TestServiceFullName, \"PingList\", \"FailedPrecondition\"))\n\trequireValueHistCount(s.T(), 2, s.clientMetrics.clientHandledHistogram.WithLabelValues(\"server_stream\", testpb.TestServiceFullName, \"PingList\"))\n}\n\nfunc (s *ClientInterceptorTestSuite) TestWithSubsystem() {\n\tcounterOpts := []CounterOption{\n\t\tWithSubsystem(\"subsystem1\"),\n\t}\n\thistOpts := []HistogramOption{\n\t\tWithHistogramSubsystem(\"subsystem1\"),\n\t}\n\tclientCounterOpts := WithClientCounterOptions(counterOpts...)\n\tclientMetrics := NewClientMetrics(clientCounterOpts, WithClientHandlingTimeHistogram(histOpts...))\n\n\trequireSubsystemName(s.T(), \"subsystem1\", clientMetrics.clientStartedCounter.WithLabelValues(\"unary\", testpb.TestServiceFullName, \"dummy\"))\n\trequireHistSubsystemName(s.T(), \"subsystem1\", clientMetrics.clientHandledHistogram.WithLabelValues(\"unary\", testpb.TestServiceFullName, \"dummy\"))\n}\n\nfunc (s *ClientInterceptorTestSuite) TestWithNamespace() {\n\tcounterOpts := []CounterOption{\n\t\tWithNamespace(\"namespace1\"),\n\t}\n\thistOpts := []HistogramOption{\n\t\tWithHistogramNamespace(\"namespace1\"),\n\t}\n\tclientCounterOpts := WithClientCounterOptions(counterOpts...)\n\tclientMetrics := NewClientMetrics(clientCounterOpts, WithClientHandlingTimeHistogram(histOpts...))\n\n\trequireNamespaceName(s.T(), \"namespace1\", clientMetrics.clientStartedCounter.WithLabelValues(\"unary\", testpb.TestServiceFullName, \"dummy\"))\n\trequireHistNamespaceName(s.T(), \"namespace1\", clientMetrics.clientHandledHistogram.WithLabelValues(\"unary\", testpb.TestServiceFullName, \"dummy\"))\n}\n"
  },
  {
    "path": "providers/prometheus/constants.go",
    "content": "// Copyright (c) The go-grpc-middleware Authors.\n// Licensed under the Apache License 2.0.\n\npackage prometheus\n\ntype grpcType string\n\n// grpcType describes all types of grpc connection.\nconst (\n\tUnary        grpcType = \"unary\"\n\tClientStream grpcType = \"client_stream\"\n\tServerStream grpcType = \"server_stream\"\n\tBidiStream   grpcType = \"bidi_stream\"\n)\n\n// Kind describes whether interceptor is a client or server type.\ntype Kind string\n\n// Enum for Client and Server Kind.\nconst (\n\tKindClient Kind = \"client\"\n\tKindServer Kind = \"server\"\n)\n"
  },
  {
    "path": "providers/prometheus/context_labels_test.go",
    "content": "// Copyright (c) The go-grpc-middleware Authors.\n// Licensed under the Apache License 2.0.\n\npackage prometheus\n\nimport (\n\t\"context\"\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/grpc-ecosystem/go-grpc-middleware/v2/interceptors\"\n\t\"github.com/prometheus/client_golang/prometheus\"\n\tdto \"github.com/prometheus/client_model/go\"\n\t\"github.com/stretchr/testify/assert\"\n\t\"github.com/stretchr/testify/require\"\n\t\"google.golang.org/grpc/codes\"\n)\n\nfunc TestServerContextLabels(t *testing.T) {\n\t// Create server metrics with context labels\n\tserverMetrics := NewServerMetrics(\n\t\tWithContextLabels(\"user_id\", \"tenant_id\"),\n\t)\n\n\t// Create a custom registry to isolate this test\n\treg := prometheus.NewRegistry()\n\treg.MustRegister(serverMetrics)\n\n\t// Create a mock context with label values\n\tctx := context.Background()\n\n\t// Create the labels extraction function\n\tlabelsFromCtx := func(ctx context.Context) prometheus.Labels {\n\t\treturn prometheus.Labels{\n\t\t\t\"user_id\":   \"user123\",\n\t\t\t\"tenant_id\": \"tenant456\",\n\t\t}\n\t}\n\n\t// Create a reporter with the labels function\n\trep := &reportable{\n\t\tserverMetrics: serverMetrics,\n\t\topts:          []Option{WithLabelsFromContext(labelsFromCtx)},\n\t}\n\n\t// Simulate a server call\n\tmeta := interceptors.CallMeta{\n\t\tTyp:     interceptors.Unary,\n\t\tService: \"testpb.PingService\",\n\t\tMethod:  \"Ping\",\n\t}\n\n\treporter, _ := rep.ServerReporter(ctx, meta)\n\n\t// Simulate call completion\n\treporter.PostCall(nil, time.Millisecond*100)\n\n\t// Collect metrics\n\tmetricFamilies, err := reg.Gather()\n\trequire.NoError(t, err)\n\n\t// Find the handled counter metric\n\tvar handledCounter *dto.MetricFamily\n\tfor _, mf := range metricFamilies {\n\t\tif *mf.Name == \"grpc_server_handled_total\" {\n\t\t\thandledCounter = mf\n\t\t\tbreak\n\t\t}\n\t}\n\n\trequire.NotNil(t, handledCounter, \"Should find grpc_server_handled_total metric\")\n\trequire.Len(t, handledCounter.Metric, 1, \"Should have one metric sample\")\n\n\t// Verify the metric has all expected labels\n\tmetric := handledCounter.Metric[0]\n\tlabelMap := make(map[string]string)\n\tfor _, label := range metric.Label {\n\t\tlabelMap[*label.Name] = *label.Value\n\t}\n\n\t// Check standard labels\n\tassert.Equal(t, \"unary\", labelMap[\"grpc_type\"])\n\tassert.Equal(t, \"testpb.PingService\", labelMap[\"grpc_service\"])\n\tassert.Equal(t, \"Ping\", labelMap[\"grpc_method\"])\n\tassert.Equal(t, codes.OK.String(), labelMap[\"grpc_code\"])\n\n\t// Check context labels\n\tassert.Equal(t, \"user123\", labelMap[\"user_id\"])\n\tassert.Equal(t, \"tenant456\", labelMap[\"tenant_id\"])\n\n\t// Verify metric value\n\tassert.InDelta(t, float64(1), *metric.Counter.Value, 0.0001, \"Metric value should be 1\")\n}\n\nfunc TestClientContextLabels(t *testing.T) {\n\t// Create client metrics with context labels\n\tclientMetrics := NewClientMetrics(\n\t\tWithClientContextLabels(\"user_id\", \"tenant_id\"),\n\t)\n\n\t// Create a custom registry to isolate this test\n\treg := prometheus.NewRegistry()\n\treg.MustRegister(clientMetrics)\n\n\t// Create a mock context with label values\n\tctx := context.Background()\n\n\t// Create the labels extraction function\n\tlabelsFromCtx := func(ctx context.Context) prometheus.Labels {\n\t\treturn prometheus.Labels{\n\t\t\t\"user_id\":   \"user123\",\n\t\t\t\"tenant_id\": \"tenant456\",\n\t\t}\n\t}\n\n\t// Create a reporter with the labels function\n\trep := &reportable{\n\t\tclientMetrics: clientMetrics,\n\t\topts:          []Option{WithLabelsFromContext(labelsFromCtx)},\n\t}\n\n\t// Simulate a server call\n\tmeta := interceptors.CallMeta{\n\t\tTyp:     interceptors.Unary,\n\t\tService: \"testpb.PingService\",\n\t\tMethod:  \"Ping\",\n\t}\n\n\treporter, _ := rep.ClientReporter(ctx, meta)\n\n\t// Simulate call completion\n\treporter.PostCall(nil, time.Millisecond*100)\n\n\t// Collect metrics\n\tmetricFamilies, err := reg.Gather()\n\trequire.NoError(t, err)\n\n\t// Find the handled counter metric\n\tvar handledCounter *dto.MetricFamily\n\tfor _, mf := range metricFamilies {\n\t\tif *mf.Name == \"grpc_client_handled_total\" {\n\t\t\thandledCounter = mf\n\t\t\tbreak\n\t\t}\n\t}\n\n\trequire.NotNil(t, handledCounter, \"Should find grpc_server_handled_total metric\")\n\trequire.Len(t, handledCounter.Metric, 1, \"Should have one metric sample\")\n\n\t// Verify the metric has all expected labels\n\tmetric := handledCounter.Metric[0]\n\tlabelMap := make(map[string]string)\n\tfor _, label := range metric.Label {\n\t\tlabelMap[*label.Name] = *label.Value\n\t}\n\n\t// Check standard labels\n\tassert.Equal(t, \"unary\", labelMap[\"grpc_type\"])\n\tassert.Equal(t, \"testpb.PingService\", labelMap[\"grpc_service\"])\n\tassert.Equal(t, \"Ping\", labelMap[\"grpc_method\"])\n\tassert.Equal(t, codes.OK.String(), labelMap[\"grpc_code\"])\n\n\t// Check context labels\n\tassert.Equal(t, \"user123\", labelMap[\"user_id\"])\n\tassert.Equal(t, \"tenant456\", labelMap[\"tenant_id\"])\n\n\t// Verify metric value\n\tassert.InDelta(t, float64(1), *metric.Counter.Value, 0.0001, \"Metric value should be 1\")\n}\n\nfunc TestServerContextLabelsWithMissingValues(t *testing.T) {\n\t// Create server metrics with context labels\n\tserverMetrics := NewServerMetrics(\n\t\tWithContextLabels(\"user_id\", \"missing_label\"),\n\t)\n\n\t// Create a custom registry to isolate this test\n\treg := prometheus.NewRegistry()\n\treg.MustRegister(serverMetrics)\n\n\t// Create a mock context with only partial label values\n\tctx := context.Background()\n\n\t// Create the labels extraction function that only returns one label\n\tlabelsFromCtx := func(ctx context.Context) prometheus.Labels {\n\t\treturn prometheus.Labels{\n\t\t\t\"user_id\": \"user123\",\n\t\t\t// missing_label is not provided\n\t\t}\n\t}\n\n\t// Create a reporter with the labels function\n\trep := &reportable{\n\t\tserverMetrics: serverMetrics,\n\t\topts:          []Option{WithLabelsFromContext(labelsFromCtx)},\n\t}\n\n\t// Simulate a server call\n\tmeta := interceptors.CallMeta{\n\t\tTyp:     interceptors.Unary,\n\t\tService: \"testpb.PingService\",\n\t\tMethod:  \"Ping\",\n\t}\n\n\treporter, _ := rep.ServerReporter(ctx, meta)\n\n\t// Simulate call completion\n\treporter.PostCall(nil, time.Millisecond*100)\n\n\t// Collect metrics\n\tmetricFamilies, err := reg.Gather()\n\trequire.NoError(t, err)\n\n\t// Find the handled counter metric\n\tvar handledCounter *dto.MetricFamily\n\tfor _, mf := range metricFamilies {\n\t\tif *mf.Name == \"grpc_server_handled_total\" {\n\t\t\thandledCounter = mf\n\t\t\tbreak\n\t\t}\n\t}\n\n\trequire.NotNil(t, handledCounter, \"Should find grpc_server_handled_total metric\")\n\trequire.Len(t, handledCounter.Metric, 1, \"Should have one metric sample\")\n\n\t// Verify the metric has all expected labels\n\tmetric := handledCounter.Metric[0]\n\tlabelMap := make(map[string]string)\n\tfor _, label := range metric.Label {\n\t\tlabelMap[*label.Name] = *label.Value\n\t}\n\n\t// Check standard labels\n\tassert.Equal(t, \"unary\", labelMap[\"grpc_type\"])\n\tassert.Equal(t, \"testpb.PingService\", labelMap[\"grpc_service\"])\n\tassert.Equal(t, \"Ping\", labelMap[\"grpc_method\"])\n\tassert.Equal(t, codes.OK.String(), labelMap[\"grpc_code\"])\n\n\t// Check context labels - user_id should be present, missing_label should be empty\n\tassert.Equal(t, \"user123\", labelMap[\"user_id\"])\n\tassert.Empty(t, labelMap[\"missing_label\"])\n\n\t// Verify metric value\n\tassert.InDelta(t, float64(1), *metric.Counter.Value, 0.0001, \"Metric value should be 1\")\n}\n\nfunc TestClientContextLabelsWithMissingValues(t *testing.T) {\n\t// Create client metrics with context labels\n\tclientMetrics := NewClientMetrics(\n\t\tWithClientContextLabels(\"user_id\", \"missing_label\"),\n\t)\n\n\t// Create a custom registry to isolate this test\n\treg := prometheus.NewRegistry()\n\treg.MustRegister(clientMetrics)\n\n\t// Create a mock context with only partial label values\n\tctx := context.Background()\n\n\t// Create the labels extraction function that only returns one label\n\tlabelsFromCtx := func(ctx context.Context) prometheus.Labels {\n\t\treturn prometheus.Labels{\n\t\t\t\"user_id\": \"user123\",\n\t\t\t// missing_label is not provided\n\t\t}\n\t}\n\n\t// Create a reporter with the labels function\n\trep := &reportable{\n\t\tclientMetrics: clientMetrics,\n\t\topts:          []Option{WithLabelsFromContext(labelsFromCtx)},\n\t}\n\n\t// Simulate a server call\n\tmeta := interceptors.CallMeta{\n\t\tTyp:     interceptors.Unary,\n\t\tService: \"testpb.PingService\",\n\t\tMethod:  \"Ping\",\n\t}\n\n\treporter, _ := rep.ClientReporter(ctx, meta)\n\n\t// Simulate call completion\n\treporter.PostCall(nil, time.Millisecond*100)\n\n\t// Collect metrics\n\tmetricFamilies, err := reg.Gather()\n\trequire.NoError(t, err)\n\n\t// Find the handled counter metric\n\tvar handledCounter *dto.MetricFamily\n\tfor _, mf := range metricFamilies {\n\t\tif *mf.Name == \"grpc_client_handled_total\" {\n\t\t\thandledCounter = mf\n\t\t\tbreak\n\t\t}\n\t}\n\n\trequire.NotNil(t, handledCounter, \"Should find grpc_server_handled_total metric\")\n\trequire.Len(t, handledCounter.Metric, 1, \"Should have one metric sample\")\n\n\t// Verify the metric has all expected labels\n\tmetric := handledCounter.Metric[0]\n\tlabelMap := make(map[string]string)\n\tfor _, label := range metric.Label {\n\t\tlabelMap[*label.Name] = *label.Value\n\t}\n\n\t// Check standard labels\n\tassert.Equal(t, \"unary\", labelMap[\"grpc_type\"])\n\tassert.Equal(t, \"testpb.PingService\", labelMap[\"grpc_service\"])\n\tassert.Equal(t, \"Ping\", labelMap[\"grpc_method\"])\n\tassert.Equal(t, codes.OK.String(), labelMap[\"grpc_code\"])\n\n\t// Check context labels - user_id should be present, missing_label should be empty\n\tassert.Equal(t, \"user123\", labelMap[\"user_id\"])\n\tassert.Empty(t, labelMap[\"missing_label\"])\n\n\t// Verify metric value\n\tassert.InDelta(t, float64(1), *metric.Counter.Value, 0.0001, \"Metric value should be 1\")\n}\n\nfunc TestServerContextLabelsWithHistogram(t *testing.T) {\n\t// Create server metrics with context labels and histogram enabled\n\tserverMetrics := NewServerMetrics(\n\t\tWithContextLabels(\"user_id\"),\n\t\tWithServerHandlingTimeHistogram(),\n\t)\n\n\t// Create a custom registry to isolate this test\n\treg := prometheus.NewRegistry()\n\treg.MustRegister(serverMetrics)\n\n\t// Create a mock context with label values\n\tctx := context.Background()\n\n\t// Create the labels extraction function\n\tlabelsFromCtx := func(ctx context.Context) prometheus.Labels {\n\t\treturn prometheus.Labels{\n\t\t\t\"user_id\": \"user123\",\n\t\t}\n\t}\n\n\t// Create a reporter with the labels function\n\trep := &reportable{\n\t\tserverMetrics: serverMetrics,\n\t\topts:          []Option{WithLabelsFromContext(labelsFromCtx)},\n\t}\n\n\t// Simulate a server call\n\tmeta := interceptors.CallMeta{\n\t\tTyp:     interceptors.Unary,\n\t\tService: \"testpb.PingService\",\n\t\tMethod:  \"Ping\",\n\t}\n\n\treporter, _ := rep.ServerReporter(ctx, meta)\n\n\t// Simulate call completion\n\treporter.PostCall(nil, time.Millisecond*100)\n\n\t// Collect metrics\n\tmetricFamilies, err := reg.Gather()\n\trequire.NoError(t, err)\n\n\t// Find the histogram metric\n\tvar histogram *dto.MetricFamily\n\tfor _, mf := range metricFamilies {\n\t\tif *mf.Name == \"grpc_server_handling_seconds\" {\n\t\t\thistogram = mf\n\t\t\tbreak\n\t\t}\n\t}\n\n\trequire.NotNil(t, histogram, \"Should find grpc_server_handling_seconds metric\")\n\trequire.Len(t, histogram.Metric, 1, \"Should have one metric sample\")\n\n\t// Verify the histogram has all expected labels\n\tmetric := histogram.Metric[0]\n\tlabelMap := make(map[string]string)\n\tfor _, label := range metric.Label {\n\t\tlabelMap[*label.Name] = *label.Value\n\t}\n\n\t// Check standard labels\n\tassert.Equal(t, \"unary\", labelMap[\"grpc_type\"])\n\tassert.Equal(t, \"testpb.PingService\", labelMap[\"grpc_service\"])\n\tassert.Equal(t, \"Ping\", labelMap[\"grpc_method\"])\n\n\t// Check context labels\n\tassert.Equal(t, \"user123\", labelMap[\"user_id\"])\n\n\t// Verify histogram has recorded a sample\n\tassert.Equal(t, uint64(1), *metric.Histogram.SampleCount)\n}\n\nfunc TestClientContextLabelsWithHistogram(t *testing.T) {\n\t// Create client metrics with context labels and histogram enabled\n\tclientMetrics := NewClientMetrics(\n\t\tWithClientContextLabels(\"user_id\"),\n\t\tWithClientHandlingTimeHistogram(),\n\t)\n\n\t// Create a custom registry to isolate this test\n\treg := prometheus.NewRegistry()\n\treg.MustRegister(clientMetrics)\n\n\t// Create a mock context with label values\n\tctx := context.Background()\n\n\t// Create the labels extraction function\n\tlabelsFromCtx := func(ctx context.Context) prometheus.Labels {\n\t\treturn prometheus.Labels{\n\t\t\t\"user_id\": \"user123\",\n\t\t}\n\t}\n\n\t// Create a reporter with the labels function\n\trep := &reportable{\n\t\tclientMetrics: clientMetrics,\n\t\topts:          []Option{WithLabelsFromContext(labelsFromCtx)},\n\t}\n\n\t// Simulate a server call\n\tmeta := interceptors.CallMeta{\n\t\tTyp:     interceptors.Unary,\n\t\tService: \"testpb.PingService\",\n\t\tMethod:  \"Ping\",\n\t}\n\n\treporter, _ := rep.ClientReporter(ctx, meta)\n\n\t// Simulate call completion\n\treporter.PostCall(nil, time.Millisecond*100)\n\n\t// Collect metrics\n\tmetricFamilies, err := reg.Gather()\n\trequire.NoError(t, err)\n\n\t// Find the histogram metric\n\tvar histogram *dto.MetricFamily\n\tfor _, mf := range metricFamilies {\n\t\tif *mf.Name == \"grpc_client_handling_seconds\" {\n\t\t\thistogram = mf\n\t\t\tbreak\n\t\t}\n\t}\n\n\trequire.NotNil(t, histogram, \"Should find grpc_server_handling_seconds metric\")\n\trequire.Len(t, histogram.Metric, 1, \"Should have one metric sample\")\n\n\t// Verify the histogram has all expected labels\n\tmetric := histogram.Metric[0]\n\tlabelMap := make(map[string]string)\n\tfor _, label := range metric.Label {\n\t\tlabelMap[*label.Name] = *label.Value\n\t}\n\n\t// Check standard labels\n\tassert.Equal(t, \"unary\", labelMap[\"grpc_type\"])\n\tassert.Equal(t, \"testpb.PingService\", labelMap[\"grpc_service\"])\n\tassert.Equal(t, \"Ping\", labelMap[\"grpc_method\"])\n\n\t// Check context labels\n\tassert.Equal(t, \"user123\", labelMap[\"user_id\"])\n\n\t// Verify histogram has recorded a sample\n\tassert.Equal(t, uint64(1), *metric.Histogram.SampleCount)\n}\n"
  },
  {
    "path": "providers/prometheus/doc.go",
    "content": "// Copyright (c) The go-grpc-middleware Authors.\n// Licensed under the Apache License 2.0.\n\n/*\nPackage prometheus provides a standalone interceptor for metrics. It's next iteration of deprecated https://github.com/grpc-ecosystem/go-grpc-prometheus.\nSee https://github.com/grpc-ecosystem/go-grpc-middleware/tree/main/examples for example.\n*/\npackage prometheus\n"
  },
  {
    "path": "providers/prometheus/go.mod",
    "content": "module github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus\n\ngo 1.23.0\n\nrequire (\n\tgithub.com/grpc-ecosystem/go-grpc-middleware/v2 v2.1.0\n\tgithub.com/prometheus/client_golang v1.14.0\n\tgithub.com/prometheus/client_model v0.3.0\n\tgithub.com/stretchr/testify v1.8.4\n\tgoogle.golang.org/grpc v1.74.2\n\n)\n\nrequire (\n\tgithub.com/beorn7/perks v1.0.1 // indirect\n\tgithub.com/cespare/xxhash/v2 v2.3.0 // indirect\n\tgithub.com/davecgh/go-spew v1.1.1 // indirect\n\tgithub.com/golang/protobuf v1.5.4 // indirect\n\tgithub.com/matttproud/golang_protobuf_extensions v1.0.1 // indirect\n\tgithub.com/pmezard/go-difflib v1.0.0 // indirect\n\tgithub.com/prometheus/common v0.37.0 // indirect\n\tgithub.com/prometheus/procfs v0.8.0 // indirect\n\tgolang.org/x/net v0.40.0 // indirect\n\tgolang.org/x/sys v0.33.0 // indirect\n\tgolang.org/x/text v0.25.0 // indirect\n\tgoogle.golang.org/genproto/googleapis/rpc v0.0.0-20250528174236-200df99c418a // indirect\n\tgoogle.golang.org/protobuf v1.36.6 // indirect\n\tgopkg.in/yaml.v3 v3.0.1 // indirect\n)\n"
  },
  {
    "path": "providers/prometheus/go.sum",
    "content": "cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=\ncloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=\ncloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU=\ncloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU=\ncloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY=\ncloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc=\ncloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0=\ncloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To=\ncloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4=\ncloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M=\ncloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc=\ncloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk=\ncloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs=\ncloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc=\ncloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY=\ncloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o=\ncloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE=\ncloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc=\ncloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg=\ncloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc=\ncloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ=\ncloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE=\ncloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk=\ncloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I=\ncloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw=\ncloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA=\ncloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU=\ncloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw=\ncloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos=\ncloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk=\ncloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs=\ncloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0=\ndmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=\ngithub.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=\ngithub.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=\ngithub.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=\ngithub.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=\ngithub.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=\ngithub.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=\ngithub.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho=\ngithub.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=\ngithub.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=\ngithub.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=\ngithub.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=\ngithub.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=\ngithub.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=\ngithub.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=\ngithub.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=\ngithub.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=\ngithub.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=\ngithub.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=\ngithub.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=\ngithub.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=\ngithub.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=\ngithub.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=\ngithub.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=\ngithub.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=\ngithub.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=\ngithub.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=\ngithub.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=\ngithub.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=\ngithub.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=\ngithub.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=\ngithub.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=\ngithub.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=\ngithub.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=\ngithub.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY=\ngithub.com/go-kit/log v0.2.0/go.mod h1:NwTd00d/i8cPZ3xOwwiv2PO5MOcx78fFErGNcVmBjv0=\ngithub.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=\ngithub.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=\ngithub.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A=\ngithub.com/go-logfmt/logfmt v0.5.1/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs=\ngithub.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI=\ngithub.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=\ngithub.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=\ngithub.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=\ngithub.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=\ngithub.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=\ngithub.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=\ngithub.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=\ngithub.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=\ngithub.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=\ngithub.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=\ngithub.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=\ngithub.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y=\ngithub.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=\ngithub.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=\ngithub.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=\ngithub.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4=\ngithub.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=\ngithub.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=\ngithub.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=\ngithub.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=\ngithub.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=\ngithub.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk=\ngithub.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=\ngithub.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=\ngithub.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs=\ngithub.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w=\ngithub.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=\ngithub.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8=\ngithub.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=\ngithub.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=\ngithub.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=\ngithub.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=\ngithub.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek=\ngithub.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps=\ngithub.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=\ngithub.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=\ngithub.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=\ngithub.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=\ngithub.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=\ngithub.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=\ngithub.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=\ngithub.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=\ngithub.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=\ngithub.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=\ngithub.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=\ngithub.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=\ngithub.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=\ngithub.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=\ngithub.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=\ngithub.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=\ngithub.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=\ngithub.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=\ngithub.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=\ngithub.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=\ngithub.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=\ngithub.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=\ngithub.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=\ngithub.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=\ngithub.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=\ngithub.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=\ngithub.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=\ngithub.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=\ngithub.com/grpc-ecosystem/go-grpc-middleware/v2 v2.1.0 h1:pRhl55Yx1eC7BZ1N+BBWwnKaMyD8uC+34TLdndZMAKk=\ngithub.com/grpc-ecosystem/go-grpc-middleware/v2 v2.1.0/go.mod h1:XKMd7iuf/RGPSMJ/U4HP0zS2Z9Fh8Ps9a+6X26m/tmI=\ngithub.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=\ngithub.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=\ngithub.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=\ngithub.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4=\ngithub.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=\ngithub.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=\ngithub.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=\ngithub.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=\ngithub.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=\ngithub.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk=\ngithub.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=\ngithub.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM=\ngithub.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=\ngithub.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=\ngithub.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=\ngithub.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=\ngithub.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=\ngithub.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=\ngithub.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=\ngithub.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=\ngithub.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=\ngithub.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU=\ngithub.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=\ngithub.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=\ngithub.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=\ngithub.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=\ngithub.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=\ngithub.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=\ngithub.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=\ngithub.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=\ngithub.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=\ngithub.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=\ngithub.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=\ngithub.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=\ngithub.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=\ngithub.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=\ngithub.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo=\ngithub.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M=\ngithub.com/prometheus/client_golang v1.11.0/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0=\ngithub.com/prometheus/client_golang v1.12.1/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY=\ngithub.com/prometheus/client_golang v1.14.0 h1:nJdhIvne2eSX/XRAFV9PcvFFRbrjbcTUj0VP62TMhnw=\ngithub.com/prometheus/client_golang v1.14.0/go.mod h1:8vpkKitgIVNcqrRBWh1C4TIUQgYNtG/XQE4E/Zae36Y=\ngithub.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=\ngithub.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=\ngithub.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=\ngithub.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=\ngithub.com/prometheus/client_model v0.3.0 h1:UBgGFHqYdG/TPFD1B1ogZywDqEkwp3fBMvqdiQ7Xew4=\ngithub.com/prometheus/client_model v0.3.0/go.mod h1:LDGWKZIo7rky3hgvBe+caln+Dr3dPggB5dvjtD7w9+w=\ngithub.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=\ngithub.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo=\ngithub.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc=\ngithub.com/prometheus/common v0.32.1/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls=\ngithub.com/prometheus/common v0.37.0 h1:ccBbHCgIiT9uSoFY0vX8H3zsNR5eLt17/RQLUvn8pXE=\ngithub.com/prometheus/common v0.37.0/go.mod h1:phzohg0JFMnBEFGxTDbfu3QyL5GI8gTQJFhYO5B3mfA=\ngithub.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=\ngithub.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=\ngithub.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU=\ngithub.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA=\ngithub.com/prometheus/procfs v0.7.3/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA=\ngithub.com/prometheus/procfs v0.8.0 h1:ODq8ZFEaYeCaZOJlZZdJA2AbQR98dSHSM1KW/You5mo=\ngithub.com/prometheus/procfs v0.8.0/go.mod h1:z7EfXMXOkbkqb9IINtpCn86r/to3BnA0uaxHdg830/4=\ngithub.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=\ngithub.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=\ngithub.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=\ngithub.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88=\ngithub.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=\ngithub.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=\ngithub.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=\ngithub.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=\ngithub.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=\ngithub.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=\ngithub.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=\ngithub.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=\ngithub.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=\ngithub.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=\ngo.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=\ngo.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8=\ngo.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=\ngo.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=\ngo.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=\ngo.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA=\ngo.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A=\ngo.opentelemetry.io/otel v1.36.0 h1:UumtzIklRBY6cI/lllNZlALOF5nNIzJVb16APdvgTXg=\ngo.opentelemetry.io/otel v1.36.0/go.mod h1:/TcFMXYjyRNh8khOAO9ybYkqaDBb/70aVwkNML4pP8E=\ngo.opentelemetry.io/otel/metric v1.36.0 h1:MoWPKVhQvJ+eeXWHFBOPoBOi20jh6Iq2CcCREuTYufE=\ngo.opentelemetry.io/otel/metric v1.36.0/go.mod h1:zC7Ks+yeyJt4xig9DEw9kuUFe5C3zLbVjV2PzT6qzbs=\ngo.opentelemetry.io/otel/sdk v1.36.0 h1:b6SYIuLRs88ztox4EyrvRti80uXIFy+Sqzoh9kFULbs=\ngo.opentelemetry.io/otel/sdk v1.36.0/go.mod h1:+lC+mTgD+MUWfjJubi2vvXWcVxyr9rmlshZni72pXeY=\ngo.opentelemetry.io/otel/sdk/metric v1.36.0 h1:r0ntwwGosWGaa0CrSt8cuNuTcccMXERFwHX4dThiPis=\ngo.opentelemetry.io/otel/sdk/metric v1.36.0/go.mod h1:qTNOhFDfKRwX0yXOqJYegL5WRaW376QbB7P4Pb0qva4=\ngo.opentelemetry.io/otel/trace v1.36.0 h1:ahxWNuqZjpdiFAyrIoQ4GIiAIhxAunQR6MUoKrsNd4w=\ngo.opentelemetry.io/otel/trace v1.36.0/go.mod h1:gQ+OnDZzrybY4k4seLzPAWNwVBBVlF2szhehOBB/tGA=\ngolang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=\ngolang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=\ngolang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=\ngolang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=\ngolang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=\ngolang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=\ngolang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=\ngolang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=\ngolang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=\ngolang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek=\ngolang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY=\ngolang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=\ngolang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=\ngolang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=\ngolang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM=\ngolang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU=\ngolang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=\ngolang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=\ngolang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=\ngolang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=\ngolang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=\ngolang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=\ngolang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=\ngolang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=\ngolang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=\ngolang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs=\ngolang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=\ngolang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=\ngolang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE=\ngolang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o=\ngolang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=\ngolang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY=\ngolang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=\ngolang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=\ngolang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=\ngolang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=\ngolang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=\ngolang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=\ngolang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=\ngolang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=\ngolang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=\ngolang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=\ngolang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=\ngolang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=\ngolang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=\ngolang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=\ngolang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=\ngolang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=\ngolang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=\ngolang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=\ngolang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=\ngolang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=\ngolang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=\ngolang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=\ngolang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=\ngolang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=\ngolang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=\ngolang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=\ngolang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=\ngolang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=\ngolang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=\ngolang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=\ngolang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=\ngolang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=\ngolang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=\ngolang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=\ngolang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=\ngolang.org/x/net v0.40.0 h1:79Xs7wF06Gbdcg4kdCCIQArK11Z1hr5POQ6+fIYHNuY=\ngolang.org/x/net v0.40.0/go.mod h1:y0hY0exeL2Pku80/zKK7tpntoX23cqL3Oa6njdgRtds=\ngolang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=\ngolang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=\ngolang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=\ngolang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=\ngolang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=\ngolang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=\ngolang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc=\ngolang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=\ngolang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=\ngolang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=\ngolang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=\ngolang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.33.0 h1:q3i8TbbEz+JRD9ywIRlyRAQbM0qF7hu24q3teo2hbuw=\ngolang.org/x/sys v0.33.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=\ngolang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=\ngolang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=\ngolang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=\ngolang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=\ngolang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=\ngolang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=\ngolang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=\ngolang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=\ngolang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=\ngolang.org/x/text v0.25.0 h1:qVyWApTSYLk/drJRO5mDlNYskwQznZmkpV2c8q9zls4=\ngolang.org/x/text v0.25.0/go.mod h1:WEdwpYrmk1qmdHvhkSTNPm3app7v4rsT8F2UD6+VHIA=\ngolang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=\ngolang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=\ngolang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=\ngolang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=\ngolang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=\ngolang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=\ngolang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=\ngolang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=\ngolang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=\ngolang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=\ngolang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=\ngolang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=\ngolang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=\ngolang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=\ngolang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=\ngolang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=\ngolang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=\ngolang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=\ngolang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=\ngolang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=\ngolang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=\ngolang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=\ngolang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=\ngolang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=\ngolang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=\ngolang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=\ngolang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=\ngolang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=\ngolang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=\ngolang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=\ngolang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=\ngolang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=\ngolang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=\ngolang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw=\ngolang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw=\ngolang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8=\ngolang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=\ngolang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=\ngolang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=\ngolang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=\ngolang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=\ngolang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=\ngolang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=\ngolang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=\ngolang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=\ngolang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=\ngolang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=\ngoogle.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE=\ngoogle.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M=\ngoogle.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=\ngoogle.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=\ngoogle.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=\ngoogle.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=\ngoogle.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=\ngoogle.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=\ngoogle.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=\ngoogle.golang.org/api v0.19.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=\ngoogle.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=\ngoogle.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=\ngoogle.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE=\ngoogle.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE=\ngoogle.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM=\ngoogle.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc=\ngoogle.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=\ngoogle.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=\ngoogle.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=\ngoogle.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0=\ngoogle.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=\ngoogle.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=\ngoogle.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=\ngoogle.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=\ngoogle.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=\ngoogle.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=\ngoogle.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=\ngoogle.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=\ngoogle.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=\ngoogle.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8=\ngoogle.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=\ngoogle.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=\ngoogle.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=\ngoogle.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=\ngoogle.golang.org/genproto v0.0.0-20200115191322-ca5a22157cba/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=\ngoogle.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=\ngoogle.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA=\ngoogle.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=\ngoogle.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=\ngoogle.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=\ngoogle.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=\ngoogle.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=\ngoogle.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=\ngoogle.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=\ngoogle.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=\ngoogle.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U=\ngoogle.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=\ngoogle.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA=\ngoogle.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=\ngoogle.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=\ngoogle.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=\ngoogle.golang.org/genproto/googleapis/rpc v0.0.0-20250528174236-200df99c418a h1:v2PbRU4K3llS09c7zodFpNePeamkAwG3mPrAery9VeE=\ngoogle.golang.org/genproto/googleapis/rpc v0.0.0-20250528174236-200df99c418a/go.mod h1:qQ0YXyHHx3XkvlzUtpXDkS29lDSafHMZBAZDc03LQ3A=\ngoogle.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=\ngoogle.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=\ngoogle.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=\ngoogle.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=\ngoogle.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=\ngoogle.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=\ngoogle.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=\ngoogle.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=\ngoogle.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60=\ngoogle.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk=\ngoogle.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=\ngoogle.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=\ngoogle.golang.org/grpc v1.74.2 h1:WoosgB65DlWVC9FqI82dGsZhWFNBSLjQ84bjROOpMu4=\ngoogle.golang.org/grpc v1.74.2/go.mod h1:CtQ+BGjaAIXHs/5YS3i473GqwBBa1zGQNevxdeBEXrM=\ngoogle.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=\ngoogle.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=\ngoogle.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=\ngoogle.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE=\ngoogle.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=\ngoogle.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=\ngoogle.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=\ngoogle.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=\ngoogle.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4=\ngoogle.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=\ngoogle.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=\ngoogle.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=\ngoogle.golang.org/protobuf v1.36.6 h1:z1NpPI8ku2WgiWnf+t9wTPsn6eP1L7ksHUlkfLvd9xY=\ngoogle.golang.org/protobuf v1.36.6/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY=\ngopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=\ngopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=\ngopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=\ngopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo=\ngopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=\ngopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=\ngopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=\ngopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=\ngopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=\ngopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=\ngopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=\ngopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=\ngopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=\ngopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=\nhonnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=\nhonnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=\nhonnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=\nhonnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=\nhonnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=\nhonnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=\nhonnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=\nrsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=\nrsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=\nrsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=\n"
  },
  {
    "path": "providers/prometheus/options.go",
    "content": "// Copyright (c) The go-grpc-middleware Authors.\n// Licensed under the Apache License 2.0.\n\npackage prometheus\n\nimport (\n\t\"github.com/prometheus/client_golang/prometheus\"\n\t\"google.golang.org/grpc\"\n\t\"google.golang.org/grpc/status\"\n)\n\n// FromError returns a grpc status. If the error code is neither a valid grpc status nor a context error, codes.Unknown\n// will be set.\nfunc FromError(err error) *status.Status {\n\ts, ok := status.FromError(err)\n\t// Mirror what the grpc server itself does, i.e. also convert context errors to status\n\tif !ok {\n\t\ts = status.FromContextError(err)\n\t}\n\treturn s\n}\n\n// A CounterOption lets you add options to Counter metrics using With* funcs.\ntype CounterOption func(*prometheus.CounterOpts)\n\ntype counterOptions []CounterOption\n\nfunc (co counterOptions) apply(o prometheus.CounterOpts) prometheus.CounterOpts {\n\tfor _, f := range co {\n\t\tf(&o)\n\t}\n\treturn o\n}\n\n// WithConstLabels allows you to add ConstLabels to Counter metrics.\nfunc WithConstLabels(labels prometheus.Labels) CounterOption {\n\treturn func(o *prometheus.CounterOpts) {\n\t\to.ConstLabels = labels\n\t}\n}\n\n// WithSubsystem allows you to add a Subsystem to Counter metrics.\nfunc WithSubsystem(subsystem string) CounterOption {\n\treturn func(o *prometheus.CounterOpts) {\n\t\to.Subsystem = subsystem\n\t}\n}\n\n// WithNamespace allows you to add a Namespace to Counter metrics.\nfunc WithNamespace(namespace string) CounterOption {\n\treturn func(o *prometheus.CounterOpts) {\n\t\to.Namespace = namespace\n\t}\n}\n\n// A HistogramOption lets you add options to Histogram metrics using With*\n// funcs.\ntype HistogramOption func(*prometheus.HistogramOpts)\n\ntype histogramOptions []HistogramOption\n\nfunc (ho histogramOptions) apply(o *prometheus.HistogramOpts) prometheus.HistogramOpts {\n\tfor _, f := range ho {\n\t\tf(o)\n\t}\n\treturn *o\n}\n\n// WithHistogramBuckets allows you to specify custom bucket ranges for histograms if EnableHandlingTimeHistogram is on.\nfunc WithHistogramBuckets(buckets []float64) HistogramOption {\n\treturn func(o *prometheus.HistogramOpts) { o.Buckets = buckets }\n}\n\n// WithHistogramOpts allows you to specify HistogramOpts but makes sure the correct name and label is used.\n// This function is helpful when specifying more than just the buckets, like using NativeHistograms.\nfunc WithHistogramOpts(opts *prometheus.HistogramOpts) HistogramOption {\n\t// TODO: This isn't ideal either if new fields are added to prometheus.HistogramOpts.\n\t// Maybe we can change the interface to accept arbitrary HistogramOpts and\n\t// only make sure to overwrite the necessary fields (name, labels).\n\treturn func(o *prometheus.HistogramOpts) {\n\t\to.Buckets = opts.Buckets\n\t\to.NativeHistogramBucketFactor = opts.NativeHistogramBucketFactor\n\t\to.NativeHistogramZeroThreshold = opts.NativeHistogramZeroThreshold\n\t\to.NativeHistogramMaxBucketNumber = opts.NativeHistogramMaxBucketNumber\n\t\to.NativeHistogramMinResetDuration = opts.NativeHistogramMinResetDuration\n\t\to.NativeHistogramMaxZeroThreshold = opts.NativeHistogramMaxZeroThreshold\n\t}\n}\n\n// WithHistogramConstLabels allows you to add custom ConstLabels to\n// histograms metrics.\nfunc WithHistogramConstLabels(labels prometheus.Labels) HistogramOption {\n\treturn func(o *prometheus.HistogramOpts) {\n\t\to.ConstLabels = labels\n\t}\n}\n\n// WithHistogramSubsystem allows you to add a Subsystem to histograms metrics.\nfunc WithHistogramSubsystem(subsystem string) HistogramOption {\n\treturn func(o *prometheus.HistogramOpts) {\n\t\to.Subsystem = subsystem\n\t}\n}\n\n// WithHistogramNamespace allows you to add a Namespace to histograms metrics.\nfunc WithHistogramNamespace(namespace string) HistogramOption {\n\treturn func(o *prometheus.HistogramOpts) {\n\t\to.Namespace = namespace\n\t}\n}\n\nfunc typeFromMethodInfo(mInfo *grpc.MethodInfo) grpcType {\n\tif !mInfo.IsClientStream && !mInfo.IsServerStream {\n\t\treturn Unary\n\t}\n\tif mInfo.IsClientStream && !mInfo.IsServerStream {\n\t\treturn ClientStream\n\t}\n\tif !mInfo.IsClientStream && mInfo.IsServerStream {\n\t\treturn ServerStream\n\t}\n\treturn BidiStream\n}\n\n// An Option lets you add options to prometheus interceptors using With* funcs.\ntype Option func(*config)\n\ntype config struct {\n\texemplarFn exemplarFromCtxFn\n\tlabelsFn   labelsFromCtxFn\n}\n\nfunc (c *config) apply(opts []Option) {\n\tfor _, o := range opts {\n\t\to(c)\n\t}\n}\n\n// WithExemplarFromContext sets function that will be used to deduce exemplar for all counter and histogram metrics.\nfunc WithExemplarFromContext(exemplarFn exemplarFromCtxFn) Option {\n\treturn func(o *config) {\n\t\to.exemplarFn = exemplarFn\n\t}\n}\n\n// WithLabelsFromContext sets function that will be used to extract labels from context for metrics.\n// This should be used in conjunction with WithContextLabels to define which labels to extract.\nfunc WithLabelsFromContext(labelsFn labelsFromCtxFn) Option {\n\treturn func(o *config) {\n\t\to.labelsFn = labelsFn\n\t}\n}\n"
  },
  {
    "path": "providers/prometheus/reporter.go",
    "content": "// Copyright (c) The go-grpc-middleware Authors.\n// Licensed under the Apache License 2.0.\n\npackage prometheus\n\nimport (\n\t\"context\"\n\t\"time\"\n\n\t\"github.com/grpc-ecosystem/go-grpc-middleware/v2/interceptors\"\n\t\"github.com/prometheus/client_golang/prometheus\"\n)\n\ntype reporter struct {\n\tclientMetrics   *ClientMetrics\n\tserverMetrics   *ServerMetrics\n\ttyp             interceptors.GRPCType\n\tservice, method string\n\tkind            Kind\n\texemplar        prometheus.Labels\n\tcontextLabels   []string\n}\n\nfunc (r *reporter) PostCall(err error, rpcDuration time.Duration) {\n\t// get status code from error\n\tstatus := FromError(err)\n\tcode := status.Code()\n\n\t// perform handling of metrics from code\n\tswitch r.kind {\n\tcase KindServer:\n\t\tbaseLabels := []string{string(r.typ), r.service, r.method, code.String()}\n\t\tallLabels := append(baseLabels, r.contextLabels...)\n\t\tr.incrementWithExemplar(r.serverMetrics.serverHandledCounter, allLabels...)\n\t\tif r.serverMetrics.serverHandledHistogram != nil {\n\t\t\thistLabels := []string{string(r.typ), r.service, r.method}\n\t\t\tallHistLabels := append(histLabels, r.contextLabels...)\n\t\t\tr.observeWithExemplar(r.serverMetrics.serverHandledHistogram, rpcDuration.Seconds(), allHistLabels...)\n\t\t}\n\n\tcase KindClient:\n\t\tbaseLabels := []string{string(r.typ), r.service, r.method, code.String()}\n\t\tallLabels := append(baseLabels, r.contextLabels...)\n\t\tr.incrementWithExemplar(r.clientMetrics.clientHandledCounter, allLabels...)\n\t\tif r.clientMetrics.clientHandledHistogram != nil {\n\t\t\thistLabels := []string{string(r.typ), r.service, r.method}\n\t\t\tallHistLabels := append(histLabels, r.contextLabels...)\n\t\t\tr.observeWithExemplar(r.clientMetrics.clientHandledHistogram, rpcDuration.Seconds(), allHistLabels...)\n\t\t}\n\t}\n}\n\nfunc (r *reporter) PostMsgSend(_ any, _ error, sendDuration time.Duration) {\n\tswitch r.kind {\n\tcase KindServer:\n\t\tbaseLabels := []string{string(r.typ), r.service, r.method}\n\t\tallLabels := append(baseLabels, r.contextLabels...)\n\t\tr.incrementWithExemplar(r.serverMetrics.serverStreamMsgSent, allLabels...)\n\tcase KindClient:\n\t\tbaseLabels := []string{string(r.typ), r.service, r.method}\n\t\tallLabels := append(baseLabels, r.contextLabels...)\n\t\tr.incrementWithExemplar(r.clientMetrics.clientStreamMsgSent, allLabels...)\n\t\tif r.clientMetrics.clientStreamSendHistogram != nil {\n\t\t\tr.observeWithExemplar(r.clientMetrics.clientStreamSendHistogram, sendDuration.Seconds(), allLabels...)\n\t\t}\n\t}\n}\n\nfunc (r *reporter) PostMsgReceive(_ any, _ error, recvDuration time.Duration) {\n\tswitch r.kind {\n\tcase KindServer:\n\t\tbaseLabels := []string{string(r.typ), r.service, r.method}\n\t\tallLabels := append(baseLabels, r.contextLabels...)\n\t\tr.incrementWithExemplar(r.serverMetrics.serverStreamMsgReceived, allLabels...)\n\tcase KindClient:\n\t\tbaseLabels := []string{string(r.typ), r.service, r.method}\n\t\tallLabels := append(baseLabels, r.contextLabels...)\n\t\tr.incrementWithExemplar(r.clientMetrics.clientStreamMsgReceived, allLabels...)\n\t\tif r.clientMetrics.clientStreamRecvHistogram != nil {\n\t\t\tr.observeWithExemplar(r.clientMetrics.clientStreamRecvHistogram, recvDuration.Seconds(), allLabels...)\n\t\t}\n\t}\n}\n\ntype reportable struct {\n\tclientMetrics *ClientMetrics\n\tserverMetrics *ServerMetrics\n\n\topts []Option\n}\n\nfunc (rep *reportable) ServerReporter(ctx context.Context, meta interceptors.CallMeta) (interceptors.Reporter, context.Context) {\n\treturn rep.reporter(ctx, rep.serverMetrics, nil, meta, KindServer)\n}\n\nfunc (rep *reportable) ClientReporter(ctx context.Context, meta interceptors.CallMeta) (interceptors.Reporter, context.Context) {\n\treturn rep.reporter(ctx, nil, rep.clientMetrics, meta, KindClient)\n}\n\nfunc (rep *reportable) reporter(ctx context.Context, sm *ServerMetrics, cm *ClientMetrics, meta interceptors.CallMeta, kind Kind) (interceptors.Reporter, context.Context) {\n\tvar c config\n\tc.apply(rep.opts)\n\tr := &reporter{\n\t\tclientMetrics: cm,\n\t\tserverMetrics: sm,\n\t\ttyp:           meta.Typ,\n\t\tservice:       meta.Service,\n\t\tmethod:        meta.Method,\n\t\tkind:          kind,\n\t}\n\tif c.exemplarFn != nil {\n\t\tr.exemplar = c.exemplarFn(ctx)\n\t}\n\n\t// Extract context labels if labelsFn is configured and we're on server side\n\tif c.labelsFn != nil {\n\t\tvar contextLabelNames []string\n\t\tif kind == KindServer && sm != nil {\n\t\t\tcontextLabelNames = sm.contextLabelNames\n\t\t} else if kind == KindClient && cm != nil {\n\t\t\tcontextLabelNames = cm.contextLabelNames\n\t\t}\n\n\t\tcontextLabelMap := c.labelsFn(ctx)\n\t\t// Extract context label values in the order defined by the server metrics\n\t\tr.contextLabels = make([]string, len(contextLabelNames))\n\t\tfor i, labelName := range contextLabelNames {\n\t\t\tif value, exists := contextLabelMap[labelName]; exists {\n\t\t\t\tr.contextLabels[i] = value\n\t\t\t} else {\n\t\t\t\t// Use empty string if label not found in context\n\t\t\t\tr.contextLabels[i] = \"\"\n\t\t\t}\n\t\t}\n\t}\n\n\tswitch kind {\n\tcase KindClient:\n\t\tbaseLabels := []string{string(r.typ), r.service, r.method}\n\t\tallLabels := append(baseLabels, r.contextLabels...)\n\t\tr.incrementWithExemplar(r.clientMetrics.clientStartedCounter, allLabels...)\n\tcase KindServer:\n\t\tbaseLabels := []string{string(r.typ), r.service, r.method}\n\t\tallLabels := append(baseLabels, r.contextLabels...)\n\t\tr.incrementWithExemplar(r.serverMetrics.serverStartedCounter, allLabels...)\n\t}\n\treturn r, ctx\n}\n\nfunc (r *reporter) incrementWithExemplar(c *prometheus.CounterVec, lvals ...string) {\n\tc.WithLabelValues(lvals...).(prometheus.ExemplarAdder).AddWithExemplar(1, r.exemplar)\n}\n\nfunc (r *reporter) observeWithExemplar(h *prometheus.HistogramVec, value float64, lvals ...string) {\n\th.WithLabelValues(lvals...).(prometheus.ExemplarObserver).ObserveWithExemplar(value, r.exemplar)\n}\n"
  },
  {
    "path": "providers/prometheus/server_metrics.go",
    "content": "// Copyright (c) The go-grpc-middleware Authors.\n// Licensed under the Apache License 2.0.\n\npackage prometheus\n\nimport (\n\t\"github.com/grpc-ecosystem/go-grpc-middleware/v2/interceptors\"\n\t\"github.com/prometheus/client_golang/prometheus\"\n\t\"google.golang.org/grpc\"\n\t\"google.golang.org/grpc/reflection\"\n)\n\n// ServerMetrics represents a collection of metrics to be registered on a\n// Prometheus metrics registry for a gRPC server.\ntype ServerMetrics struct {\n\tserverStartedCounter    *prometheus.CounterVec\n\tserverHandledCounter    *prometheus.CounterVec\n\tserverStreamMsgReceived *prometheus.CounterVec\n\tserverStreamMsgSent     *prometheus.CounterVec\n\t// serverHandledHistogram can be nil.\n\tserverHandledHistogram *prometheus.HistogramVec\n\t// contextLabelNames stores the names of context labels\n\tcontextLabelNames []string\n}\n\n// NewServerMetrics returns a new ServerMetrics object that has server interceptor methods.\n// NOTE: Remember to register ServerMetrics object by using prometheus registry\n// e.g. prometheus.MustRegister(myServerMetrics).\nfunc NewServerMetrics(opts ...ServerMetricsOption) *ServerMetrics {\n\tvar config serverMetricsConfig\n\tconfig.apply(opts)\n\n\t// Build label names by combining default labels with context labels\n\tdefaultLabels := []string{\"grpc_type\", \"grpc_service\", \"grpc_method\"}\n\tdefaultLabelsWithCode := []string{\"grpc_type\", \"grpc_service\", \"grpc_method\", \"grpc_code\"}\n\n\tstartedLabels := append(defaultLabels, config.contextLabels...)\n\thandledLabels := append(defaultLabelsWithCode, config.contextLabels...)\n\tstreamLabels := append(defaultLabels, config.contextLabels...)\n\n\t// Create histogram if enabled\n\tvar serverHandledHistogram *prometheus.HistogramVec\n\tif config.enableHistogram {\n\t\thistogramLabels := append(defaultLabels, config.contextLabels...)\n\t\tserverHandledHistogram = prometheus.NewHistogramVec(\n\t\t\thistogramOptions(config.histogramOpts).apply(&prometheus.HistogramOpts{\n\t\t\t\tName:    \"grpc_server_handling_seconds\",\n\t\t\t\tHelp:    \"Histogram of response latency (seconds) of gRPC that had been application-level handled by the server.\",\n\t\t\t\tBuckets: prometheus.DefBuckets,\n\t\t\t}),\n\t\t\thistogramLabels,\n\t\t)\n\t}\n\n\treturn &ServerMetrics{\n\t\tserverStartedCounter: prometheus.NewCounterVec(\n\t\t\tconfig.counterOpts.apply(prometheus.CounterOpts{\n\t\t\t\tName: \"grpc_server_started_total\",\n\t\t\t\tHelp: \"Total number of RPCs started on the server.\",\n\t\t\t}), startedLabels),\n\t\tserverHandledCounter: prometheus.NewCounterVec(\n\t\t\tconfig.counterOpts.apply(prometheus.CounterOpts{\n\t\t\t\tName: \"grpc_server_handled_total\",\n\t\t\t\tHelp: \"Total number of RPCs completed on the server, regardless of success or failure.\",\n\t\t\t}), handledLabels),\n\t\tserverStreamMsgReceived: prometheus.NewCounterVec(\n\t\t\tconfig.counterOpts.apply(prometheus.CounterOpts{\n\t\t\t\tName: \"grpc_server_msg_received_total\",\n\t\t\t\tHelp: \"Total number of RPC stream messages received on the server.\",\n\t\t\t}), streamLabels),\n\t\tserverStreamMsgSent: prometheus.NewCounterVec(\n\t\t\tconfig.counterOpts.apply(prometheus.CounterOpts{\n\t\t\t\tName: \"grpc_server_msg_sent_total\",\n\t\t\t\tHelp: \"Total number of gRPC stream messages sent by the server.\",\n\t\t\t}), streamLabels),\n\t\tserverHandledHistogram: serverHandledHistogram,\n\t\tcontextLabelNames:      config.contextLabels,\n\t}\n}\n\n// Describe sends the super-set of all possible descriptors of metrics\n// collected by this Collector to the provided channel and returns once\n// the last descriptor has been sent.\nfunc (m *ServerMetrics) Describe(ch chan<- *prometheus.Desc) {\n\tm.serverStartedCounter.Describe(ch)\n\tm.serverHandledCounter.Describe(ch)\n\tm.serverStreamMsgReceived.Describe(ch)\n\tm.serverStreamMsgSent.Describe(ch)\n\tif m.serverHandledHistogram != nil {\n\t\tm.serverHandledHistogram.Describe(ch)\n\t}\n}\n\n// Collect is called by the Prometheus registry when collecting\n// metrics. The implementation sends each collected metric via the\n// provided channel and returns once the last metric has been sent.\nfunc (m *ServerMetrics) Collect(ch chan<- prometheus.Metric) {\n\tm.serverStartedCounter.Collect(ch)\n\tm.serverHandledCounter.Collect(ch)\n\tm.serverStreamMsgReceived.Collect(ch)\n\tm.serverStreamMsgSent.Collect(ch)\n\tif m.serverHandledHistogram != nil {\n\t\tm.serverHandledHistogram.Collect(ch)\n\t}\n}\n\n// InitializeMetrics initializes all metrics, with their appropriate null\n// value, for all gRPC methods registered on a gRPC server. This is useful, to\n// ensure that all metrics exist when collecting and querying.\n// NOTE: This might add significant cardinality and might not be needed in future version of Prometheus (created timestamp).\nfunc (m *ServerMetrics) InitializeMetrics(server reflection.ServiceInfoProvider) {\n\tserviceInfo := server.GetServiceInfo()\n\tfor serviceName, info := range serviceInfo {\n\t\tfor _, mInfo := range info.Methods {\n\t\t\tm.preRegisterMethod(serviceName, &mInfo)\n\t\t}\n\t}\n}\n\n// preRegisterMethod is invoked on Register of a Server, allowing all gRPC services labels to be pre-populated.\nfunc (m *ServerMetrics) preRegisterMethod(serviceName string, mInfo *grpc.MethodInfo) {\n\tmethodName := mInfo.Name\n\tmethodType := string(typeFromMethodInfo(mInfo))\n\n\t// Create empty context label values for pre-registration\n\tcontextLabels := make([]string, len(m.contextLabelNames))\n\tfor i := range contextLabels {\n\t\tcontextLabels[i] = \"\"\n\t}\n\n\t// Build complete label value arrays\n\tstartedLabels := append([]string{methodType, serviceName, methodName}, contextLabels...)\n\tstreamLabels := append([]string{methodType, serviceName, methodName}, contextLabels...)\n\n\t// These are just references (no increments), as just referencing will create the labels but not set values.\n\t_, _ = m.serverStartedCounter.GetMetricWithLabelValues(startedLabels...)\n\t_, _ = m.serverStreamMsgReceived.GetMetricWithLabelValues(streamLabels...)\n\t_, _ = m.serverStreamMsgSent.GetMetricWithLabelValues(streamLabels...)\n\tif m.serverHandledHistogram != nil {\n\t\t_, _ = m.serverHandledHistogram.GetMetricWithLabelValues(streamLabels...)\n\t}\n\tfor _, code := range interceptors.AllCodes {\n\t\thandledLabelsWithCode := append([]string{methodType, serviceName, methodName, code.String()}, contextLabels...)\n\t\t_, _ = m.serverHandledCounter.GetMetricWithLabelValues(handledLabelsWithCode...)\n\t}\n}\n\n// UnaryServerInterceptor is a gRPC server-side interceptor that provides Prometheus monitoring for Unary RPCs.\nfunc (m *ServerMetrics) UnaryServerInterceptor(opts ...Option) grpc.UnaryServerInterceptor {\n\treturn interceptors.UnaryServerInterceptor(&reportable{\n\t\topts:          opts,\n\t\tserverMetrics: m,\n\t})\n}\n\n// StreamServerInterceptor is a gRPC server-side interceptor that provides Prometheus monitoring for Streaming RPCs.\nfunc (m *ServerMetrics) StreamServerInterceptor(opts ...Option) grpc.StreamServerInterceptor {\n\treturn interceptors.StreamServerInterceptor(&reportable{\n\t\topts:          opts,\n\t\tserverMetrics: m,\n\t})\n}\n"
  },
  {
    "path": "providers/prometheus/server_options.go",
    "content": "// Copyright (c) The go-grpc-middleware Authors.\n// Licensed under the Apache License 2.0.\n\npackage prometheus\n\nimport (\n\t\"context\"\n\n\t\"github.com/prometheus/client_golang/prometheus\"\n)\n\ntype (\n\texemplarFromCtxFn func(ctx context.Context) prometheus.Labels\n\tlabelsFromCtxFn   func(metadata context.Context) prometheus.Labels\n)\n\ntype serverMetricsConfig struct {\n\tcounterOpts counterOptions\n\t// histogramOpts stores the options for creating the histogram with dynamic labels\n\thistogramOpts histogramOptions\n\t// enableHistogram indicates whether histogram should be created\n\tenableHistogram bool\n\t// contextLabels defines the names of dynamic labels to be extracted from context\n\tcontextLabels []string\n}\n\ntype ServerMetricsOption func(*serverMetricsConfig)\n\nfunc (c *serverMetricsConfig) apply(opts []ServerMetricsOption) {\n\tfor _, o := range opts {\n\t\to(c)\n\t}\n}\n\n// WithServerCounterOptions sets counter options.\nfunc WithServerCounterOptions(opts ...CounterOption) ServerMetricsOption {\n\treturn func(o *serverMetricsConfig) {\n\t\to.counterOpts = opts\n\t}\n}\n\n// WithServerHandlingTimeHistogram turns on recording of handling time of RPCs.\n// Histogram metrics can be very expensive for Prometheus to retain and query.\nfunc WithServerHandlingTimeHistogram(opts ...HistogramOption) ServerMetricsOption {\n\treturn func(o *serverMetricsConfig) {\n\t\to.histogramOpts = opts\n\t\to.enableHistogram = true\n\t}\n}\n\n// WithContextLabels configures the server metrics to include dynamic labels extracted from context.\n// The provided label names will be added to all server metrics as dynamic labels.\n// Use WithLabelsFromContext in the interceptor options to specify how to extract these labels from context.\nfunc WithContextLabels(labelNames ...string) ServerMetricsOption {\n\treturn func(o *serverMetricsConfig) {\n\t\to.contextLabels = labelNames\n\t}\n}\n"
  },
  {
    "path": "providers/prometheus/server_test.go",
    "content": "// Copyright (c) The go-grpc-middleware Authors.\n// Licensed under the Apache License 2.0.\n\npackage prometheus\n\nimport (\n\t\"bufio\"\n\t\"context\"\n\t\"errors\"\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"net/http/httptest\"\n\t\"reflect\"\n\t\"strings\"\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/grpc-ecosystem/go-grpc-middleware/v2/testing/testpb\"\n\t\"github.com/prometheus/client_golang/prometheus\"\n\t\"github.com/prometheus/client_golang/prometheus/promhttp\"\n\t\"github.com/prometheus/client_golang/prometheus/testutil\"\n\tdto \"github.com/prometheus/client_model/go\"\n\t\"github.com/stretchr/testify/require\"\n\t\"github.com/stretchr/testify/suite\"\n\t\"google.golang.org/grpc\"\n\t\"google.golang.org/grpc/codes\"\n)\n\nfunc TestServerInterceptorSuite(t *testing.T) {\n\ts := NewServerMetrics(WithServerHandlingTimeHistogram())\n\tsuite.Run(t, &ServerInterceptorTestSuite{\n\t\tInterceptorTestSuite: &testpb.InterceptorTestSuite{\n\t\t\tTestService: &testpb.TestPingService{},\n\t\t\tServerOpts: []grpc.ServerOption{\n\t\t\t\tgrpc.StreamInterceptor(s.StreamServerInterceptor()),\n\t\t\t\tgrpc.UnaryInterceptor(s.UnaryServerInterceptor()),\n\t\t\t},\n\t\t},\n\t\tserverMetrics: s,\n\t})\n}\n\ntype ServerInterceptorTestSuite struct {\n\t*testpb.InterceptorTestSuite\n\n\tserverMetrics *ServerMetrics\n}\n\nfunc (s *ServerInterceptorTestSuite) SetupTest() {\n\ts.serverMetrics.serverStartedCounter.Reset()\n\ts.serverMetrics.serverHandledCounter.Reset()\n\ts.serverMetrics.serverHandledHistogram.Reset()\n\ts.serverMetrics.serverStreamMsgReceived.Reset()\n\ts.serverMetrics.serverStreamMsgSent.Reset()\n\ts.serverMetrics.InitializeMetrics(s.Server)\n}\n\nfunc (s *ServerInterceptorTestSuite) TestWithSubsystem() {\n\tcounterOpts := []CounterOption{\n\t\tWithSubsystem(\"subsystem1\"),\n\t}\n\thistOpts := []HistogramOption{\n\t\tWithHistogramSubsystem(\"subsystem1\"),\n\t}\n\tserverCounterOpts := WithServerCounterOptions(counterOpts...)\n\tserverMetrics := NewServerMetrics(serverCounterOpts, WithServerHandlingTimeHistogram(histOpts...))\n\n\trequireSubsystemName(s.T(), \"subsystem1\", serverMetrics.serverStartedCounter.WithLabelValues(\"unary\", testpb.TestServiceFullName, \"dummy\"))\n\trequireHistSubsystemName(s.T(), \"subsystem1\", serverMetrics.serverHandledHistogram.WithLabelValues(\"unary\", testpb.TestServiceFullName, \"dummy\"))\n}\n\nfunc (s *ServerInterceptorTestSuite) TestRegisterPresetsStuff() {\n\tregistry := prometheus.NewPedanticRegistry()\n\ts.Require().NoError(registry.Register(s.serverMetrics))\n\n\tfor testID, testCase := range []struct {\n\t\tmetricName     string\n\t\texistingLabels []string\n\t}{\n\t\t// Order of label is irrelevant.\n\t\t{\"grpc_server_started_total\", []string{testpb.TestServiceFullName, \"PingEmpty\", \"unary\"}},\n\t\t{\"grpc_server_started_total\", []string{testpb.TestServiceFullName, \"PingList\", \"server_stream\"}},\n\t\t{\"grpc_server_msg_received_total\", []string{testpb.TestServiceFullName, \"PingList\", \"server_stream\"}},\n\t\t{\"grpc_server_msg_sent_total\", []string{testpb.TestServiceFullName, \"PingEmpty\", \"unary\"}},\n\t\t{\"grpc_server_handling_seconds_sum\", []string{testpb.TestServiceFullName, \"PingEmpty\", \"unary\"}},\n\t\t{\"grpc_server_handling_seconds_count\", []string{testpb.TestServiceFullName, \"PingList\", \"server_stream\"}},\n\t\t{\"grpc_server_handled_total\", []string{testpb.TestServiceFullName, \"PingList\", \"server_stream\", \"OutOfRange\"}},\n\t\t{\"grpc_server_handled_total\", []string{testpb.TestServiceFullName, \"PingList\", \"server_stream\", \"Aborted\"}},\n\t\t{\"grpc_server_handled_total\", []string{testpb.TestServiceFullName, \"PingEmpty\", \"unary\", \"FailedPrecondition\"}},\n\t\t{\"grpc_server_handled_total\", []string{testpb.TestServiceFullName, \"PingEmpty\", \"unary\", \"ResourceExhausted\"}},\n\t} {\n\t\tlineCount := len(fetchPrometheusLines(s.T(), registry, testCase.metricName, testCase.existingLabels...))\n\t\ts.Assert().NotZero(lineCount, \"metrics must exist for test case %d\", testID)\n\t}\n}\n\nfunc (s *ServerInterceptorTestSuite) TestUnaryIncrementsMetrics() {\n\t_, err := s.Client.PingEmpty(s.SimpleCtx(), &testpb.PingEmptyRequest{})\n\ts.Require().NoError(err)\n\trequireValue(s.T(), 1, s.serverMetrics.serverStartedCounter.WithLabelValues(\"unary\", testpb.TestServiceFullName, \"PingEmpty\"))\n\trequireValue(s.T(), 1, s.serverMetrics.serverHandledCounter.WithLabelValues(\"unary\", testpb.TestServiceFullName, \"PingEmpty\", \"OK\"))\n\trequireValueHistCount(s.T(), 1, s.serverMetrics.serverHandledHistogram.WithLabelValues(\"unary\", testpb.TestServiceFullName, \"PingEmpty\"))\n\n\t_, err = s.Client.PingError(s.SimpleCtx(), &testpb.PingErrorRequest{ErrorCodeReturned: uint32(codes.FailedPrecondition)})\n\ts.Require().Error(err)\n\trequireValue(s.T(), 1, s.serverMetrics.serverStartedCounter.WithLabelValues(\"unary\", testpb.TestServiceFullName, \"PingError\"))\n\trequireValue(s.T(), 1, s.serverMetrics.serverHandledCounter.WithLabelValues(\"unary\", testpb.TestServiceFullName, \"PingError\", \"FailedPrecondition\"))\n\trequireValueHistCount(s.T(), 1, s.serverMetrics.serverHandledHistogram.WithLabelValues(\"unary\", testpb.TestServiceFullName, \"PingError\"))\n}\n\nfunc (s *ServerInterceptorTestSuite) TestStartedStreamingIncrementsStarted() {\n\t_, err := s.Client.PingList(s.SimpleCtx(), &testpb.PingListRequest{})\n\ts.Require().NoError(err)\n\trequireValueWithRetry(s.SimpleCtx(), s.T(), 1,\n\t\ts.serverMetrics.serverStartedCounter.WithLabelValues(\"server_stream\", testpb.TestServiceFullName, \"PingList\"))\n\n\t_, err = s.Client.PingList(s.SimpleCtx(), &testpb.PingListRequest{ErrorCodeReturned: uint32(codes.FailedPrecondition)})\n\ts.Require().NoError(err, \"PingList must not fail immediately\")\n\trequireValueWithRetry(s.SimpleCtx(), s.T(), 2,\n\t\ts.serverMetrics.serverStartedCounter.WithLabelValues(\"server_stream\", testpb.TestServiceFullName, \"PingList\"))\n}\n\nfunc (s *ServerInterceptorTestSuite) TestStreamingIncrementsMetrics() {\n\tss, _ := s.Client.PingList(s.SimpleCtx(), &testpb.PingListRequest{})\n\t// Do a read, just for kicks.\n\tcount := 0\n\tfor {\n\t\t_, err := ss.Recv()\n\t\tif errors.Is(err, io.EOF) {\n\t\t\tbreak\n\t\t}\n\t\ts.Require().NoError(err, \"reading pingList shouldn't fail\")\n\t\tcount++\n\t}\n\ts.Require().Equal(testpb.ListResponseCount, count, \"Number of received msg on the wire must match\")\n\n\trequireValueWithRetry(s.SimpleCtx(), s.T(), 1,\n\t\ts.serverMetrics.serverStartedCounter.WithLabelValues(\"server_stream\", testpb.TestServiceFullName, \"PingList\"))\n\trequireValueWithRetry(s.SimpleCtx(), s.T(), 1,\n\t\ts.serverMetrics.serverHandledCounter.WithLabelValues(\"server_stream\", testpb.TestServiceFullName, \"PingList\", \"OK\"))\n\trequireValueWithRetry(s.SimpleCtx(), s.T(), testpb.ListResponseCount,\n\t\ts.serverMetrics.serverStreamMsgSent.WithLabelValues(\"server_stream\", testpb.TestServiceFullName, \"PingList\"))\n\trequireValueWithRetry(s.SimpleCtx(), s.T(), 1,\n\t\ts.serverMetrics.serverStreamMsgReceived.WithLabelValues(\"server_stream\", testpb.TestServiceFullName, \"PingList\"))\n\trequireValueWithRetryHistCount(s.SimpleCtx(), s.T(), 1,\n\t\ts.serverMetrics.serverHandledHistogram.WithLabelValues(\"server_stream\", testpb.TestServiceFullName, \"PingList\"))\n\n\t_, err := s.Client.PingList(s.SimpleCtx(), &testpb.PingListRequest{ErrorCodeReturned: uint32(codes.FailedPrecondition)}) // should return with code=FailedPrecondition\n\ts.Require().NoError(err, \"PingList must not fail immediately\")\n\n\trequireValueWithRetry(s.SimpleCtx(), s.T(), 2,\n\t\ts.serverMetrics.serverStartedCounter.WithLabelValues(\"server_stream\", testpb.TestServiceFullName, \"PingList\"))\n\trequireValueWithRetry(s.SimpleCtx(), s.T(), 1,\n\t\ts.serverMetrics.serverHandledCounter.WithLabelValues(\"server_stream\", testpb.TestServiceFullName, \"PingList\", \"FailedPrecondition\"))\n\trequireValueWithRetryHistCount(s.SimpleCtx(), s.T(), 2,\n\t\ts.serverMetrics.serverHandledHistogram.WithLabelValues(\"server_stream\", testpb.TestServiceFullName, \"PingList\"))\n}\n\nfunc (s *ServerInterceptorTestSuite) TestContextCancelledTreatedAsStatus() {\n\tctx, cancel := context.WithCancel(context.TODO())\n\tdefer cancel()\n\n\tstream, _ := s.Client.PingStream(ctx)\n\terr := stream.Send(&testpb.PingStreamRequest{})\n\ts.Require().NoError(err)\n\tcancel()\n\n\trequireValueWithRetry(s.SimpleCtx(), s.T(), 1,\n\t\ts.serverMetrics.serverHandledCounter.WithLabelValues(\"bidi_stream\", testpb.TestServiceFullName, \"PingStream\", \"Canceled\"))\n}\n\n// fetchPrometheusLines does mocked HTTP GET request against real prometheus handler to get the same view that Prometheus\n// would have while scraping this endpoint.\n// Order of matching label vales does not matter.\nfunc fetchPrometheusLines(t *testing.T, reg prometheus.Gatherer, metricName string, matchingLabelValues ...string) []string {\n\tresp := httptest.NewRecorder()\n\treq, err := http.NewRequest(http.MethodGet, \"/\", http.NoBody)\n\trequire.NoError(t, err, \"failed creating request for Prometheus handler\")\n\n\tpromhttp.HandlerFor(reg, promhttp.HandlerOpts{}).ServeHTTP(resp, req)\n\treader := bufio.NewReader(resp.Body)\n\n\tvar ret []string\n\tfor {\n\t\tline, err := reader.ReadString('\\n')\n\t\tif err == io.EOF {\n\t\t\tbreak\n\t\t} else {\n\t\t\trequire.NoError(t, err, \"error reading stuff\")\n\t\t}\n\t\tif !strings.HasPrefix(line, metricName) {\n\t\t\tcontinue\n\t\t}\n\t\tmatches := true\n\t\tfor _, labelValue := range matchingLabelValues {\n\t\t\tif !strings.Contains(line, `\"`+labelValue+`\"`) {\n\t\t\t\tmatches = false\n\t\t\t}\n\t\t}\n\t\tif matches {\n\t\t\tret = append(ret, line)\n\t\t}\n\n\t}\n\treturn ret\n}\n\n// toFloat64HistCount does the same thing as prometheus go client testutil.ToFloat64, but for histograms.\n// TODO(bwplotka): Upstream this function to prometheus client.\nfunc toFloat64HistCount(h prometheus.Observer) uint64 {\n\tvar (\n\t\tm      prometheus.Metric\n\t\tmCount int\n\t\tmChan  = make(chan prometheus.Metric)\n\t\tdone   = make(chan struct{})\n\t)\n\n\tgo func() {\n\t\tfor m = range mChan {\n\t\t\tmCount++\n\t\t}\n\t\tclose(done)\n\t}()\n\n\tc, ok := h.(prometheus.Collector)\n\tif !ok {\n\t\tpanic(fmt.Errorf(\"observer is not a collector; got: %T\", h))\n\t}\n\n\tc.Collect(mChan)\n\tclose(mChan)\n\t<-done\n\n\tif mCount != 1 {\n\t\tpanic(fmt.Errorf(\"collected %d metrics instead of exactly 1\", mCount))\n\t}\n\n\tpb := &dto.Metric{}\n\tif err := m.Write(pb); err != nil {\n\t\tpanic(fmt.Errorf(\"metric write failed: %w\", err))\n\t}\n\n\tif pb.Histogram != nil {\n\t\treturn pb.Histogram.GetSampleCount()\n\t}\n\tpanic(fmt.Errorf(\"collected a non-histogram metric: %s\", pb))\n}\n\nfunc requireSubsystemName(t *testing.T, expect string, c prometheus.Collector) {\n\tt.Helper()\n\tmetricFullName := reflect.ValueOf(*c.(prometheus.Metric).Desc()).FieldByName(\"fqName\").String()\n\n\tif strings.Split(metricFullName, \"_\")[0] == expect {\n\t\treturn\n\t}\n\n\tt.Errorf(\"expected %s value to start with %s; \", metricFullName, expect)\n\tt.Fail()\n}\n\nfunc requireNamespaceName(t *testing.T, expect string, c prometheus.Collector) {\n\tt.Helper()\n\tmetricFullName := reflect.ValueOf(*c.(prometheus.Metric).Desc()).FieldByName(\"fqName\").String()\n\n\tif strings.Split(metricFullName, \"_\")[0] == expect {\n\t\treturn\n\t}\n\n\tt.Errorf(\"expected %s value to start with %s; \", metricFullName, expect)\n\tt.Fail()\n}\n\nfunc requireValue(t *testing.T, expect int, c prometheus.Collector) {\n\tt.Helper()\n\tv := int(testutil.ToFloat64(c))\n\tif v == expect {\n\t\treturn\n\t}\n\n\tmetricFullName := reflect.ValueOf(*c.(prometheus.Metric).Desc()).FieldByName(\"fqName\").String()\n\tt.Errorf(\"expected %d %s value; got %d; \", expect, metricFullName, v)\n\tt.Fail()\n}\n\nfunc requireHistSubsystemName(t *testing.T, expect string, o prometheus.Observer) {\n\tt.Helper()\n\tmetricFullName := reflect.ValueOf(*o.(prometheus.Metric).Desc()).FieldByName(\"fqName\").String()\n\n\tif strings.Split(metricFullName, \"_\")[0] == expect {\n\t\treturn\n\t}\n\n\tt.Errorf(\"expected %s value to start with %s; \", metricFullName, expect)\n\tt.Fail()\n}\n\nfunc requireHistNamespaceName(t *testing.T, expect string, o prometheus.Observer) {\n\tt.Helper()\n\tmetricFullName := reflect.ValueOf(*o.(prometheus.Metric).Desc()).FieldByName(\"fqName\").String()\n\n\tif strings.Split(metricFullName, \"_\")[0] == expect {\n\t\treturn\n\t}\n\n\tt.Errorf(\"expected %s value to start with %s; \", metricFullName, expect)\n\tt.Fail()\n}\n\nfunc requireValueHistCount(t *testing.T, expect int, o prometheus.Observer) {\n\tt.Helper()\n\tv := int(toFloat64HistCount(o))\n\tif v == expect {\n\t\treturn\n\t}\n\n\tmetricFullName := reflect.ValueOf(*o.(prometheus.Metric).Desc()).FieldByName(\"fqName\").String()\n\tt.Errorf(\"expected %d %s value; got %d; \", expect, metricFullName, v)\n\tt.Fail()\n}\n\nfunc requireValueWithRetry(ctx context.Context, t *testing.T, expect int, c prometheus.Collector) {\n\tt.Helper()\n\tfor {\n\t\tv := int(testutil.ToFloat64(c))\n\t\tif v == expect {\n\t\t\treturn\n\t\t}\n\n\t\tselect {\n\t\tcase <-ctx.Done():\n\t\t\tmetricFullName := reflect.ValueOf(*c.(prometheus.Metric).Desc()).FieldByName(\"fqName\").String()\n\t\t\tt.Errorf(\"timeout while expecting %d %s value; got %d; \", expect, metricFullName, v)\n\t\t\tt.Fail()\n\t\t\treturn\n\t\tcase <-time.After(100 * time.Millisecond):\n\t\t}\n\t}\n}\n\nfunc requireValueWithRetryHistCount(ctx context.Context, t *testing.T, expect int, o prometheus.Observer) {\n\tt.Helper()\n\tfor {\n\t\tv := int(toFloat64HistCount(o))\n\t\tif v == expect {\n\t\t\treturn\n\t\t}\n\n\t\tselect {\n\t\tcase <-ctx.Done():\n\t\t\tmetricFullName := reflect.ValueOf(*o.(prometheus.Metric).Desc()).FieldByName(\"fqName\").String()\n\t\t\tt.Errorf(\"timeout while expecting %d %s histogram count value; got %d; \", expect, metricFullName, v)\n\t\t\tt.Fail()\n\t\t\treturn\n\t\tcase <-time.After(100 * time.Millisecond):\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "testing/testpb/interceptor_suite.go",
    "content": "// Copyright (c) The go-grpc-middleware Authors.\n// Licensed under the Apache License 2.0.\n\npackage testpb\n\nimport (\n\t\"context\"\n\t\"crypto/rand\"\n\t\"crypto/rsa\"\n\t\"crypto/tls\"\n\t\"crypto/x509\"\n\t\"crypto/x509/pkix\"\n\t\"encoding/pem\"\n\t\"errors\"\n\t\"flag\"\n\t\"math/big\"\n\t\"net\"\n\t\"sync\"\n\t\"time\"\n\n\t\"github.com/stretchr/testify/suite\"\n\t\"google.golang.org/grpc\"\n\t\"google.golang.org/grpc/codes\"\n\t\"google.golang.org/grpc/credentials\"\n\t\"google.golang.org/grpc/credentials/insecure\"\n\t\"google.golang.org/grpc/status\"\n)\n\nvar (\n\tflagTls = flag.Bool(\"use_tls\", true, \"whether all gRPC middleware tests should use tls\")\n\n\tcertPEM []byte\n\tkeyPEM  []byte\n)\n\n// InterceptorTestSuite is a testify/Suite that starts a gRPC PingService server and a client.\ntype InterceptorTestSuite struct {\n\tsuite.Suite\n\n\tTestService TestServiceServer\n\tServerOpts  []grpc.ServerOption\n\tClientOpts  []grpc.DialOption\n\n\tserverAddr     string\n\tServerListener net.Listener\n\tServer         *grpc.Server\n\tclientConn     *grpc.ClientConn\n\tClient         TestServiceClient\n\n\trestartServerWithDelayedStart chan time.Duration\n\tserverRunning                 chan bool\n\n\tcancels []context.CancelFunc\n}\n\nfunc (s *InterceptorTestSuite) SetupSuite() {\n\ts.restartServerWithDelayedStart = make(chan time.Duration)\n\ts.serverRunning = make(chan bool)\n\n\ts.serverAddr = \"127.0.0.1:0\"\n\tvar err error\n\tcertPEM, keyPEM, err = generateCertAndKey([]string{\"localhost\", \"example.com\"})\n\ts.Require().NoError(err, \"unable to generate test certificate/key\")\n\n\tgo func() {\n\t\tfor {\n\t\t\tvar err error\n\t\t\ts.ServerListener, err = net.Listen(\"tcp\", s.serverAddr)\n\t\t\ts.serverAddr = s.ServerListener.Addr().String()\n\t\t\ts.Require().NoError(err, \"must be able to allocate a port for serverListener\")\n\t\t\tif *flagTls {\n\t\t\t\tcert, err := tls.X509KeyPair(certPEM, keyPEM)\n\t\t\t\ts.Require().NoError(err, \"unable to load test TLS certificate\")\n\t\t\t\tcreds := credentials.NewServerTLSFromCert(&cert)\n\t\t\t\ts.ServerOpts = append(s.ServerOpts, grpc.Creds(creds))\n\t\t\t}\n\t\t\t// This is the point where we hook up the interceptor.\n\t\t\ts.Server = grpc.NewServer(s.ServerOpts...)\n\t\t\t// Create a service if the instantiator hasn't provided one.\n\t\t\tif s.TestService == nil {\n\t\t\t\ts.TestService = &TestPingService{}\n\t\t\t}\n\t\t\tRegisterTestServiceServer(s.Server, s.TestService)\n\n\t\t\tw := sync.WaitGroup{}\n\t\t\tw.Add(1)\n\t\t\tgo func() {\n\t\t\t\t_ = s.Server.Serve(s.ServerListener)\n\t\t\t\tw.Done()\n\t\t\t}()\n\t\t\tif s.Client == nil {\n\t\t\t\ts.Client = s.NewClient(s.ClientOpts...)\n\t\t\t}\n\n\t\t\ts.serverRunning <- true\n\n\t\t\td := <-s.restartServerWithDelayedStart\n\t\t\ts.Server.Stop()\n\t\t\ttime.Sleep(d)\n\t\t\tw.Wait()\n\t\t}\n\t}()\n\n\tselect {\n\tcase <-s.serverRunning:\n\tcase <-time.After(2 * time.Second):\n\t\ts.T().Fatal(\"server failed to start before deadline\")\n\t}\n}\n\nfunc (s *InterceptorTestSuite) RestartServer(delayedStart time.Duration) <-chan bool {\n\ts.restartServerWithDelayedStart <- delayedStart\n\ttime.Sleep(10 * time.Millisecond)\n\treturn s.serverRunning\n}\n\nfunc (s *InterceptorTestSuite) NewClient(dialOpts ...grpc.DialOption) TestServiceClient {\n\ts.T().Helper()\n\n\tvar err error\n\tif *flagTls {\n\t\tcp := x509.NewCertPool()\n\t\tif !cp.AppendCertsFromPEM(certPEM) {\n\t\t\ts.T().Fatal(\"failed to append certificate\")\n\t\t}\n\t\tcreds := credentials.NewTLS(&tls.Config{ServerName: \"localhost\", RootCAs: cp})\n\t\tdialOpts = append(dialOpts, grpc.WithTransportCredentials(creds))\n\t} else {\n\t\tdialOpts = append(dialOpts, grpc.WithTransportCredentials(insecure.NewCredentials()))\n\t}\n\ts.clientConn, err = grpc.NewClient(s.ServerAddr(), dialOpts...)\n\ts.Require().NoError(err, \"must not error on client Dial\")\n\treturn NewTestServiceClient(s.clientConn)\n}\n\nfunc (s *InterceptorTestSuite) ServerAddr() string {\n\treturn s.serverAddr\n}\n\ntype ctxTestNumber struct{}\n\nvar (\n\tctxTestNumberKey = &ctxTestNumber{}\n\tzero             = 0\n)\n\nfunc ExtractCtxTestNumber(ctx context.Context) *int {\n\tif v, ok := ctx.Value(ctxTestNumberKey).(*int); ok {\n\t\treturn v\n\t}\n\treturn &zero\n}\n\ntype wrappedErrFields struct {\n\twrappedErr error\n\tfields     []any\n}\n\nfunc (err *wrappedErrFields) Unwrap() error {\n\treturn err.wrappedErr\n}\n\nfunc (err *wrappedErrFields) Error() string {\n\tif err.wrappedErr == nil {\n\t\treturn \"\"\n\t}\n\n\t// Ideally we print wrapped fields as well\n\treturn err.wrappedErr.Error()\n}\n\nfunc (err *wrappedErrFields) GRPCStatus() *status.Status {\n\tif s, ok := status.FromError(err.wrappedErr); ok {\n\t\treturn s\n\t}\n\treturn status.New(codes.Unknown, err.Error())\n}\n\nfunc WrapFieldsInError(err error, fields []any) error {\n\treturn &wrappedErrFields{err, fields}\n}\n\nfunc ExtractErrorFields(err error) []any {\n\tvar e *wrappedErrFields\n\tok := errors.As(err, &e)\n\tif !ok {\n\t\treturn nil\n\t}\n\treturn e.fields\n}\n\n// UnaryServerInterceptor returns a new unary server interceptors that adds query information logging.\nfunc UnaryServerInterceptor() grpc.UnaryServerInterceptor {\n\treturn func(ctx context.Context, req any, _ *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (any, error) {\n\t\tnewCtx := ctx\n\t\tresp, err := handler(newCtx, req)\n\t\treturn resp, err\n\t}\n}\n\nfunc (s *InterceptorTestSuite) SimpleCtx() context.Context {\n\tctx, cancel := context.WithTimeout(context.TODO(), 2*time.Second)\n\tctx = context.WithValue(ctx, ctxTestNumberKey, 1)\n\ts.cancels = append(s.cancels, cancel)\n\treturn ctx\n}\n\nfunc (s *InterceptorTestSuite) DeadlineCtx(deadline time.Time) context.Context {\n\tctx, cancel := context.WithDeadline(context.TODO(), deadline)\n\ts.cancels = append(s.cancels, cancel)\n\treturn ctx\n}\n\nfunc (s *InterceptorTestSuite) TearDownSuite() {\n\ttime.Sleep(10 * time.Millisecond)\n\tif s.ServerListener != nil {\n\t\ts.Server.GracefulStop()\n\t\ts.T().Logf(\"stopped grpc.Server at: %v\", s.ServerAddr())\n\t\t_ = s.ServerListener.Close()\n\t}\n\tif s.clientConn != nil {\n\t\t_ = s.clientConn.Close()\n\t}\n\tfor _, c := range s.cancels {\n\t\tc()\n\t}\n}\n\n// generateCertAndKey copied from https://github.com/johanbrandhorst/certify/blob/master/issuers/vault/vault_suite_test.go#L255\n// with minor modifications.\nfunc generateCertAndKey(san []string) ([]byte, []byte, error) {\n\tpriv, err := rsa.GenerateKey(rand.Reader, 2048)\n\tif err != nil {\n\t\treturn nil, nil, err\n\t}\n\tnotBefore := time.Now()\n\tnotAfter := notBefore.Add(time.Hour)\n\tserialNumberLimit := new(big.Int).Lsh(big.NewInt(1), 128)\n\tserialNumber, err := rand.Int(rand.Reader, serialNumberLimit)\n\tif err != nil {\n\t\treturn nil, nil, err\n\t}\n\ttemplate := x509.Certificate{\n\t\tSerialNumber: serialNumber,\n\t\tSubject: pkix.Name{\n\t\t\tCommonName: \"example.com\",\n\t\t},\n\t\tNotBefore:             notBefore,\n\t\tNotAfter:              notAfter,\n\t\tKeyUsage:              x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature,\n\t\tExtKeyUsage:           []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth},\n\t\tBasicConstraintsValid: true,\n\t\tDNSNames:              san,\n\t}\n\tderBytes, err := x509.CreateCertificate(rand.Reader, &template, &template, priv.Public(), priv)\n\tif err != nil {\n\t\treturn nil, nil, err\n\t}\n\tcertOut := pem.EncodeToMemory(&pem.Block{\n\t\tType:  \"CERTIFICATE\",\n\t\tBytes: derBytes,\n\t})\n\tkeyOut := pem.EncodeToMemory(&pem.Block{\n\t\tType:  \"RSA PRIVATE KEY\",\n\t\tBytes: x509.MarshalPKCS1PrivateKey(priv),\n\t})\n\n\treturn certOut, keyOut, nil\n}\n"
  },
  {
    "path": "testing/testpb/pingservice.go",
    "content": "// Copyright (c) The go-grpc-middleware Authors.\n// Licensed under the Apache License 2.0.\n\n/*\nPackage `grpc_testing` provides helper functions for testing validators in this package.\n*/\n\npackage testpb\n\nimport (\n\t\"context\"\n\t\"errors\"\n\t\"io\"\n\n\t\"google.golang.org/grpc/codes\"\n\t\"google.golang.org/grpc/status\"\n)\n\nconst (\n\t// ListResponseCount is the expected number of responses to PingList\n\tListResponseCount = 100\n)\n\nvar TestServiceFullName = TestService_ServiceDesc.ServiceName\n\n// Interface implementation assert.\nvar _ TestServiceServer = &TestPingService{}\n\ntype TestPingService struct {\n\tUnimplementedTestServiceServer\n\tPingFunc func(ctx context.Context)\n}\n\nfunc (s *TestPingService) PingEmpty(_ context.Context, _ *PingEmptyRequest) (*PingEmptyResponse, error) {\n\treturn &PingEmptyResponse{}, nil\n}\n\nfunc (s *TestPingService) Ping(ctx context.Context, ping *PingRequest) (*PingResponse, error) {\n\tif s.PingFunc != nil {\n\t\ts.PingFunc(ctx)\n\t}\n\t// Modify the ctx value to verify the logger sees the value updated from the initial value\n\tn := ExtractCtxTestNumber(ctx)\n\tif n != nil {\n\t\t*n = 42\n\t}\n\t// Send user trailers and headers.\n\treturn &PingResponse{Value: ping.Value, Counter: 0}, nil\n}\n\nfunc (s *TestPingService) PingError(_ context.Context, ping *PingErrorRequest) (*PingErrorResponse, error) {\n\tcode := codes.Code(ping.ErrorCodeReturned)\n\treturn nil, WrapFieldsInError(status.Error(code, \"Userspace error\"), []any{\"error-field\", \"plop\"})\n}\n\nfunc (s *TestPingService) PingList(ping *PingListRequest, stream TestService_PingListServer) error {\n\tif ping.ErrorCodeReturned != 0 {\n\t\treturn status.Error(codes.Code(ping.ErrorCodeReturned), \"foobar\")\n\t}\n\n\t// Send user trailers and headers.\n\tfor i := 0; i < ListResponseCount; i++ {\n\t\tif err := stream.Send(&PingListResponse{Value: ping.Value, Counter: int32(i)}); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\treturn nil\n}\n\nfunc (s *TestPingService) PingStream(stream TestService_PingStreamServer) error {\n\tcount := 0\n\tfor {\n\t\tping, err := stream.Recv()\n\t\tif errors.Is(err, io.EOF) {\n\t\t\tbreak\n\t\t}\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tif err := stream.Send(&PingStreamResponse{Value: ping.Value, Counter: int32(count)}); err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\tcount += 1\n\t}\n\treturn nil\n}\n\nfunc (s *TestPingService) PingClientStream(stream TestService_PingClientStreamServer) error {\n\tcount := 0\n\tfor {\n\t\t_, err := stream.Recv()\n\t\tif errors.Is(err, io.EOF) {\n\t\t\tbreak\n\t\t}\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tcount += 1\n\t}\n\treturn stream.SendAndClose(&PingClientStreamResponse{Counter: int32(count)})\n}\n"
  },
  {
    "path": "testing/testpb/pingservice_test.go",
    "content": "// Copyright (c) The go-grpc-middleware Authors.\n// Licensed under the Apache License 2.0.\n\npackage testpb\n\nimport (\n\t\"context\"\n\t\"errors\"\n\t\"fmt\"\n\t\"net\"\n\t\"testing\"\n\n\t\"github.com/stretchr/testify/assert\"\n\t\"github.com/stretchr/testify/require\"\n\t\"google.golang.org/grpc\"\n\t\"google.golang.org/grpc/codes\"\n\t\"google.golang.org/grpc/credentials/insecure\"\n\t\"google.golang.org/grpc/status\"\n)\n\nfunc TestPingServiceOnWire(t *testing.T) {\n\tstopped := make(chan error)\n\tserverListener, err := net.Listen(\"tcp\", \"127.0.0.1:0\")\n\trequire.NoError(t, err, \"must be able to allocate a port for serverListener\")\n\n\tserver := grpc.NewServer()\n\tRegisterTestServiceServer(server, &TestPingService{})\n\n\tgo func() {\n\t\tdefer close(stopped)\n\t\tstopped <- server.Serve(serverListener)\n\t}()\n\tdefer func() {\n\t\tserver.Stop()\n\t\t<-stopped\n\t}()\n\n\t// This is the point where we hook up the interceptor.\n\tclientConn, err := grpc.NewClient(\n\t\tserverListener.Addr().String(),\n\t\tgrpc.WithTransportCredentials(insecure.NewCredentials()),\n\t)\n\trequire.NoError(t, err, \"must not error on client Dial\")\n\n\ttestClient := NewTestServiceClient(clientConn)\n\tselect {\n\tcase clientConnErr := <-stopped:\n\t\tt.Fatal(\"gRPC server stopped prematurely\", clientConnErr)\n\tdefault:\n\t}\n\n\tr, err := testClient.PingEmpty(context.Background(), &PingEmptyRequest{})\n\trequire.NoError(t, err)\n\trequire.NotNil(t, r)\n\n\tr2, err := testClient.Ping(context.Background(), &PingRequest{Value: \"24\"})\n\trequire.NoError(t, err)\n\trequire.Equal(t, \"24\", r2.Value)\n\trequire.Equal(t, int32(0), r2.Counter)\n\n\t_, err = testClient.PingError(context.Background(), &PingErrorRequest{\n\t\tErrorCodeReturned: uint32(codes.Internal),\n\t\tValue:             \"24\",\n\t})\n\trequire.Error(t, err)\n\trequire.Equal(t, codes.Internal, status.Code(err))\n\n\tl, err := testClient.PingList(context.Background(), &PingListRequest{Value: \"24\"})\n\trequire.NoError(t, err)\n\tfor i := 0; i < ListResponseCount; i++ {\n\t\tr, receiveError := l.Recv()\n\t\trequire.NoError(t, receiveError)\n\t\trequire.Equal(t, \"24\", r.Value)\n\t\trequire.Equal(t, int32(i), r.Counter)\n\t}\n\n\ts, err := testClient.PingStream(context.Background())\n\trequire.NoError(t, err)\n\tfor i := 0; i < ListResponseCount; i++ {\n\t\trequire.NoError(t, s.Send(&PingStreamRequest{Value: fmt.Sprintf(\"%v\", i)}))\n\n\t\tr, err := s.Recv()\n\t\trequire.NoError(t, err)\n\t\trequire.Equal(t, fmt.Sprintf(\"%v\", i), r.Value)\n\t\trequire.Equal(t, int32(i), r.Counter)\n\t}\n\n\tselect {\n\tcase err := <-stopped:\n\t\tt.Fatal(\"gRPC server stopped prematurely\", err)\n\tdefault:\n\t}\n}\n\nfunc TestTestServicePing_PingError(t *testing.T) {\n\ttestCases := map[string]struct {\n\t\trequest   *PingErrorRequest\n\t\terr       error\n\t\tunwrapped error\n\t\tmsg       string\n\t}{\n\t\t\"NotFound\": {\n\t\t\trequest:   &PingErrorRequest{ErrorCodeReturned: uint32(codes.NotFound), Value: \"not found\"},\n\t\t\terr:       &wrappedErrFields{wrappedErr: status.Error(codes.NotFound, \"Userspace error\"), fields: []any{\"error-field\", \"plop\"}},\n\t\t\tunwrapped: status.Error(codes.NotFound, \"Userspace error\"),\n\t\t\tmsg:       \"rpc error: code = NotFound desc = Userspace error\",\n\t\t},\n\t\t\"OK\": {\n\t\t\trequest:   &PingErrorRequest{ErrorCodeReturned: uint32(codes.OK), Value: \"ok\"},\n\t\t\terr:       &wrappedErrFields{wrappedErr: nil, fields: []any{\"error-field\", \"plop\"}},\n\t\t\tunwrapped: nil,\n\t\t\tmsg:       \"\",\n\t\t},\n\t}\n\n\tfor name, testCase := range testCases {\n\t\tt.Run(name, func(t *testing.T) {\n\t\t\tsvc := &TestPingService{}\n\n\t\t\t_, err := svc.PingError(context.Background(), testCase.request)\n\t\t\trequire.Equal(t, testCase.err, err)\n\n\t\t\tvar we *wrappedErrFields\n\t\t\tok := errors.As(err, &we)\n\t\t\trequire.True(t, ok)\n\n\t\t\tassert.Equal(t, testCase.unwrapped, we.Unwrap())\n\t\t\tassert.Equal(t, testCase.msg, we.Error())\n\t\t})\n\t}\n}\n"
  },
  {
    "path": "testing/testpb/test.manual_validator.pb.go",
    "content": "// Manual code for validation tests.\n\npackage testpb\n\nimport (\n\t\"errors\"\n\t\"math\"\n)\n\nfunc (x *PingRequest) Validate(bool) error {\n\tif x.SleepTimeMs > 10000 {\n\t\treturn errors.New(\"cannot sleep for more than 10s\")\n\t}\n\treturn nil\n}\n\nfunc (x *PingErrorRequest) Validate() error {\n\tif x.SleepTimeMs > 10000 {\n\t\treturn errors.New(\"cannot sleep for more than 10s\")\n\t}\n\treturn nil\n}\n\nfunc (x *PingListRequest) Validate(bool) error {\n\tif x.SleepTimeMs > 10000 {\n\t\treturn errors.New(\"cannot sleep for more than 10s\")\n\t}\n\treturn nil\n}\n\nfunc (x *PingStreamRequest) Validate(bool) error {\n\tif x.SleepTimeMs > 10000 {\n\t\treturn errors.New(\"cannot sleep for more than 10s\")\n\t}\n\treturn nil\n}\n\n// Validate implements the legacy validation interface from protoc-gen-validate.\nfunc (x *PingResponse) Validate() error {\n\tif x.Counter > math.MaxInt16 {\n\t\treturn errors.New(\"ping allocation exceeded\")\n\t}\n\treturn nil\n}\n\n// ValidateAll implements the new ValidateAll interface from protoc-gen-validate.\nfunc (x *PingResponse) ValidateAll() error {\n\tif x.Counter > math.MaxInt16 {\n\t\treturn errors.New(\"ping allocation exceeded\")\n\t}\n\treturn nil\n}\n\nvar (\n\tGoodPing       = &PingRequest{Value: \"something\", SleepTimeMs: 9999}\n\tGoodPingError  = &PingErrorRequest{Value: \"something\", SleepTimeMs: 9999}\n\tGoodPingList   = &PingListRequest{Value: \"something\", SleepTimeMs: 9999}\n\tGoodPingStream = &PingStreamRequest{Value: \"something\", SleepTimeMs: 9999}\n\n\tBadPing       = &PingRequest{Value: \"something\", SleepTimeMs: 10001}\n\tBadPingError  = &PingErrorRequest{Value: \"something\", SleepTimeMs: 10001}\n\tBadPingList   = &PingListRequest{Value: \"something\", SleepTimeMs: 10001}\n\tBadPingStream = &PingStreamRequest{Value: \"something\", SleepTimeMs: 10001}\n\n\tGoodPingResponse = &PingResponse{Counter: 100}\n\tBadPingResponse  = &PingResponse{Counter: math.MaxInt16 + 1}\n)\n"
  },
  {
    "path": "testing/testpb/test.pb.go",
    "content": "// Code generated by protoc-gen-go. DO NOT EDIT.\n// versions:\n// \tprotoc-gen-go v1.36.5\n// \tprotoc        v6.31.1\n// source: test.proto\n\npackage testpb\n\nimport (\n\treflect \"reflect\"\n\tsync \"sync\"\n\tunsafe \"unsafe\"\n\n\tprotoreflect \"google.golang.org/protobuf/reflect/protoreflect\"\n\tprotoimpl \"google.golang.org/protobuf/runtime/protoimpl\"\n)\n\nconst (\n\t// Verify that this generated code is sufficiently up-to-date.\n\t_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)\n\t// Verify that runtime/protoimpl is sufficiently up-to-date.\n\t_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)\n)\n\ntype PingEmptyRequest struct {\n\tstate         protoimpl.MessageState `protogen:\"open.v1\"`\n\tunknownFields protoimpl.UnknownFields\n\tsizeCache     protoimpl.SizeCache\n}\n\nfunc (x *PingEmptyRequest) Reset() {\n\t*x = PingEmptyRequest{}\n\tmi := &file_test_proto_msgTypes[0]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *PingEmptyRequest) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*PingEmptyRequest) ProtoMessage() {}\n\nfunc (x *PingEmptyRequest) ProtoReflect() protoreflect.Message {\n\tmi := &file_test_proto_msgTypes[0]\n\tif x != nil {\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tif ms.LoadMessageInfo() == nil {\n\t\t\tms.StoreMessageInfo(mi)\n\t\t}\n\t\treturn ms\n\t}\n\treturn mi.MessageOf(x)\n}\n\n// Deprecated: Use PingEmptyRequest.ProtoReflect.Descriptor instead.\nfunc (*PingEmptyRequest) Descriptor() ([]byte, []int) {\n\treturn file_test_proto_rawDescGZIP(), []int{0}\n}\n\ntype PingEmptyResponse struct {\n\tstate         protoimpl.MessageState `protogen:\"open.v1\"`\n\tunknownFields protoimpl.UnknownFields\n\tsizeCache     protoimpl.SizeCache\n}\n\nfunc (x *PingEmptyResponse) Reset() {\n\t*x = PingEmptyResponse{}\n\tmi := &file_test_proto_msgTypes[1]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *PingEmptyResponse) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*PingEmptyResponse) ProtoMessage() {}\n\nfunc (x *PingEmptyResponse) ProtoReflect() protoreflect.Message {\n\tmi := &file_test_proto_msgTypes[1]\n\tif x != nil {\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tif ms.LoadMessageInfo() == nil {\n\t\t\tms.StoreMessageInfo(mi)\n\t\t}\n\t\treturn ms\n\t}\n\treturn mi.MessageOf(x)\n}\n\n// Deprecated: Use PingEmptyResponse.ProtoReflect.Descriptor instead.\nfunc (*PingEmptyResponse) Descriptor() ([]byte, []int) {\n\treturn file_test_proto_rawDescGZIP(), []int{1}\n}\n\ntype PingRequest struct {\n\tstate             protoimpl.MessageState `protogen:\"open.v1\"`\n\tValue             string                 `protobuf:\"bytes,1,opt,name=value,proto3\" json:\"value,omitempty\"`\n\tSleepTimeMs       int32                  `protobuf:\"varint,2,opt,name=sleep_time_ms,json=sleepTimeMs,proto3\" json:\"sleep_time_ms,omitempty\"`\n\tErrorCodeReturned uint32                 `protobuf:\"varint,3,opt,name=error_code_returned,json=errorCodeReturned,proto3\" json:\"error_code_returned,omitempty\"`\n\tunknownFields     protoimpl.UnknownFields\n\tsizeCache         protoimpl.SizeCache\n}\n\nfunc (x *PingRequest) Reset() {\n\t*x = PingRequest{}\n\tmi := &file_test_proto_msgTypes[2]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *PingRequest) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*PingRequest) ProtoMessage() {}\n\nfunc (x *PingRequest) ProtoReflect() protoreflect.Message {\n\tmi := &file_test_proto_msgTypes[2]\n\tif x != nil {\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tif ms.LoadMessageInfo() == nil {\n\t\t\tms.StoreMessageInfo(mi)\n\t\t}\n\t\treturn ms\n\t}\n\treturn mi.MessageOf(x)\n}\n\n// Deprecated: Use PingRequest.ProtoReflect.Descriptor instead.\nfunc (*PingRequest) Descriptor() ([]byte, []int) {\n\treturn file_test_proto_rawDescGZIP(), []int{2}\n}\n\nfunc (x *PingRequest) GetValue() string {\n\tif x != nil {\n\t\treturn x.Value\n\t}\n\treturn \"\"\n}\n\nfunc (x *PingRequest) GetSleepTimeMs() int32 {\n\tif x != nil {\n\t\treturn x.SleepTimeMs\n\t}\n\treturn 0\n}\n\nfunc (x *PingRequest) GetErrorCodeReturned() uint32 {\n\tif x != nil {\n\t\treturn x.ErrorCodeReturned\n\t}\n\treturn 0\n}\n\ntype PingResponse struct {\n\tstate         protoimpl.MessageState `protogen:\"open.v1\"`\n\tValue         string                 `protobuf:\"bytes,1,opt,name=value,proto3\" json:\"value,omitempty\"`\n\tCounter       int32                  `protobuf:\"varint,2,opt,name=counter,proto3\" json:\"counter,omitempty\"`\n\tunknownFields protoimpl.UnknownFields\n\tsizeCache     protoimpl.SizeCache\n}\n\nfunc (x *PingResponse) Reset() {\n\t*x = PingResponse{}\n\tmi := &file_test_proto_msgTypes[3]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *PingResponse) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*PingResponse) ProtoMessage() {}\n\nfunc (x *PingResponse) ProtoReflect() protoreflect.Message {\n\tmi := &file_test_proto_msgTypes[3]\n\tif x != nil {\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tif ms.LoadMessageInfo() == nil {\n\t\t\tms.StoreMessageInfo(mi)\n\t\t}\n\t\treturn ms\n\t}\n\treturn mi.MessageOf(x)\n}\n\n// Deprecated: Use PingResponse.ProtoReflect.Descriptor instead.\nfunc (*PingResponse) Descriptor() ([]byte, []int) {\n\treturn file_test_proto_rawDescGZIP(), []int{3}\n}\n\nfunc (x *PingResponse) GetValue() string {\n\tif x != nil {\n\t\treturn x.Value\n\t}\n\treturn \"\"\n}\n\nfunc (x *PingResponse) GetCounter() int32 {\n\tif x != nil {\n\t\treturn x.Counter\n\t}\n\treturn 0\n}\n\ntype PingErrorRequest struct {\n\tstate             protoimpl.MessageState `protogen:\"open.v1\"`\n\tValue             string                 `protobuf:\"bytes,1,opt,name=value,proto3\" json:\"value,omitempty\"`\n\tSleepTimeMs       int32                  `protobuf:\"varint,2,opt,name=sleep_time_ms,json=sleepTimeMs,proto3\" json:\"sleep_time_ms,omitempty\"`\n\tErrorCodeReturned uint32                 `protobuf:\"varint,3,opt,name=error_code_returned,json=errorCodeReturned,proto3\" json:\"error_code_returned,omitempty\"`\n\tunknownFields     protoimpl.UnknownFields\n\tsizeCache         protoimpl.SizeCache\n}\n\nfunc (x *PingErrorRequest) Reset() {\n\t*x = PingErrorRequest{}\n\tmi := &file_test_proto_msgTypes[4]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *PingErrorRequest) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*PingErrorRequest) ProtoMessage() {}\n\nfunc (x *PingErrorRequest) ProtoReflect() protoreflect.Message {\n\tmi := &file_test_proto_msgTypes[4]\n\tif x != nil {\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tif ms.LoadMessageInfo() == nil {\n\t\t\tms.StoreMessageInfo(mi)\n\t\t}\n\t\treturn ms\n\t}\n\treturn mi.MessageOf(x)\n}\n\n// Deprecated: Use PingErrorRequest.ProtoReflect.Descriptor instead.\nfunc (*PingErrorRequest) Descriptor() ([]byte, []int) {\n\treturn file_test_proto_rawDescGZIP(), []int{4}\n}\n\nfunc (x *PingErrorRequest) GetValue() string {\n\tif x != nil {\n\t\treturn x.Value\n\t}\n\treturn \"\"\n}\n\nfunc (x *PingErrorRequest) GetSleepTimeMs() int32 {\n\tif x != nil {\n\t\treturn x.SleepTimeMs\n\t}\n\treturn 0\n}\n\nfunc (x *PingErrorRequest) GetErrorCodeReturned() uint32 {\n\tif x != nil {\n\t\treturn x.ErrorCodeReturned\n\t}\n\treturn 0\n}\n\ntype PingErrorResponse struct {\n\tstate         protoimpl.MessageState `protogen:\"open.v1\"`\n\tValue         string                 `protobuf:\"bytes,1,opt,name=value,proto3\" json:\"value,omitempty\"`\n\tCounter       int32                  `protobuf:\"varint,2,opt,name=counter,proto3\" json:\"counter,omitempty\"`\n\tunknownFields protoimpl.UnknownFields\n\tsizeCache     protoimpl.SizeCache\n}\n\nfunc (x *PingErrorResponse) Reset() {\n\t*x = PingErrorResponse{}\n\tmi := &file_test_proto_msgTypes[5]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *PingErrorResponse) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*PingErrorResponse) ProtoMessage() {}\n\nfunc (x *PingErrorResponse) ProtoReflect() protoreflect.Message {\n\tmi := &file_test_proto_msgTypes[5]\n\tif x != nil {\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tif ms.LoadMessageInfo() == nil {\n\t\t\tms.StoreMessageInfo(mi)\n\t\t}\n\t\treturn ms\n\t}\n\treturn mi.MessageOf(x)\n}\n\n// Deprecated: Use PingErrorResponse.ProtoReflect.Descriptor instead.\nfunc (*PingErrorResponse) Descriptor() ([]byte, []int) {\n\treturn file_test_proto_rawDescGZIP(), []int{5}\n}\n\nfunc (x *PingErrorResponse) GetValue() string {\n\tif x != nil {\n\t\treturn x.Value\n\t}\n\treturn \"\"\n}\n\nfunc (x *PingErrorResponse) GetCounter() int32 {\n\tif x != nil {\n\t\treturn x.Counter\n\t}\n\treturn 0\n}\n\ntype PingListRequest struct {\n\tstate             protoimpl.MessageState `protogen:\"open.v1\"`\n\tValue             string                 `protobuf:\"bytes,1,opt,name=value,proto3\" json:\"value,omitempty\"`\n\tSleepTimeMs       int32                  `protobuf:\"varint,2,opt,name=sleep_time_ms,json=sleepTimeMs,proto3\" json:\"sleep_time_ms,omitempty\"`\n\tErrorCodeReturned uint32                 `protobuf:\"varint,3,opt,name=error_code_returned,json=errorCodeReturned,proto3\" json:\"error_code_returned,omitempty\"`\n\tunknownFields     protoimpl.UnknownFields\n\tsizeCache         protoimpl.SizeCache\n}\n\nfunc (x *PingListRequest) Reset() {\n\t*x = PingListRequest{}\n\tmi := &file_test_proto_msgTypes[6]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *PingListRequest) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*PingListRequest) ProtoMessage() {}\n\nfunc (x *PingListRequest) ProtoReflect() protoreflect.Message {\n\tmi := &file_test_proto_msgTypes[6]\n\tif x != nil {\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tif ms.LoadMessageInfo() == nil {\n\t\t\tms.StoreMessageInfo(mi)\n\t\t}\n\t\treturn ms\n\t}\n\treturn mi.MessageOf(x)\n}\n\n// Deprecated: Use PingListRequest.ProtoReflect.Descriptor instead.\nfunc (*PingListRequest) Descriptor() ([]byte, []int) {\n\treturn file_test_proto_rawDescGZIP(), []int{6}\n}\n\nfunc (x *PingListRequest) GetValue() string {\n\tif x != nil {\n\t\treturn x.Value\n\t}\n\treturn \"\"\n}\n\nfunc (x *PingListRequest) GetSleepTimeMs() int32 {\n\tif x != nil {\n\t\treturn x.SleepTimeMs\n\t}\n\treturn 0\n}\n\nfunc (x *PingListRequest) GetErrorCodeReturned() uint32 {\n\tif x != nil {\n\t\treturn x.ErrorCodeReturned\n\t}\n\treturn 0\n}\n\ntype PingListResponse struct {\n\tstate         protoimpl.MessageState `protogen:\"open.v1\"`\n\tValue         string                 `protobuf:\"bytes,1,opt,name=value,proto3\" json:\"value,omitempty\"`\n\tCounter       int32                  `protobuf:\"varint,2,opt,name=counter,proto3\" json:\"counter,omitempty\"`\n\tunknownFields protoimpl.UnknownFields\n\tsizeCache     protoimpl.SizeCache\n}\n\nfunc (x *PingListResponse) Reset() {\n\t*x = PingListResponse{}\n\tmi := &file_test_proto_msgTypes[7]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *PingListResponse) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*PingListResponse) ProtoMessage() {}\n\nfunc (x *PingListResponse) ProtoReflect() protoreflect.Message {\n\tmi := &file_test_proto_msgTypes[7]\n\tif x != nil {\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tif ms.LoadMessageInfo() == nil {\n\t\t\tms.StoreMessageInfo(mi)\n\t\t}\n\t\treturn ms\n\t}\n\treturn mi.MessageOf(x)\n}\n\n// Deprecated: Use PingListResponse.ProtoReflect.Descriptor instead.\nfunc (*PingListResponse) Descriptor() ([]byte, []int) {\n\treturn file_test_proto_rawDescGZIP(), []int{7}\n}\n\nfunc (x *PingListResponse) GetValue() string {\n\tif x != nil {\n\t\treturn x.Value\n\t}\n\treturn \"\"\n}\n\nfunc (x *PingListResponse) GetCounter() int32 {\n\tif x != nil {\n\t\treturn x.Counter\n\t}\n\treturn 0\n}\n\ntype PingStreamRequest struct {\n\tstate             protoimpl.MessageState `protogen:\"open.v1\"`\n\tValue             string                 `protobuf:\"bytes,1,opt,name=value,proto3\" json:\"value,omitempty\"`\n\tSleepTimeMs       int32                  `protobuf:\"varint,2,opt,name=sleep_time_ms,json=sleepTimeMs,proto3\" json:\"sleep_time_ms,omitempty\"`\n\tErrorCodeReturned uint32                 `protobuf:\"varint,3,opt,name=error_code_returned,json=errorCodeReturned,proto3\" json:\"error_code_returned,omitempty\"`\n\tunknownFields     protoimpl.UnknownFields\n\tsizeCache         protoimpl.SizeCache\n}\n\nfunc (x *PingStreamRequest) Reset() {\n\t*x = PingStreamRequest{}\n\tmi := &file_test_proto_msgTypes[8]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *PingStreamRequest) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*PingStreamRequest) ProtoMessage() {}\n\nfunc (x *PingStreamRequest) ProtoReflect() protoreflect.Message {\n\tmi := &file_test_proto_msgTypes[8]\n\tif x != nil {\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tif ms.LoadMessageInfo() == nil {\n\t\t\tms.StoreMessageInfo(mi)\n\t\t}\n\t\treturn ms\n\t}\n\treturn mi.MessageOf(x)\n}\n\n// Deprecated: Use PingStreamRequest.ProtoReflect.Descriptor instead.\nfunc (*PingStreamRequest) Descriptor() ([]byte, []int) {\n\treturn file_test_proto_rawDescGZIP(), []int{8}\n}\n\nfunc (x *PingStreamRequest) GetValue() string {\n\tif x != nil {\n\t\treturn x.Value\n\t}\n\treturn \"\"\n}\n\nfunc (x *PingStreamRequest) GetSleepTimeMs() int32 {\n\tif x != nil {\n\t\treturn x.SleepTimeMs\n\t}\n\treturn 0\n}\n\nfunc (x *PingStreamRequest) GetErrorCodeReturned() uint32 {\n\tif x != nil {\n\t\treturn x.ErrorCodeReturned\n\t}\n\treturn 0\n}\n\ntype PingStreamResponse struct {\n\tstate         protoimpl.MessageState `protogen:\"open.v1\"`\n\tValue         string                 `protobuf:\"bytes,1,opt,name=value,proto3\" json:\"value,omitempty\"`\n\tCounter       int32                  `protobuf:\"varint,2,opt,name=counter,proto3\" json:\"counter,omitempty\"`\n\tunknownFields protoimpl.UnknownFields\n\tsizeCache     protoimpl.SizeCache\n}\n\nfunc (x *PingStreamResponse) Reset() {\n\t*x = PingStreamResponse{}\n\tmi := &file_test_proto_msgTypes[9]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *PingStreamResponse) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*PingStreamResponse) ProtoMessage() {}\n\nfunc (x *PingStreamResponse) ProtoReflect() protoreflect.Message {\n\tmi := &file_test_proto_msgTypes[9]\n\tif x != nil {\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tif ms.LoadMessageInfo() == nil {\n\t\t\tms.StoreMessageInfo(mi)\n\t\t}\n\t\treturn ms\n\t}\n\treturn mi.MessageOf(x)\n}\n\n// Deprecated: Use PingStreamResponse.ProtoReflect.Descriptor instead.\nfunc (*PingStreamResponse) Descriptor() ([]byte, []int) {\n\treturn file_test_proto_rawDescGZIP(), []int{9}\n}\n\nfunc (x *PingStreamResponse) GetValue() string {\n\tif x != nil {\n\t\treturn x.Value\n\t}\n\treturn \"\"\n}\n\nfunc (x *PingStreamResponse) GetCounter() int32 {\n\tif x != nil {\n\t\treturn x.Counter\n\t}\n\treturn 0\n}\n\ntype PingClientStreamRequest struct {\n\tstate             protoimpl.MessageState `protogen:\"open.v1\"`\n\tValue             string                 `protobuf:\"bytes,1,opt,name=value,proto3\" json:\"value,omitempty\"`\n\tSleepTimeMs       int32                  `protobuf:\"varint,2,opt,name=sleep_time_ms,json=sleepTimeMs,proto3\" json:\"sleep_time_ms,omitempty\"`\n\tErrorCodeReturned uint32                 `protobuf:\"varint,3,opt,name=error_code_returned,json=errorCodeReturned,proto3\" json:\"error_code_returned,omitempty\"`\n\tunknownFields     protoimpl.UnknownFields\n\tsizeCache         protoimpl.SizeCache\n}\n\nfunc (x *PingClientStreamRequest) Reset() {\n\t*x = PingClientStreamRequest{}\n\tmi := &file_test_proto_msgTypes[10]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *PingClientStreamRequest) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*PingClientStreamRequest) ProtoMessage() {}\n\nfunc (x *PingClientStreamRequest) ProtoReflect() protoreflect.Message {\n\tmi := &file_test_proto_msgTypes[10]\n\tif x != nil {\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tif ms.LoadMessageInfo() == nil {\n\t\t\tms.StoreMessageInfo(mi)\n\t\t}\n\t\treturn ms\n\t}\n\treturn mi.MessageOf(x)\n}\n\n// Deprecated: Use PingClientStreamRequest.ProtoReflect.Descriptor instead.\nfunc (*PingClientStreamRequest) Descriptor() ([]byte, []int) {\n\treturn file_test_proto_rawDescGZIP(), []int{10}\n}\n\nfunc (x *PingClientStreamRequest) GetValue() string {\n\tif x != nil {\n\t\treturn x.Value\n\t}\n\treturn \"\"\n}\n\nfunc (x *PingClientStreamRequest) GetSleepTimeMs() int32 {\n\tif x != nil {\n\t\treturn x.SleepTimeMs\n\t}\n\treturn 0\n}\n\nfunc (x *PingClientStreamRequest) GetErrorCodeReturned() uint32 {\n\tif x != nil {\n\t\treturn x.ErrorCodeReturned\n\t}\n\treturn 0\n}\n\ntype PingClientStreamResponse struct {\n\tstate         protoimpl.MessageState `protogen:\"open.v1\"`\n\tCounter       int32                  `protobuf:\"varint,1,opt,name=counter,proto3\" json:\"counter,omitempty\"`\n\tunknownFields protoimpl.UnknownFields\n\tsizeCache     protoimpl.SizeCache\n}\n\nfunc (x *PingClientStreamResponse) Reset() {\n\t*x = PingClientStreamResponse{}\n\tmi := &file_test_proto_msgTypes[11]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *PingClientStreamResponse) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*PingClientStreamResponse) ProtoMessage() {}\n\nfunc (x *PingClientStreamResponse) ProtoReflect() protoreflect.Message {\n\tmi := &file_test_proto_msgTypes[11]\n\tif x != nil {\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tif ms.LoadMessageInfo() == nil {\n\t\t\tms.StoreMessageInfo(mi)\n\t\t}\n\t\treturn ms\n\t}\n\treturn mi.MessageOf(x)\n}\n\n// Deprecated: Use PingClientStreamResponse.ProtoReflect.Descriptor instead.\nfunc (*PingClientStreamResponse) Descriptor() ([]byte, []int) {\n\treturn file_test_proto_rawDescGZIP(), []int{11}\n}\n\nfunc (x *PingClientStreamResponse) GetCounter() int32 {\n\tif x != nil {\n\t\treturn x.Counter\n\t}\n\treturn 0\n}\n\nvar File_test_proto protoreflect.FileDescriptor\n\nvar file_test_proto_rawDesc = string([]byte{\n\t0x0a, 0x0a, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x11, 0x74, 0x65,\n\t0x73, 0x74, 0x69, 0x6e, 0x67, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x70, 0x62, 0x2e, 0x76, 0x31, 0x22,\n\t0x12, 0x0a, 0x10, 0x50, 0x69, 0x6e, 0x67, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x52, 0x65, 0x71, 0x75,\n\t0x65, 0x73, 0x74, 0x22, 0x13, 0x0a, 0x11, 0x50, 0x69, 0x6e, 0x67, 0x45, 0x6d, 0x70, 0x74, 0x79,\n\t0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x77, 0x0a, 0x0b, 0x50, 0x69, 0x6e, 0x67,\n\t0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65,\n\t0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x22, 0x0a,\n\t0x0d, 0x73, 0x6c, 0x65, 0x65, 0x70, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x5f, 0x6d, 0x73, 0x18, 0x02,\n\t0x20, 0x01, 0x28, 0x05, 0x52, 0x0b, 0x73, 0x6c, 0x65, 0x65, 0x70, 0x54, 0x69, 0x6d, 0x65, 0x4d,\n\t0x73, 0x12, 0x2e, 0x0a, 0x13, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x5f,\n\t0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x65, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x11,\n\t0x65, 0x72, 0x72, 0x6f, 0x72, 0x43, 0x6f, 0x64, 0x65, 0x52, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x65,\n\t0x64, 0x22, 0x3e, 0x0a, 0x0c, 0x50, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,\n\t0x65, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09,\n\t0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x6f, 0x75, 0x6e, 0x74,\n\t0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x07, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x65,\n\t0x72, 0x22, 0x7c, 0x0a, 0x10, 0x50, 0x69, 0x6e, 0x67, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x52, 0x65,\n\t0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x01,\n\t0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x22, 0x0a, 0x0d, 0x73,\n\t0x6c, 0x65, 0x65, 0x70, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x5f, 0x6d, 0x73, 0x18, 0x02, 0x20, 0x01,\n\t0x28, 0x05, 0x52, 0x0b, 0x73, 0x6c, 0x65, 0x65, 0x70, 0x54, 0x69, 0x6d, 0x65, 0x4d, 0x73, 0x12,\n\t0x2e, 0x0a, 0x13, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x5f, 0x72, 0x65,\n\t0x74, 0x75, 0x72, 0x6e, 0x65, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x11, 0x65, 0x72,\n\t0x72, 0x6f, 0x72, 0x43, 0x6f, 0x64, 0x65, 0x52, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x65, 0x64, 0x22,\n\t0x43, 0x0a, 0x11, 0x50, 0x69, 0x6e, 0x67, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x52, 0x65, 0x73, 0x70,\n\t0x6f, 0x6e, 0x73, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x01, 0x20,\n\t0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x6f,\n\t0x75, 0x6e, 0x74, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x07, 0x63, 0x6f, 0x75,\n\t0x6e, 0x74, 0x65, 0x72, 0x22, 0x7b, 0x0a, 0x0f, 0x50, 0x69, 0x6e, 0x67, 0x4c, 0x69, 0x73, 0x74,\n\t0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65,\n\t0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x22, 0x0a,\n\t0x0d, 0x73, 0x6c, 0x65, 0x65, 0x70, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x5f, 0x6d, 0x73, 0x18, 0x02,\n\t0x20, 0x01, 0x28, 0x05, 0x52, 0x0b, 0x73, 0x6c, 0x65, 0x65, 0x70, 0x54, 0x69, 0x6d, 0x65, 0x4d,\n\t0x73, 0x12, 0x2e, 0x0a, 0x13, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x5f,\n\t0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x65, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x11,\n\t0x65, 0x72, 0x72, 0x6f, 0x72, 0x43, 0x6f, 0x64, 0x65, 0x52, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x65,\n\t0x64, 0x22, 0x42, 0x0a, 0x10, 0x50, 0x69, 0x6e, 0x67, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73,\n\t0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x01,\n\t0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x63,\n\t0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x07, 0x63, 0x6f,\n\t0x75, 0x6e, 0x74, 0x65, 0x72, 0x22, 0x7d, 0x0a, 0x11, 0x50, 0x69, 0x6e, 0x67, 0x53, 0x74, 0x72,\n\t0x65, 0x61, 0x6d, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61,\n\t0x6c, 0x75, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65,\n\t0x12, 0x22, 0x0a, 0x0d, 0x73, 0x6c, 0x65, 0x65, 0x70, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x5f, 0x6d,\n\t0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0b, 0x73, 0x6c, 0x65, 0x65, 0x70, 0x54, 0x69,\n\t0x6d, 0x65, 0x4d, 0x73, 0x12, 0x2e, 0x0a, 0x13, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x5f, 0x63, 0x6f,\n\t0x64, 0x65, 0x5f, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x65, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28,\n\t0x0d, 0x52, 0x11, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x43, 0x6f, 0x64, 0x65, 0x52, 0x65, 0x74, 0x75,\n\t0x72, 0x6e, 0x65, 0x64, 0x22, 0x44, 0x0a, 0x12, 0x50, 0x69, 0x6e, 0x67, 0x53, 0x74, 0x72, 0x65,\n\t0x61, 0x6d, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61,\n\t0x6c, 0x75, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65,\n\t0x12, 0x18, 0x0a, 0x07, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28,\n\t0x05, 0x52, 0x07, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x22, 0x83, 0x01, 0x0a, 0x17, 0x50,\n\t0x69, 0x6e, 0x67, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x52,\n\t0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18,\n\t0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x22, 0x0a, 0x0d,\n\t0x73, 0x6c, 0x65, 0x65, 0x70, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x5f, 0x6d, 0x73, 0x18, 0x02, 0x20,\n\t0x01, 0x28, 0x05, 0x52, 0x0b, 0x73, 0x6c, 0x65, 0x65, 0x70, 0x54, 0x69, 0x6d, 0x65, 0x4d, 0x73,\n\t0x12, 0x2e, 0x0a, 0x13, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x5f, 0x72,\n\t0x65, 0x74, 0x75, 0x72, 0x6e, 0x65, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x11, 0x65,\n\t0x72, 0x72, 0x6f, 0x72, 0x43, 0x6f, 0x64, 0x65, 0x52, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x65, 0x64,\n\t0x22, 0x34, 0x0a, 0x18, 0x50, 0x69, 0x6e, 0x67, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x53, 0x74,\n\t0x72, 0x65, 0x61, 0x6d, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, 0x07,\n\t0x63, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x07, 0x63,\n\t0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x32, 0xb7, 0x04, 0x0a, 0x0b, 0x54, 0x65, 0x73, 0x74, 0x53,\n\t0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x58, 0x0a, 0x09, 0x50, 0x69, 0x6e, 0x67, 0x45, 0x6d,\n\t0x70, 0x74, 0x79, 0x12, 0x23, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x67, 0x2e, 0x74, 0x65,\n\t0x73, 0x74, 0x70, 0x62, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x69, 0x6e, 0x67, 0x45, 0x6d, 0x70, 0x74,\n\t0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x24, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x69,\n\t0x6e, 0x67, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x70, 0x62, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x69, 0x6e,\n\t0x67, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00,\n\t0x12, 0x49, 0x0a, 0x04, 0x50, 0x69, 0x6e, 0x67, 0x12, 0x1e, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x69,\n\t0x6e, 0x67, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x70, 0x62, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x69, 0x6e,\n\t0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1f, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x69,\n\t0x6e, 0x67, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x70, 0x62, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x69, 0x6e,\n\t0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x58, 0x0a, 0x09, 0x50,\n\t0x69, 0x6e, 0x67, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x23, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x69,\n\t0x6e, 0x67, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x70, 0x62, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x69, 0x6e,\n\t0x67, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x24, 0x2e,\n\t0x74, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x67, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x70, 0x62, 0x2e, 0x76,\n\t0x31, 0x2e, 0x50, 0x69, 0x6e, 0x67, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f,\n\t0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x57, 0x0a, 0x08, 0x50, 0x69, 0x6e, 0x67, 0x4c, 0x69, 0x73,\n\t0x74, 0x12, 0x22, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x67, 0x2e, 0x74, 0x65, 0x73, 0x74,\n\t0x70, 0x62, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x69, 0x6e, 0x67, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65,\n\t0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x23, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x67, 0x2e,\n\t0x74, 0x65, 0x73, 0x74, 0x70, 0x62, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x69, 0x6e, 0x67, 0x4c, 0x69,\n\t0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x30, 0x01, 0x12, 0x5f,\n\t0x0a, 0x0a, 0x50, 0x69, 0x6e, 0x67, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x12, 0x24, 0x2e, 0x74,\n\t0x65, 0x73, 0x74, 0x69, 0x6e, 0x67, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x70, 0x62, 0x2e, 0x76, 0x31,\n\t0x2e, 0x50, 0x69, 0x6e, 0x67, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x52, 0x65, 0x71, 0x75, 0x65,\n\t0x73, 0x74, 0x1a, 0x25, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x67, 0x2e, 0x74, 0x65, 0x73,\n\t0x74, 0x70, 0x62, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x69, 0x6e, 0x67, 0x53, 0x74, 0x72, 0x65, 0x61,\n\t0x6d, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x28, 0x01, 0x30, 0x01, 0x12,\n\t0x6f, 0x0a, 0x10, 0x50, 0x69, 0x6e, 0x67, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x53, 0x74, 0x72,\n\t0x65, 0x61, 0x6d, 0x12, 0x2a, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x67, 0x2e, 0x74, 0x65,\n\t0x73, 0x74, 0x70, 0x62, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x69, 0x6e, 0x67, 0x43, 0x6c, 0x69, 0x65,\n\t0x6e, 0x74, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a,\n\t0x2b, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x67, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x70, 0x62,\n\t0x2e, 0x76, 0x31, 0x2e, 0x50, 0x69, 0x6e, 0x67, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x53, 0x74,\n\t0x72, 0x65, 0x61, 0x6d, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x28, 0x01,\n\t0x42, 0x0a, 0x5a, 0x08, 0x2e, 0x3b, 0x74, 0x65, 0x73, 0x74, 0x70, 0x62, 0x62, 0x06, 0x70, 0x72,\n\t0x6f, 0x74, 0x6f, 0x33,\n})\n\nvar (\n\tfile_test_proto_rawDescOnce sync.Once\n\tfile_test_proto_rawDescData []byte\n)\n\nfunc file_test_proto_rawDescGZIP() []byte {\n\tfile_test_proto_rawDescOnce.Do(func() {\n\t\tfile_test_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_test_proto_rawDesc), len(file_test_proto_rawDesc)))\n\t})\n\treturn file_test_proto_rawDescData\n}\n\nvar file_test_proto_msgTypes = make([]protoimpl.MessageInfo, 12)\nvar file_test_proto_goTypes = []any{\n\t(*PingEmptyRequest)(nil),         // 0: testing.testpb.v1.PingEmptyRequest\n\t(*PingEmptyResponse)(nil),        // 1: testing.testpb.v1.PingEmptyResponse\n\t(*PingRequest)(nil),              // 2: testing.testpb.v1.PingRequest\n\t(*PingResponse)(nil),             // 3: testing.testpb.v1.PingResponse\n\t(*PingErrorRequest)(nil),         // 4: testing.testpb.v1.PingErrorRequest\n\t(*PingErrorResponse)(nil),        // 5: testing.testpb.v1.PingErrorResponse\n\t(*PingListRequest)(nil),          // 6: testing.testpb.v1.PingListRequest\n\t(*PingListResponse)(nil),         // 7: testing.testpb.v1.PingListResponse\n\t(*PingStreamRequest)(nil),        // 8: testing.testpb.v1.PingStreamRequest\n\t(*PingStreamResponse)(nil),       // 9: testing.testpb.v1.PingStreamResponse\n\t(*PingClientStreamRequest)(nil),  // 10: testing.testpb.v1.PingClientStreamRequest\n\t(*PingClientStreamResponse)(nil), // 11: testing.testpb.v1.PingClientStreamResponse\n}\nvar file_test_proto_depIdxs = []int32{\n\t0,  // 0: testing.testpb.v1.TestService.PingEmpty:input_type -> testing.testpb.v1.PingEmptyRequest\n\t2,  // 1: testing.testpb.v1.TestService.Ping:input_type -> testing.testpb.v1.PingRequest\n\t4,  // 2: testing.testpb.v1.TestService.PingError:input_type -> testing.testpb.v1.PingErrorRequest\n\t6,  // 3: testing.testpb.v1.TestService.PingList:input_type -> testing.testpb.v1.PingListRequest\n\t8,  // 4: testing.testpb.v1.TestService.PingStream:input_type -> testing.testpb.v1.PingStreamRequest\n\t10, // 5: testing.testpb.v1.TestService.PingClientStream:input_type -> testing.testpb.v1.PingClientStreamRequest\n\t1,  // 6: testing.testpb.v1.TestService.PingEmpty:output_type -> testing.testpb.v1.PingEmptyResponse\n\t3,  // 7: testing.testpb.v1.TestService.Ping:output_type -> testing.testpb.v1.PingResponse\n\t5,  // 8: testing.testpb.v1.TestService.PingError:output_type -> testing.testpb.v1.PingErrorResponse\n\t7,  // 9: testing.testpb.v1.TestService.PingList:output_type -> testing.testpb.v1.PingListResponse\n\t9,  // 10: testing.testpb.v1.TestService.PingStream:output_type -> testing.testpb.v1.PingStreamResponse\n\t11, // 11: testing.testpb.v1.TestService.PingClientStream:output_type -> testing.testpb.v1.PingClientStreamResponse\n\t6,  // [6:12] is the sub-list for method output_type\n\t0,  // [0:6] is the sub-list for method input_type\n\t0,  // [0:0] is the sub-list for extension type_name\n\t0,  // [0:0] is the sub-list for extension extendee\n\t0,  // [0:0] is the sub-list for field type_name\n}\n\nfunc init() { file_test_proto_init() }\nfunc file_test_proto_init() {\n\tif File_test_proto != nil {\n\t\treturn\n\t}\n\ttype x struct{}\n\tout := protoimpl.TypeBuilder{\n\t\tFile: protoimpl.DescBuilder{\n\t\t\tGoPackagePath: reflect.TypeOf(x{}).PkgPath(),\n\t\t\tRawDescriptor: unsafe.Slice(unsafe.StringData(file_test_proto_rawDesc), len(file_test_proto_rawDesc)),\n\t\t\tNumEnums:      0,\n\t\t\tNumMessages:   12,\n\t\t\tNumExtensions: 0,\n\t\t\tNumServices:   1,\n\t\t},\n\t\tGoTypes:           file_test_proto_goTypes,\n\t\tDependencyIndexes: file_test_proto_depIdxs,\n\t\tMessageInfos:      file_test_proto_msgTypes,\n\t}.Build()\n\tFile_test_proto = out.File\n\tfile_test_proto_goTypes = nil\n\tfile_test_proto_depIdxs = nil\n}\n"
  },
  {
    "path": "testing/testpb/test_grpc.pb.go",
    "content": "// Code generated by protoc-gen-go-grpc. DO NOT EDIT.\n// versions:\n// - protoc-gen-go-grpc v1.5.1\n// - protoc             v6.31.1\n// source: test.proto\n\npackage testpb\n\nimport (\n\tcontext \"context\"\n\n\tgrpc \"google.golang.org/grpc\"\n\tcodes \"google.golang.org/grpc/codes\"\n\tstatus \"google.golang.org/grpc/status\"\n)\n\n// This is a compile-time assertion to ensure that this generated file\n// is compatible with the grpc package it is being compiled against.\n// Requires gRPC-Go v1.64.0 or later.\nconst _ = grpc.SupportPackageIsVersion9\n\nconst (\n\tTestService_PingEmpty_FullMethodName        = \"/testing.testpb.v1.TestService/PingEmpty\"\n\tTestService_Ping_FullMethodName             = \"/testing.testpb.v1.TestService/Ping\"\n\tTestService_PingError_FullMethodName        = \"/testing.testpb.v1.TestService/PingError\"\n\tTestService_PingList_FullMethodName         = \"/testing.testpb.v1.TestService/PingList\"\n\tTestService_PingStream_FullMethodName       = \"/testing.testpb.v1.TestService/PingStream\"\n\tTestService_PingClientStream_FullMethodName = \"/testing.testpb.v1.TestService/PingClientStream\"\n)\n\n// TestServiceClient is the client API for TestService service.\n//\n// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream.\ntype TestServiceClient interface {\n\tPingEmpty(ctx context.Context, in *PingEmptyRequest, opts ...grpc.CallOption) (*PingEmptyResponse, error)\n\tPing(ctx context.Context, in *PingRequest, opts ...grpc.CallOption) (*PingResponse, error)\n\tPingError(ctx context.Context, in *PingErrorRequest, opts ...grpc.CallOption) (*PingErrorResponse, error)\n\tPingList(ctx context.Context, in *PingListRequest, opts ...grpc.CallOption) (grpc.ServerStreamingClient[PingListResponse], error)\n\tPingStream(ctx context.Context, opts ...grpc.CallOption) (grpc.BidiStreamingClient[PingStreamRequest, PingStreamResponse], error)\n\tPingClientStream(ctx context.Context, opts ...grpc.CallOption) (grpc.ClientStreamingClient[PingClientStreamRequest, PingClientStreamResponse], error)\n}\n\ntype testServiceClient struct {\n\tcc grpc.ClientConnInterface\n}\n\nfunc NewTestServiceClient(cc grpc.ClientConnInterface) TestServiceClient {\n\treturn &testServiceClient{cc}\n}\n\nfunc (c *testServiceClient) PingEmpty(ctx context.Context, in *PingEmptyRequest, opts ...grpc.CallOption) (*PingEmptyResponse, error) {\n\tcOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)\n\tout := new(PingEmptyResponse)\n\terr := c.cc.Invoke(ctx, TestService_PingEmpty_FullMethodName, in, out, cOpts...)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn out, nil\n}\n\nfunc (c *testServiceClient) Ping(ctx context.Context, in *PingRequest, opts ...grpc.CallOption) (*PingResponse, error) {\n\tcOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)\n\tout := new(PingResponse)\n\terr := c.cc.Invoke(ctx, TestService_Ping_FullMethodName, in, out, cOpts...)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn out, nil\n}\n\nfunc (c *testServiceClient) PingError(ctx context.Context, in *PingErrorRequest, opts ...grpc.CallOption) (*PingErrorResponse, error) {\n\tcOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)\n\tout := new(PingErrorResponse)\n\terr := c.cc.Invoke(ctx, TestService_PingError_FullMethodName, in, out, cOpts...)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn out, nil\n}\n\nfunc (c *testServiceClient) PingList(ctx context.Context, in *PingListRequest, opts ...grpc.CallOption) (grpc.ServerStreamingClient[PingListResponse], error) {\n\tcOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)\n\tstream, err := c.cc.NewStream(ctx, &TestService_ServiceDesc.Streams[0], TestService_PingList_FullMethodName, cOpts...)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tx := &grpc.GenericClientStream[PingListRequest, PingListResponse]{ClientStream: stream}\n\tif err := x.ClientStream.SendMsg(in); err != nil {\n\t\treturn nil, err\n\t}\n\tif err := x.ClientStream.CloseSend(); err != nil {\n\t\treturn nil, err\n\t}\n\treturn x, nil\n}\n\n// This type alias is provided for backwards compatibility with existing code that references the prior non-generic stream type by name.\ntype TestService_PingListClient = grpc.ServerStreamingClient[PingListResponse]\n\nfunc (c *testServiceClient) PingStream(ctx context.Context, opts ...grpc.CallOption) (grpc.BidiStreamingClient[PingStreamRequest, PingStreamResponse], error) {\n\tcOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)\n\tstream, err := c.cc.NewStream(ctx, &TestService_ServiceDesc.Streams[1], TestService_PingStream_FullMethodName, cOpts...)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tx := &grpc.GenericClientStream[PingStreamRequest, PingStreamResponse]{ClientStream: stream}\n\treturn x, nil\n}\n\n// This type alias is provided for backwards compatibility with existing code that references the prior non-generic stream type by name.\ntype TestService_PingStreamClient = grpc.BidiStreamingClient[PingStreamRequest, PingStreamResponse]\n\nfunc (c *testServiceClient) PingClientStream(ctx context.Context, opts ...grpc.CallOption) (grpc.ClientStreamingClient[PingClientStreamRequest, PingClientStreamResponse], error) {\n\tcOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)\n\tstream, err := c.cc.NewStream(ctx, &TestService_ServiceDesc.Streams[2], TestService_PingClientStream_FullMethodName, cOpts...)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tx := &grpc.GenericClientStream[PingClientStreamRequest, PingClientStreamResponse]{ClientStream: stream}\n\treturn x, nil\n}\n\n// This type alias is provided for backwards compatibility with existing code that references the prior non-generic stream type by name.\ntype TestService_PingClientStreamClient = grpc.ClientStreamingClient[PingClientStreamRequest, PingClientStreamResponse]\n\n// TestServiceServer is the server API for TestService service.\n// All implementations must embed UnimplementedTestServiceServer\n// for forward compatibility.\ntype TestServiceServer interface {\n\tPingEmpty(context.Context, *PingEmptyRequest) (*PingEmptyResponse, error)\n\tPing(context.Context, *PingRequest) (*PingResponse, error)\n\tPingError(context.Context, *PingErrorRequest) (*PingErrorResponse, error)\n\tPingList(*PingListRequest, grpc.ServerStreamingServer[PingListResponse]) error\n\tPingStream(grpc.BidiStreamingServer[PingStreamRequest, PingStreamResponse]) error\n\tPingClientStream(grpc.ClientStreamingServer[PingClientStreamRequest, PingClientStreamResponse]) error\n\tmustEmbedUnimplementedTestServiceServer()\n}\n\n// UnimplementedTestServiceServer must be embedded to have\n// forward compatible implementations.\n//\n// NOTE: this should be embedded by value instead of pointer to avoid a nil\n// pointer dereference when methods are called.\ntype UnimplementedTestServiceServer struct{}\n\nfunc (UnimplementedTestServiceServer) PingEmpty(context.Context, *PingEmptyRequest) (*PingEmptyResponse, error) {\n\treturn nil, status.Errorf(codes.Unimplemented, \"method PingEmpty not implemented\")\n}\nfunc (UnimplementedTestServiceServer) Ping(context.Context, *PingRequest) (*PingResponse, error) {\n\treturn nil, status.Errorf(codes.Unimplemented, \"method Ping not implemented\")\n}\nfunc (UnimplementedTestServiceServer) PingError(context.Context, *PingErrorRequest) (*PingErrorResponse, error) {\n\treturn nil, status.Errorf(codes.Unimplemented, \"method PingError not implemented\")\n}\nfunc (UnimplementedTestServiceServer) PingList(*PingListRequest, grpc.ServerStreamingServer[PingListResponse]) error {\n\treturn status.Errorf(codes.Unimplemented, \"method PingList not implemented\")\n}\nfunc (UnimplementedTestServiceServer) PingStream(grpc.BidiStreamingServer[PingStreamRequest, PingStreamResponse]) error {\n\treturn status.Errorf(codes.Unimplemented, \"method PingStream not implemented\")\n}\nfunc (UnimplementedTestServiceServer) PingClientStream(grpc.ClientStreamingServer[PingClientStreamRequest, PingClientStreamResponse]) error {\n\treturn status.Errorf(codes.Unimplemented, \"method PingClientStream not implemented\")\n}\nfunc (UnimplementedTestServiceServer) mustEmbedUnimplementedTestServiceServer() {}\nfunc (UnimplementedTestServiceServer) testEmbeddedByValue()                     {}\n\n// UnsafeTestServiceServer may be embedded to opt out of forward compatibility for this service.\n// Use of this interface is not recommended, as added methods to TestServiceServer will\n// result in compilation errors.\ntype UnsafeTestServiceServer interface {\n\tmustEmbedUnimplementedTestServiceServer()\n}\n\nfunc RegisterTestServiceServer(s grpc.ServiceRegistrar, srv TestServiceServer) {\n\t// If the following call pancis, it indicates UnimplementedTestServiceServer was\n\t// embedded by pointer and is nil.  This will cause panics if an\n\t// unimplemented method is ever invoked, so we test this at initialization\n\t// time to prevent it from happening at runtime later due to I/O.\n\tif t, ok := srv.(interface{ testEmbeddedByValue() }); ok {\n\t\tt.testEmbeddedByValue()\n\t}\n\ts.RegisterService(&TestService_ServiceDesc, srv)\n}\n\nfunc _TestService_PingEmpty_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {\n\tin := new(PingEmptyRequest)\n\tif err := dec(in); err != nil {\n\t\treturn nil, err\n\t}\n\tif interceptor == nil {\n\t\treturn srv.(TestServiceServer).PingEmpty(ctx, in)\n\t}\n\tinfo := &grpc.UnaryServerInfo{\n\t\tServer:     srv,\n\t\tFullMethod: TestService_PingEmpty_FullMethodName,\n\t}\n\thandler := func(ctx context.Context, req interface{}) (interface{}, error) {\n\t\treturn srv.(TestServiceServer).PingEmpty(ctx, req.(*PingEmptyRequest))\n\t}\n\treturn interceptor(ctx, in, info, handler)\n}\n\nfunc _TestService_Ping_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {\n\tin := new(PingRequest)\n\tif err := dec(in); err != nil {\n\t\treturn nil, err\n\t}\n\tif interceptor == nil {\n\t\treturn srv.(TestServiceServer).Ping(ctx, in)\n\t}\n\tinfo := &grpc.UnaryServerInfo{\n\t\tServer:     srv,\n\t\tFullMethod: TestService_Ping_FullMethodName,\n\t}\n\thandler := func(ctx context.Context, req interface{}) (interface{}, error) {\n\t\treturn srv.(TestServiceServer).Ping(ctx, req.(*PingRequest))\n\t}\n\treturn interceptor(ctx, in, info, handler)\n}\n\nfunc _TestService_PingError_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {\n\tin := new(PingErrorRequest)\n\tif err := dec(in); err != nil {\n\t\treturn nil, err\n\t}\n\tif interceptor == nil {\n\t\treturn srv.(TestServiceServer).PingError(ctx, in)\n\t}\n\tinfo := &grpc.UnaryServerInfo{\n\t\tServer:     srv,\n\t\tFullMethod: TestService_PingError_FullMethodName,\n\t}\n\thandler := func(ctx context.Context, req interface{}) (interface{}, error) {\n\t\treturn srv.(TestServiceServer).PingError(ctx, req.(*PingErrorRequest))\n\t}\n\treturn interceptor(ctx, in, info, handler)\n}\n\nfunc _TestService_PingList_Handler(srv interface{}, stream grpc.ServerStream) error {\n\tm := new(PingListRequest)\n\tif err := stream.RecvMsg(m); err != nil {\n\t\treturn err\n\t}\n\treturn srv.(TestServiceServer).PingList(m, &grpc.GenericServerStream[PingListRequest, PingListResponse]{ServerStream: stream})\n}\n\n// This type alias is provided for backwards compatibility with existing code that references the prior non-generic stream type by name.\ntype TestService_PingListServer = grpc.ServerStreamingServer[PingListResponse]\n\nfunc _TestService_PingStream_Handler(srv interface{}, stream grpc.ServerStream) error {\n\treturn srv.(TestServiceServer).PingStream(&grpc.GenericServerStream[PingStreamRequest, PingStreamResponse]{ServerStream: stream})\n}\n\n// This type alias is provided for backwards compatibility with existing code that references the prior non-generic stream type by name.\ntype TestService_PingStreamServer = grpc.BidiStreamingServer[PingStreamRequest, PingStreamResponse]\n\nfunc _TestService_PingClientStream_Handler(srv interface{}, stream grpc.ServerStream) error {\n\treturn srv.(TestServiceServer).PingClientStream(&grpc.GenericServerStream[PingClientStreamRequest, PingClientStreamResponse]{ServerStream: stream})\n}\n\n// This type alias is provided for backwards compatibility with existing code that references the prior non-generic stream type by name.\ntype TestService_PingClientStreamServer = grpc.ClientStreamingServer[PingClientStreamRequest, PingClientStreamResponse]\n\n// TestService_ServiceDesc is the grpc.ServiceDesc for TestService service.\n// It's only intended for direct use with grpc.RegisterService,\n// and not to be introspected or modified (even as a copy)\nvar TestService_ServiceDesc = grpc.ServiceDesc{\n\tServiceName: \"testing.testpb.v1.TestService\",\n\tHandlerType: (*TestServiceServer)(nil),\n\tMethods: []grpc.MethodDesc{\n\t\t{\n\t\t\tMethodName: \"PingEmpty\",\n\t\t\tHandler:    _TestService_PingEmpty_Handler,\n\t\t},\n\t\t{\n\t\t\tMethodName: \"Ping\",\n\t\t\tHandler:    _TestService_Ping_Handler,\n\t\t},\n\t\t{\n\t\t\tMethodName: \"PingError\",\n\t\t\tHandler:    _TestService_PingError_Handler,\n\t\t},\n\t},\n\tStreams: []grpc.StreamDesc{\n\t\t{\n\t\t\tStreamName:    \"PingList\",\n\t\t\tHandler:       _TestService_PingList_Handler,\n\t\t\tServerStreams: true,\n\t\t},\n\t\t{\n\t\t\tStreamName:    \"PingStream\",\n\t\t\tHandler:       _TestService_PingStream_Handler,\n\t\t\tServerStreams: true,\n\t\t\tClientStreams: true,\n\t\t},\n\t\t{\n\t\t\tStreamName:    \"PingClientStream\",\n\t\t\tHandler:       _TestService_PingClientStream_Handler,\n\t\t\tClientStreams: true,\n\t\t},\n\t},\n\tMetadata: \"test.proto\",\n}\n"
  },
  {
    "path": "testing/testpb/v1/test.proto",
    "content": "syntax = \"proto3\";\n\npackage testing.testpb.v1;\n\noption go_package = \".;testpb\";\n\nmessage PingEmptyRequest {}\n\nmessage PingEmptyResponse {}\n\nmessage PingRequest {\n  string value = 1;\n  int32 sleep_time_ms = 2;\n  uint32 error_code_returned = 3;\n}\n\nmessage PingResponse {\n  string value = 1;\n  int32 counter = 2;\n}\n\nmessage PingErrorRequest {\n  string value = 1;\n  int32 sleep_time_ms = 2;\n  uint32 error_code_returned = 3;\n}\n\nmessage PingErrorResponse {\n  string value = 1;\n  int32 counter = 2;\n}\n\nmessage PingListRequest {\n  string value = 1;\n  int32 sleep_time_ms = 2;\n  uint32 error_code_returned = 3;\n}\n\nmessage PingListResponse {\n  string value = 1;\n  int32 counter = 2;\n}\n\nmessage PingStreamRequest {\n  string value = 1;\n  int32 sleep_time_ms = 2;\n  uint32 error_code_returned = 3;\n}\n\nmessage PingStreamResponse {\n  string value = 1;\n  int32 counter = 2;\n}\n\nmessage PingClientStreamRequest {\n  string value = 1;\n  int32 sleep_time_ms = 2;\n  uint32 error_code_returned = 3;\n}\n\nmessage PingClientStreamResponse {\n  int32 counter = 1;\n}\n\nservice TestService {\n  rpc PingEmpty(PingEmptyRequest) returns (PingEmptyResponse) {}\n\n  rpc Ping(PingRequest) returns (PingResponse) {}\n\n  rpc PingError(PingErrorRequest) returns (PingErrorResponse) {}\n\n  rpc PingList(PingListRequest) returns (stream PingListResponse) {}\n\n  rpc PingStream(stream PingStreamRequest) returns (stream PingStreamResponse) {}\n\n  rpc PingClientStream(stream PingClientStreamRequest) returns (PingClientStreamResponse) {}\n}\n"
  },
  {
    "path": "testing/testvalidate/testvalidate.buf.gen.yaml",
    "content": "version: v2\nplugins:\n  - remote: buf.build/protocolbuffers/go:v1.36.6\n    out: .\n    opt: paths=source_relative\n  - remote: buf.build/grpc/go:v1.5.1\n    out: .\n    opt:\n      - paths=source_relative\n      - require_unimplemented_servers=false\n"
  },
  {
    "path": "testing/testvalidate/v1/test_validate.pb.go",
    "content": "// Code generated by protoc-gen-go. DO NOT EDIT.\n// versions:\n// \tprotoc-gen-go v1.36.6\n// \tprotoc        (unknown)\n// source: testing/testvalidate/v1/test_validate.proto\n\npackage testvalidatev1\n\nimport (\n\treflect \"reflect\"\n\tsync \"sync\"\n\tunsafe \"unsafe\"\n\n\t_ \"buf.build/gen/go/bufbuild/protovalidate/protocolbuffers/go/buf/validate\"\n\tprotoreflect \"google.golang.org/protobuf/reflect/protoreflect\"\n\tprotoimpl \"google.golang.org/protobuf/runtime/protoimpl\"\n)\n\nconst (\n\t// Verify that this generated code is sufficiently up-to-date.\n\t_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)\n\t// Verify that runtime/protoimpl is sufficiently up-to-date.\n\t_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)\n)\n\ntype SendRequest struct {\n\tstate         protoimpl.MessageState `protogen:\"open.v1\"`\n\tMessage       string                 `protobuf:\"bytes,1,opt,name=message,proto3\" json:\"message,omitempty\"`\n\tunknownFields protoimpl.UnknownFields\n\tsizeCache     protoimpl.SizeCache\n}\n\nfunc (x *SendRequest) Reset() {\n\t*x = SendRequest{}\n\tmi := &file_testing_testvalidate_v1_test_validate_proto_msgTypes[0]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *SendRequest) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*SendRequest) ProtoMessage() {}\n\nfunc (x *SendRequest) ProtoReflect() protoreflect.Message {\n\tmi := &file_testing_testvalidate_v1_test_validate_proto_msgTypes[0]\n\tif x != nil {\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tif ms.LoadMessageInfo() == nil {\n\t\t\tms.StoreMessageInfo(mi)\n\t\t}\n\t\treturn ms\n\t}\n\treturn mi.MessageOf(x)\n}\n\n// Deprecated: Use SendRequest.ProtoReflect.Descriptor instead.\nfunc (*SendRequest) Descriptor() ([]byte, []int) {\n\treturn file_testing_testvalidate_v1_test_validate_proto_rawDescGZIP(), []int{0}\n}\n\nfunc (x *SendRequest) GetMessage() string {\n\tif x != nil {\n\t\treturn x.Message\n\t}\n\treturn \"\"\n}\n\ntype SendResponse struct {\n\tstate         protoimpl.MessageState `protogen:\"open.v1\"`\n\tunknownFields protoimpl.UnknownFields\n\tsizeCache     protoimpl.SizeCache\n}\n\nfunc (x *SendResponse) Reset() {\n\t*x = SendResponse{}\n\tmi := &file_testing_testvalidate_v1_test_validate_proto_msgTypes[1]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *SendResponse) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*SendResponse) ProtoMessage() {}\n\nfunc (x *SendResponse) ProtoReflect() protoreflect.Message {\n\tmi := &file_testing_testvalidate_v1_test_validate_proto_msgTypes[1]\n\tif x != nil {\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tif ms.LoadMessageInfo() == nil {\n\t\t\tms.StoreMessageInfo(mi)\n\t\t}\n\t\treturn ms\n\t}\n\treturn mi.MessageOf(x)\n}\n\n// Deprecated: Use SendResponse.ProtoReflect.Descriptor instead.\nfunc (*SendResponse) Descriptor() ([]byte, []int) {\n\treturn file_testing_testvalidate_v1_test_validate_proto_rawDescGZIP(), []int{1}\n}\n\ntype SendStreamRequest struct {\n\tstate         protoimpl.MessageState `protogen:\"open.v1\"`\n\tMessage       string                 `protobuf:\"bytes,1,opt,name=message,proto3\" json:\"message,omitempty\"`\n\tunknownFields protoimpl.UnknownFields\n\tsizeCache     protoimpl.SizeCache\n}\n\nfunc (x *SendStreamRequest) Reset() {\n\t*x = SendStreamRequest{}\n\tmi := &file_testing_testvalidate_v1_test_validate_proto_msgTypes[2]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *SendStreamRequest) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*SendStreamRequest) ProtoMessage() {}\n\nfunc (x *SendStreamRequest) ProtoReflect() protoreflect.Message {\n\tmi := &file_testing_testvalidate_v1_test_validate_proto_msgTypes[2]\n\tif x != nil {\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tif ms.LoadMessageInfo() == nil {\n\t\t\tms.StoreMessageInfo(mi)\n\t\t}\n\t\treturn ms\n\t}\n\treturn mi.MessageOf(x)\n}\n\n// Deprecated: Use SendStreamRequest.ProtoReflect.Descriptor instead.\nfunc (*SendStreamRequest) Descriptor() ([]byte, []int) {\n\treturn file_testing_testvalidate_v1_test_validate_proto_rawDescGZIP(), []int{2}\n}\n\nfunc (x *SendStreamRequest) GetMessage() string {\n\tif x != nil {\n\t\treturn x.Message\n\t}\n\treturn \"\"\n}\n\ntype SendStreamResponse struct {\n\tstate         protoimpl.MessageState `protogen:\"open.v1\"`\n\tunknownFields protoimpl.UnknownFields\n\tsizeCache     protoimpl.SizeCache\n}\n\nfunc (x *SendStreamResponse) Reset() {\n\t*x = SendStreamResponse{}\n\tmi := &file_testing_testvalidate_v1_test_validate_proto_msgTypes[3]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *SendStreamResponse) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*SendStreamResponse) ProtoMessage() {}\n\nfunc (x *SendStreamResponse) ProtoReflect() protoreflect.Message {\n\tmi := &file_testing_testvalidate_v1_test_validate_proto_msgTypes[3]\n\tif x != nil {\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tif ms.LoadMessageInfo() == nil {\n\t\t\tms.StoreMessageInfo(mi)\n\t\t}\n\t\treturn ms\n\t}\n\treturn mi.MessageOf(x)\n}\n\n// Deprecated: Use SendStreamResponse.ProtoReflect.Descriptor instead.\nfunc (*SendStreamResponse) Descriptor() ([]byte, []int) {\n\treturn file_testing_testvalidate_v1_test_validate_proto_rawDescGZIP(), []int{3}\n}\n\nvar File_testing_testvalidate_v1_test_validate_proto protoreflect.FileDescriptor\n\nconst file_testing_testvalidate_v1_test_validate_proto_rawDesc = \"\" +\n\t\"\\n\" +\n\t\"+testing/testvalidate/v1/test_validate.proto\\x12\\x17testing.testvalidate.v1\\x1a\\x1bbuf/validate/validate.proto\\\"0\\n\" +\n\t\"\\vSendRequest\\x12!\\n\" +\n\t\"\\amessage\\x18\\x01 \\x01(\\tB\\a\\xbaH\\x04r\\x02`\\x01R\\amessage\\\"\\x0e\\n\" +\n\t\"\\fSendResponse\\\"6\\n\" +\n\t\"\\x11SendStreamRequest\\x12!\\n\" +\n\t\"\\amessage\\x18\\x01 \\x01(\\tB\\a\\xbaH\\x04r\\x02`\\x01R\\amessage\\\"\\x14\\n\" +\n\t\"\\x12SendStreamResponse2\\xd7\\x01\\n\" +\n\t\"\\x13TestValidateService\\x12U\\n\" +\n\t\"\\x04Send\\x12$.testing.testvalidate.v1.SendRequest\\x1a%.testing.testvalidate.v1.SendResponse\\\"\\x00\\x12i\\n\" +\n\t\"\\n\" +\n\t\"SendStream\\x12*.testing.testvalidate.v1.SendStreamRequest\\x1a+.testing.testvalidate.v1.SendStreamResponse\\\"\\x000\\x01BUZSgithub.com/grpc-ecosystem/go-grpc-middleware/testing/testvalidate/v1;testvalidatev1b\\x06proto3\"\n\nvar (\n\tfile_testing_testvalidate_v1_test_validate_proto_rawDescOnce sync.Once\n\tfile_testing_testvalidate_v1_test_validate_proto_rawDescData []byte\n)\n\nfunc file_testing_testvalidate_v1_test_validate_proto_rawDescGZIP() []byte {\n\tfile_testing_testvalidate_v1_test_validate_proto_rawDescOnce.Do(func() {\n\t\tfile_testing_testvalidate_v1_test_validate_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_testing_testvalidate_v1_test_validate_proto_rawDesc), len(file_testing_testvalidate_v1_test_validate_proto_rawDesc)))\n\t})\n\treturn file_testing_testvalidate_v1_test_validate_proto_rawDescData\n}\n\nvar file_testing_testvalidate_v1_test_validate_proto_msgTypes = make([]protoimpl.MessageInfo, 4)\nvar file_testing_testvalidate_v1_test_validate_proto_goTypes = []any{\n\t(*SendRequest)(nil),        // 0: testing.testvalidate.v1.SendRequest\n\t(*SendResponse)(nil),       // 1: testing.testvalidate.v1.SendResponse\n\t(*SendStreamRequest)(nil),  // 2: testing.testvalidate.v1.SendStreamRequest\n\t(*SendStreamResponse)(nil), // 3: testing.testvalidate.v1.SendStreamResponse\n}\nvar file_testing_testvalidate_v1_test_validate_proto_depIdxs = []int32{\n\t0, // 0: testing.testvalidate.v1.TestValidateService.Send:input_type -> testing.testvalidate.v1.SendRequest\n\t2, // 1: testing.testvalidate.v1.TestValidateService.SendStream:input_type -> testing.testvalidate.v1.SendStreamRequest\n\t1, // 2: testing.testvalidate.v1.TestValidateService.Send:output_type -> testing.testvalidate.v1.SendResponse\n\t3, // 3: testing.testvalidate.v1.TestValidateService.SendStream:output_type -> testing.testvalidate.v1.SendStreamResponse\n\t2, // [2:4] is the sub-list for method output_type\n\t0, // [0:2] is the sub-list for method input_type\n\t0, // [0:0] is the sub-list for extension type_name\n\t0, // [0:0] is the sub-list for extension extendee\n\t0, // [0:0] is the sub-list for field type_name\n}\n\nfunc init() { file_testing_testvalidate_v1_test_validate_proto_init() }\nfunc file_testing_testvalidate_v1_test_validate_proto_init() {\n\tif File_testing_testvalidate_v1_test_validate_proto != nil {\n\t\treturn\n\t}\n\ttype x struct{}\n\tout := protoimpl.TypeBuilder{\n\t\tFile: protoimpl.DescBuilder{\n\t\t\tGoPackagePath: reflect.TypeOf(x{}).PkgPath(),\n\t\t\tRawDescriptor: unsafe.Slice(unsafe.StringData(file_testing_testvalidate_v1_test_validate_proto_rawDesc), len(file_testing_testvalidate_v1_test_validate_proto_rawDesc)),\n\t\t\tNumEnums:      0,\n\t\t\tNumMessages:   4,\n\t\t\tNumExtensions: 0,\n\t\t\tNumServices:   1,\n\t\t},\n\t\tGoTypes:           file_testing_testvalidate_v1_test_validate_proto_goTypes,\n\t\tDependencyIndexes: file_testing_testvalidate_v1_test_validate_proto_depIdxs,\n\t\tMessageInfos:      file_testing_testvalidate_v1_test_validate_proto_msgTypes,\n\t}.Build()\n\tFile_testing_testvalidate_v1_test_validate_proto = out.File\n\tfile_testing_testvalidate_v1_test_validate_proto_goTypes = nil\n\tfile_testing_testvalidate_v1_test_validate_proto_depIdxs = nil\n}\n"
  },
  {
    "path": "testing/testvalidate/v1/test_validate.proto",
    "content": "syntax = \"proto3\";\n\npackage testing.testvalidate.v1;\n\nimport \"buf/validate/validate.proto\";\n\noption go_package = \"github.com/grpc-ecosystem/go-grpc-middleware/testing/testvalidate/v1;testvalidatev1\";\n\nservice TestValidateService {\n  rpc Send(SendRequest) returns (SendResponse) {}\n  rpc SendStream(SendStreamRequest) returns (stream SendStreamResponse) {}\n}\n\nmessage SendRequest {\n  string message = 1 [(buf.validate.field).string.email = true];\n}\n\nmessage SendResponse {}\n\nmessage SendStreamRequest {\n  string message = 1 [(buf.validate.field).string.email = true];\n}\n\nmessage SendStreamResponse {}\n"
  },
  {
    "path": "testing/testvalidate/v1/test_validate_grpc.pb.go",
    "content": "// Code generated by protoc-gen-go-grpc. DO NOT EDIT.\n// versions:\n// - protoc-gen-go-grpc v1.5.1\n// - protoc             (unknown)\n// source: testing/testvalidate/v1/test_validate.proto\n\npackage testvalidatev1\n\nimport (\n\tcontext \"context\"\n\n\tgrpc \"google.golang.org/grpc\"\n\tcodes \"google.golang.org/grpc/codes\"\n\tstatus \"google.golang.org/grpc/status\"\n)\n\n// This is a compile-time assertion to ensure that this generated file\n// is compatible with the grpc package it is being compiled against.\n// Requires gRPC-Go v1.64.0 or later.\nconst _ = grpc.SupportPackageIsVersion9\n\nconst (\n\tTestValidateService_Send_FullMethodName       = \"/testing.testvalidate.v1.TestValidateService/Send\"\n\tTestValidateService_SendStream_FullMethodName = \"/testing.testvalidate.v1.TestValidateService/SendStream\"\n)\n\n// TestValidateServiceClient is the client API for TestValidateService service.\n//\n// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream.\ntype TestValidateServiceClient interface {\n\tSend(ctx context.Context, in *SendRequest, opts ...grpc.CallOption) (*SendResponse, error)\n\tSendStream(ctx context.Context, in *SendStreamRequest, opts ...grpc.CallOption) (grpc.ServerStreamingClient[SendStreamResponse], error)\n}\n\ntype testValidateServiceClient struct {\n\tcc grpc.ClientConnInterface\n}\n\nfunc NewTestValidateServiceClient(cc grpc.ClientConnInterface) TestValidateServiceClient {\n\treturn &testValidateServiceClient{cc}\n}\n\nfunc (c *testValidateServiceClient) Send(ctx context.Context, in *SendRequest, opts ...grpc.CallOption) (*SendResponse, error) {\n\tcOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)\n\tout := new(SendResponse)\n\terr := c.cc.Invoke(ctx, TestValidateService_Send_FullMethodName, in, out, cOpts...)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn out, nil\n}\n\nfunc (c *testValidateServiceClient) SendStream(ctx context.Context, in *SendStreamRequest, opts ...grpc.CallOption) (grpc.ServerStreamingClient[SendStreamResponse], error) {\n\tcOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)\n\tstream, err := c.cc.NewStream(ctx, &TestValidateService_ServiceDesc.Streams[0], TestValidateService_SendStream_FullMethodName, cOpts...)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tx := &grpc.GenericClientStream[SendStreamRequest, SendStreamResponse]{ClientStream: stream}\n\tif err := x.ClientStream.SendMsg(in); err != nil {\n\t\treturn nil, err\n\t}\n\tif err := x.ClientStream.CloseSend(); err != nil {\n\t\treturn nil, err\n\t}\n\treturn x, nil\n}\n\n// This type alias is provided for backwards compatibility with existing code that references the prior non-generic stream type by name.\ntype TestValidateService_SendStreamClient = grpc.ServerStreamingClient[SendStreamResponse]\n\n// TestValidateServiceServer is the server API for TestValidateService service.\n// All implementations should embed UnimplementedTestValidateServiceServer\n// for forward compatibility.\ntype TestValidateServiceServer interface {\n\tSend(context.Context, *SendRequest) (*SendResponse, error)\n\tSendStream(*SendStreamRequest, grpc.ServerStreamingServer[SendStreamResponse]) error\n}\n\n// UnimplementedTestValidateServiceServer should be embedded to have\n// forward compatible implementations.\n//\n// NOTE: this should be embedded by value instead of pointer to avoid a nil\n// pointer dereference when methods are called.\ntype UnimplementedTestValidateServiceServer struct{}\n\nfunc (UnimplementedTestValidateServiceServer) Send(context.Context, *SendRequest) (*SendResponse, error) {\n\treturn nil, status.Errorf(codes.Unimplemented, \"method Send not implemented\")\n}\nfunc (UnimplementedTestValidateServiceServer) SendStream(*SendStreamRequest, grpc.ServerStreamingServer[SendStreamResponse]) error {\n\treturn status.Errorf(codes.Unimplemented, \"method SendStream not implemented\")\n}\nfunc (UnimplementedTestValidateServiceServer) testEmbeddedByValue() {}\n\n// UnsafeTestValidateServiceServer may be embedded to opt out of forward compatibility for this service.\n// Use of this interface is not recommended, as added methods to TestValidateServiceServer will\n// result in compilation errors.\ntype UnsafeTestValidateServiceServer interface {\n\tmustEmbedUnimplementedTestValidateServiceServer()\n}\n\nfunc RegisterTestValidateServiceServer(s grpc.ServiceRegistrar, srv TestValidateServiceServer) {\n\t// If the following call pancis, it indicates UnimplementedTestValidateServiceServer was\n\t// embedded by pointer and is nil.  This will cause panics if an\n\t// unimplemented method is ever invoked, so we test this at initialization\n\t// time to prevent it from happening at runtime later due to I/O.\n\tif t, ok := srv.(interface{ testEmbeddedByValue() }); ok {\n\t\tt.testEmbeddedByValue()\n\t}\n\ts.RegisterService(&TestValidateService_ServiceDesc, srv)\n}\n\nfunc _TestValidateService_Send_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {\n\tin := new(SendRequest)\n\tif err := dec(in); err != nil {\n\t\treturn nil, err\n\t}\n\tif interceptor == nil {\n\t\treturn srv.(TestValidateServiceServer).Send(ctx, in)\n\t}\n\tinfo := &grpc.UnaryServerInfo{\n\t\tServer:     srv,\n\t\tFullMethod: TestValidateService_Send_FullMethodName,\n\t}\n\thandler := func(ctx context.Context, req interface{}) (interface{}, error) {\n\t\treturn srv.(TestValidateServiceServer).Send(ctx, req.(*SendRequest))\n\t}\n\treturn interceptor(ctx, in, info, handler)\n}\n\nfunc _TestValidateService_SendStream_Handler(srv interface{}, stream grpc.ServerStream) error {\n\tm := new(SendStreamRequest)\n\tif err := stream.RecvMsg(m); err != nil {\n\t\treturn err\n\t}\n\treturn srv.(TestValidateServiceServer).SendStream(m, &grpc.GenericServerStream[SendStreamRequest, SendStreamResponse]{ServerStream: stream})\n}\n\n// This type alias is provided for backwards compatibility with existing code that references the prior non-generic stream type by name.\ntype TestValidateService_SendStreamServer = grpc.ServerStreamingServer[SendStreamResponse]\n\n// TestValidateService_ServiceDesc is the grpc.ServiceDesc for TestValidateService service.\n// It's only intended for direct use with grpc.RegisterService,\n// and not to be introspected or modified (even as a copy)\nvar TestValidateService_ServiceDesc = grpc.ServiceDesc{\n\tServiceName: \"testing.testvalidate.v1.TestValidateService\",\n\tHandlerType: (*TestValidateServiceServer)(nil),\n\tMethods: []grpc.MethodDesc{\n\t\t{\n\t\t\tMethodName: \"Send\",\n\t\t\tHandler:    _TestValidateService_Send_Handler,\n\t\t},\n\t},\n\tStreams: []grpc.StreamDesc{\n\t\t{\n\t\t\tStreamName:    \"SendStream\",\n\t\t\tHandler:       _TestValidateService_SendStream_Handler,\n\t\t\tServerStreams: true,\n\t\t},\n\t},\n\tMetadata: \"testing/testvalidate/v1/test_validate.proto\",\n}\n"
  },
  {
    "path": "testing/testvalidate/validateservice.go",
    "content": "// Copyright (c) The go-grpc-middleware Authors.\n// Licensed under the Apache License 2.0.\n\npackage testvalidate\n\nimport (\n\t\"context\"\n\n\ttestvalidatev1 \"github.com/grpc-ecosystem/go-grpc-middleware/v2/testing/testvalidate/v1\"\n)\n\ntype TestValidateService struct {\n\ttestvalidatev1.UnimplementedTestValidateServiceServer\n}\n\nfunc (v *TestValidateService) Send(\n\t_ context.Context,\n\t_ *testvalidatev1.SendRequest,\n) (*testvalidatev1.SendResponse, error) {\n\treturn &testvalidatev1.SendResponse{}, nil\n}\n\nfunc (v *TestValidateService) SendStream(\n\t_ *testvalidatev1.SendStreamRequest,\n\tstream testvalidatev1.TestValidateService_SendStreamServer,\n) error {\n\tfor i := 0; i < 10; i++ {\n\t\tif err := stream.Send(&testvalidatev1.SendStreamResponse{}); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\n\treturn nil\n}\n\n// Unary requests for unit testing\nvar (\n\tBadUnaryRequest = &testvalidatev1.SendRequest{\n\t\tMessage: \"%any\",\n\t}\n\n\tGoodUnaryRequest = &testvalidatev1.SendRequest{\n\t\tMessage: \"good@example.com\",\n\t}\n)\n\n// Stream requests for unit testing\nvar (\n\tBadStreamRequest = &testvalidatev1.SendStreamRequest{\n\t\tMessage: \"%any\",\n\t}\n\n\tGoodStreamRequest = &testvalidatev1.SendStreamRequest{\n\t\tMessage: \"good@example.com\",\n\t}\n)\n"
  },
  {
    "path": "util/backoffutils/backoff.go",
    "content": "// Copyright (c) The go-grpc-middleware Authors.\n// Licensed under the Apache License 2.0.\n\n// Package backoffutils implements common backoff features.\npackage backoffutils\n\nimport (\n\t\"math/rand\"\n\t\"time\"\n)\n\n// JitterUp adds random jitter to the duration.\n//\n// This adds or subtracts time from the duration within a given jitter fraction.\n// For example for 10s and jitter 0.1, it will return a time within [9s, 11s])\nfunc JitterUp(duration time.Duration, jitter float64) time.Duration {\n\tmultiplier := jitter * (rand.Float64()*2 - 1)\n\treturn time.Duration(float64(duration) * (1 + multiplier))\n}\n\n// ExponentBase2 computes 2^(a-1) where a >= 1. If a is 0, the result is 0.\nfunc ExponentBase2(a uint) uint {\n\treturn (1 << a) >> 1\n}\n"
  },
  {
    "path": "util/backoffutils/backoff_test.go",
    "content": "// Copyright (c) The go-grpc-middleware Authors.\n// Licensed under the Apache License 2.0.\n\npackage backoffutils_test\n\nimport (\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/grpc-ecosystem/go-grpc-middleware/v2/util/backoffutils\"\n\t\"github.com/stretchr/testify/assert\"\n)\n\n// scale duration by a factor\nfunc scaleDuration(d time.Duration, factor float64) time.Duration {\n\treturn time.Duration(float64(d) * factor)\n}\n\nfunc TestJitterUp(t *testing.T) {\n\t// arguments to jitterup\n\tduration := 10 * time.Second\n\tvariance := 0.10\n\n\t// bound to check\n\tmax := 11000 * time.Millisecond\n\tmin := 9000 * time.Millisecond\n\thigh := scaleDuration(max, 0.98)\n\tlow := scaleDuration(min, 1.02)\n\n\thighCount := 0\n\tlowCount := 0\n\n\tfor i := 0; i < 1000; i++ {\n\t\tout := backoffutils.JitterUp(duration, variance)\n\t\tassert.LessOrEqual(t, out, max, \"value %s must be <= %s\", out, max)\n\t\tassert.GreaterOrEqual(t, out, min, \"value %s must be >= %s\", out, min)\n\n\t\tif out > high {\n\t\t\thighCount++\n\t\t}\n\t\tif out < low {\n\t\t\tlowCount++\n\t\t}\n\t}\n\n\tassert.NotEqual(t, 0, highCount, \"at least one sample should reach to >%s\", high)\n\tassert.NotEqual(t, 0, lowCount, \"at least one sample should to <%s\", low)\n}\n"
  },
  {
    "path": "versions.yaml",
    "content": "# Versions yaml in the format supported by multimod tool (https://github.com/open-telemetry/opentelemetry-go-build-tools/tree/7c66e93ea95406b9f8bc0174809acccec745057f/multimod).\n# While we don't use multimod yet, we keep versions grouped and listed to not get lost with manual releases.\n# We group versions, so it's easier to maintain and use.\nmodule-sets:\n  core:\n    version: v2.0.0\n    modules:\n      - github.com/grpc-ecosystem/go-grpc-middleware/v2\n  v1-providers:\n    version: v1.0.0\n    modules:\n      - github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus\n"
  },
  {
    "path": "wrappers.go",
    "content": "// Copyright (c) The go-grpc-middleware Authors.\n// Licensed under the Apache License 2.0.\n\npackage middleware\n\nimport (\n\t\"context\"\n\n\t\"google.golang.org/grpc\"\n)\n\n// WrappedServerStream is a thin wrapper around grpc.ServerStream that allows modifying context.\ntype WrappedServerStream struct {\n\tgrpc.ServerStream\n\t// WrappedContext is the wrapper's own Context. You can assign it.\n\tWrappedContext context.Context\n}\n\n// Context returns the wrapper's WrappedContext, overwriting the nested grpc.ServerStream.Context()\nfunc (w *WrappedServerStream) Context() context.Context {\n\treturn w.WrappedContext\n}\n\n// WrapServerStream returns a ServerStream that has the ability to overwrite context.\nfunc WrapServerStream(stream grpc.ServerStream) *WrappedServerStream {\n\tif existing, ok := stream.(*WrappedServerStream); ok {\n\t\treturn existing\n\t}\n\treturn &WrappedServerStream{ServerStream: stream, WrappedContext: stream.Context()}\n}\n"
  },
  {
    "path": "wrappers_test.go",
    "content": "// Copyright (c) The go-grpc-middleware Authors.\n// Licensed under the Apache License 2.0.\n\npackage middleware\n\nimport (\n\t\"context\"\n\t\"testing\"\n\n\t\"github.com/stretchr/testify/assert\"\n\t\"google.golang.org/grpc\"\n\t\"google.golang.org/grpc/codes\"\n\t\"google.golang.org/grpc/status\"\n)\n\ntype (\n\tsomeKey struct{}\n\tother   struct{}\n)\n\nfunc TestWrapServerStream(t *testing.T) {\n\tctx := context.WithValue(context.TODO(), someKey{}, 1)\n\tfake := &fakeServerStream{ctx: ctx}\n\twrapped := WrapServerStream(fake)\n\tassert.NotNil(t, wrapped.Context().Value(someKey{}), \"values from fake must propagate to wrapper\")\n\twrapped.WrappedContext = context.WithValue(wrapped.Context(), other{}, 2)\n\tassert.NotNil(t, wrapped.Context().Value(other{}), \"values from wrapper must be set\")\n}\n\ntype fakeServerStream struct {\n\tgrpc.ServerStream\n\tctx         context.Context\n\trecvMessage any\n\tsentMessage any\n}\n\nfunc (f *fakeServerStream) Context() context.Context {\n\treturn f.ctx\n}\n\nfunc (f *fakeServerStream) SendMsg(m any) error {\n\tif f.sentMessage != nil {\n\t\treturn status.Error(codes.AlreadyExists, \"fakeServerStream only takes one message, sorry\")\n\t}\n\tf.sentMessage = m\n\treturn nil\n}\n\nfunc (f *fakeServerStream) RecvMsg(m any) error {\n\tif f.recvMessage == nil {\n\t\treturn status.Error(codes.NotFound, \"fakeServerStream has no message, sorry\")\n\t}\n\treturn nil\n}\n"
  }
]