Author: Adam <git@apiote.xyz>
initial
argon.go | 111 ++++++++ go.mod | 9 go.sum | 397 +++++++++++++++++++++++++++++ main.go | 29 ++ programs/amuse.adoc | 82 ++++++ programs/asgard.adoc | 78 +++++ programs/bagend.adoc | 50 +++ programs/go-dirty.adoc | 1 programs/gonk.adoc | 49 +++ programs/gott.adoc | 85 ++++++ programs/gott_v2.adoc | 93 ++++++ programs/index.dirty | 90 ++++++ router.go | 399 ++++++++++++++++++++++++++++++ static/favicon/browserconfig.xml | 9 static/favicon/safari-pinned-tab.svg | 22 + static/favicon/site.webmanifest | 18 + static/me.asc | 13 static/style.css | 196 ++++++++++++++ templates/403.html | 12 templates/404.html | 13 templates/501.html | 14 + templates/aside.html | 20 + templates/head.html | 18 + templates/head_program.html | 19 + templates/header.html | 5 templates/index.html | 23 + templates/nav.html | 10 templates/pgp.html | 14 + templates/program.html | 18 + templates/programs.html | 19 + templates/s.html | 21 + templates/s201.html | 13 templates/short.html | 15 +
diff --git a/argon.go b/argon.go new file mode 100644 index 0000000000000000000000000000000000000000..90021a3d19acd357530a82fa78e7afdc0ec31b38 --- /dev/null +++ b/argon.go @@ -0,0 +1,111 @@ +// MIT (c) alexedwards [https://gist.github.com/alexedwards/34277fae0f48abe36822b375f0f6a621] +// move to https://github.com/alexedwards/argon2id instead of vendoring + +package main + +import ( + "crypto/rand" + "crypto/subtle" + "encoding/base64" + "errors" + "fmt" + "strings" + + "golang.org/x/crypto/argon2" +) + +var ( + ErrInvalidHash = errors.New("the encoded hash is not in the correct format") + ErrIncompatibleVersion = errors.New("incompatible version of argon2") +) + +type params struct { + memory uint32 + iterations uint32 + parallelism uint8 + saltLength uint32 + keyLength uint32 +} + +func GenerateFromPassword(password string) (encodedHash string, err error) { + p := ¶ms{ + memory: 64 * 1024, + iterations: 3, + parallelism: 2, + saltLength: 16, + keyLength: 32, + } + salt, err := generateRandomBytes(p.saltLength) + if err != nil { + return "", err + } + + hash := argon2.IDKey([]byte(password), salt, p.iterations, p.memory, p.parallelism, p.keyLength) + + b64Salt := base64.RawStdEncoding.EncodeToString(salt) + b64Hash := base64.RawStdEncoding.EncodeToString(hash) + + encodedHash = fmt.Sprintf("$argon2id$v=%d$m=%d,t=%d,p=%d$%s$%s", argon2.Version, p.memory, p.iterations, p.parallelism, b64Salt, b64Hash) + + return encodedHash, nil +} + +func generateRandomBytes(n uint32) ([]byte, error) { + b := make([]byte, n) + _, err := rand.Read(b) + if err != nil { + return nil, err + } + + return b, nil +} + +func ComparePasswordAndHash(password, encodedHash string) (match bool, err error) { + p, salt, hash, err := decodeHash(encodedHash) + if err != nil { + return false, err + } + + otherHash := argon2.IDKey([]byte(password), salt, p.iterations, p.memory, p.parallelism, p.keyLength) + + if subtle.ConstantTimeCompare(hash, otherHash) == 1 { + return true, nil + } + return false, nil +} + +func decodeHash(encodedHash string) (p *params, salt, hash []byte, err error) { + vals := strings.Split(encodedHash, "$") + if len(vals) != 6 { + return nil, nil, nil, ErrInvalidHash + } + + var version int + _, err = fmt.Sscanf(vals[2], "v=%d", &version) + if err != nil { + return nil, nil, nil, err + } + if version != argon2.Version { + return nil, nil, nil, ErrIncompatibleVersion + } + + p = ¶ms{} + _, err = fmt.Sscanf(vals[3], "m=%d,t=%d,p=%d", &p.memory, &p.iterations, &p.parallelism) + if err != nil { + return nil, nil, nil, err + } + + salt, err = base64.RawStdEncoding.DecodeString(vals[4]) + if err != nil { + return nil, nil, nil, err + } + p.saltLength = uint32(len(salt)) + + hash, err = base64.RawStdEncoding.DecodeString(vals[5]) + if err != nil { + return nil, nil, nil, err + } + p.keyLength = uint32(len(hash)) + + return p, salt, hash, nil +} diff --git a/go.mod b/go.mod new file mode 100644 index 0000000000000000000000000000000000000000..f8fa0a34ce07c8eebe2486d32cde0438f0abf347 --- /dev/null +++ b/go.mod @@ -0,0 +1,9 @@ +module notabug.org/apiote/website + +go 1.15 + +require ( + apiote.xyz/p/go-dirty v0.0.0-20211218161334-e486e7b5cf43 + github.com/bytesparadise/libasciidoc v0.6.0 + golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad +) diff --git a/go.sum b/go.sum new file mode 100644 index 0000000000000000000000000000000000000000..9e0c6ddef295256d510e581b273252e655de242f --- /dev/null +++ b/go.sum @@ -0,0 +1,397 @@ +apiote.xyz/p/go-dirty v0.0.0-20211218161334-e486e7b5cf43 h1:C6YDhXc8Wo1ZrhxeJB5BzoYRI3plju2tg0ShTvdEaTQ= +apiote.xyz/p/go-dirty v0.0.0-20211218161334-e486e7b5cf43/go.mod h1:8QnoYcdnf+1AmRhC7GBUKuCl/wRpfI3Bd58JqDbJNtw= +cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= +cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU= +cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= +cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc= +cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0= +cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= +cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= +cloud.google.com/go/firestore v1.1.0/go.mod h1:ulACoGHTpvq5r8rxGJ4ddJZBZqakUQqClKRT5SZwBmk= +cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= +cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw= +dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= +github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= +github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= +github.com/alecthomas/assert v0.0.0-20170929043011-405dbfeb8e38 h1:smF2tmSOzy2Mm+0dGI2AIUHY+w0BUc+4tn40djz7+6U= +github.com/alecthomas/assert v0.0.0-20170929043011-405dbfeb8e38/go.mod h1:r7bzyVFMNntcxPZXK3/+KdruV1H5KSlyVY0gc+NgInI= +github.com/alecthomas/chroma v0.7.1 h1:G1i02OhUbRi2nJxcNkwJaY/J1gHXj9tt72qN6ZouLFQ= +github.com/alecthomas/chroma v0.7.1/go.mod h1:gHw09mkX1Qp80JlYbmN9L3+4R5o6DJJ3GRShh+AICNc= +github.com/alecthomas/colour v0.0.0-20160524082231-60882d9e2721 h1:JHZL0hZKJ1VENNfmXvHbgYlbUOvpzYzvy2aZU5gXVeo= +github.com/alecthomas/colour v0.0.0-20160524082231-60882d9e2721/go.mod h1:QO9JBoKquHd+jz9nshCh40fOfO+JzsoXy8qTHF68zU0= +github.com/alecthomas/kong v0.2.1-0.20190708041108-0548c6b1afae/go.mod h1:+inYUSluD+p4L8KdviBSgzcqEjUQOfC5fQDRFuc36lI= +github.com/alecthomas/repr v0.0.0-20180818092828-117648cd9897 h1:p9Sln00KOTlrYkxI1zYWl1QLnEqAqEARBEYa8FQnQcY= +github.com/alecthomas/repr v0.0.0-20180818092828-117648cd9897/go.mod h1:xTS7Pm1pD1mvyM075QCDSRqH6qRLXylzS24ZTpRiSzQ= +github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= +github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= +github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= +github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= +github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= +github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= +github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= +github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= +github.com/bketelsen/crypt v0.0.3-0.20200106085610-5cbc8cc4026c/go.mod h1:MKsuJmJgSg28kpZDP6UIiPt0e0Oz0kqKNGyRaWEPv84= +github.com/bytesparadise/libasciidoc v0.6.0 h1:VPYw0epZXIBpNloE9mT9bsTLa6Km/K6ZYXGpwhSjerk= +github.com/bytesparadise/libasciidoc v0.6.0/go.mod h1:ifAy8QVs1/TRhsqtx/ORiNrHk0NowHih9P5rP9nZI7U= +github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= +github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= +github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= +github.com/coreos/etcd v3.3.13+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= +github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= +github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= +github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= +github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= +github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= +github.com/danwakefield/fnmatch v0.0.0-20160403171240-cbb64ac3d964 h1:y5HC9v93H5EPKqaS1UYVg1uYah5Xf51mBfIoWehClUQ= +github.com/danwakefield/fnmatch v0.0.0-20160403171240-cbb64ac3d964/go.mod h1:Xd9hchkHSWYkEqJwUGisez3G1QY8Ryz0sdWrLPMGjLk= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= +github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no= +github.com/dlclark/regexp2 v1.1.6 h1:CqB4MjHw0MFCDj+PHHjiESmHX+N7t0tJzKvC6M97BRg= +github.com/dlclark/regexp2 v1.1.6/go.mod h1:2pZnwuY/m+8K6iRw6wQdMtk+rH5tNGR1i55kozfMjCc= +github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= +github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= +github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4= +github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= +github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= +github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= +github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= +github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= +github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= +github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= +github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= +github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= +github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= +github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= +github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= +github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= +github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= +github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= +github.com/golang/protobuf v1.4.2 h1:+Z5KGCizgyZCbGh1KZqA0fcLLkwbsjIzS4aV2v7wJX0= +github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= +github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= +github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= +github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.2 h1:X2ev0eStA3AbceY54o37/0PQ/UWqKEiiO2dKL5OPaFM= +github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= +github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= +github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= +github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= +github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= +github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= +github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= +github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= +github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= +github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= +github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= +github.com/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q= +github.com/hashicorp/consul/sdk v0.1.1/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8= +github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= +github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= +github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= +github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= +github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= +github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU= +github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU= +github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4= +github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90= +github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= +github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64= +github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ= +github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I= +github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc= +github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= +github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= +github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= +github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= +github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= +github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= +github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= +github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= +github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= +github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= +github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= +github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= +github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= +github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY= +github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= +github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= +github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= +github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc= +github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= +github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= +github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI= +github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS42BGNg= +github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY= +github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= +github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= +github.com/mna/pigeon v1.0.1-0.20200224192238-18953b277063 h1:V7s6vhIrNeOqocziAmRoVJh6gnPPx83ovlpT7Hf5shI= +github.com/mna/pigeon v1.0.1-0.20200224192238-18953b277063/go.mod h1:rkFeDZ0gc+YbnrXPw0q2RlI0QRuKBBPu67fgYIyGRNg= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/modocache/gover v0.0.0-20171022184752-b58185e213c5 h1:8Q0qkMVC/MmWkpIdlvZgcv2o2jrlF6zqVOh7W5YHdMA= +github.com/modocache/gover v0.0.0-20171022184752-b58185e213c5/go.mod h1:caMODM3PzxT8aQXRPkAt8xlV/e7d7w8GM5g0fa5F0D8= +github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= +github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs= +github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= +github.com/nxadm/tail v1.4.4 h1:DQuhQpB1tVlglWS2hLQ5OV6B5r8aGxSrPc5Qo6uTN78= +github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= +github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= +github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= +github.com/onsi/ginkgo v1.13.0 h1:M76yO2HkZASFjXL0HSoZJ1AYEmQxNJmY41Jx1zNUq1Y= +github.com/onsi/ginkgo v1.13.0/go.mod h1:+REjRxOmWfHCjfv9TTWB1jD1Frx4XydAD3zm1lskyM0= +github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= +github.com/onsi/gomega v1.10.1 h1:o0+MgICZLuZ7xjH7Vx6zS/zcu93/BEp1VwkIW1mEXCE= +github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= +github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= +github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= +github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= +github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= +github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso= +github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= +github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= +github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= +github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= +github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= +github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= +github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= +github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= +github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= +github.com/sclevine/agouti v3.0.0+incompatible/go.mod h1:b4WX9W9L1sfQKXeJf1mUTLZKJ48R1S7H23Ji7oFO5Bw= +github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= +github.com/sergi/go-diff v1.0.0 h1:Kpca3qRNrduNnOQeazBd0ysaKrUJiIuISHxogkT9RPQ= +github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= +github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= +github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= +github.com/sirupsen/logrus v1.7.0 h1:ShrD1U9pZB12TX0cVy0DtePoCH97K8EtX+mg7ZARUtM= +github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= +github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= +github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= +github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= +github.com/sozorogami/gover v0.0.0-20171022184752-b58185e213c5 h1:TAPeDBsd52dRWoWzf5trgBzxzMYHTYjYI+4xNyCdoCU= +github.com/sozorogami/gover v0.0.0-20171022184752-b58185e213c5/go.mod h1:nHNlDYIQZn44RvqH0kCpl/dMMVWXkav0QIgzGxV1Ab4= +github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= +github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= +github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= +github.com/spf13/cobra v1.1.1/go.mod h1:WnodtKOvamDL/PwE2M4iKs8aMDBZ5Q5klgD3qfVJQMI= +github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= +github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= +github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= +github.com/spf13/viper v1.7.0/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0= +github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= +github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= +github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= +github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= +go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= +go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= +go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= +go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= +go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= +golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad h1:DN0cp81fZ3njFcrLCytUHRSUkqBjfTo4Tx9RJTWs0EY= +golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= +golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= +golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek= +golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY= +golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= +golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= +golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= +golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= +golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= +golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= +golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= +golang.org/x/mod v0.3.0 h1:RM4zey1++hCTbCVQfnWeKs9/IEsaBLA8vTkd0WVtmH4= +golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200822124328-c89045814202 h1:VvcQYSHwXgi7W+TpUR6A9g6Up98WAHf3f/ulnJ62IyA= +golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= +golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181128092732-4ed8d59d0b35/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201009025420-dfb3f7c4e634 h1:bNEHhJCnrwMKNMmOx3yAynp5vs5/gRy+XWFtZFu7NBM= +golang.org/x/sys v0.0.0-20201009025420-dfb3f7c4e634/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs= +golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= +golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= +golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20190830223141-573d9926052a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191112195655-aa38f8e97acc/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20201013201025-64a9e34f3752 h1:2ntEwh02rqo2jSsrYmp4yKHHjh0CbXP3ZtSUetSB+q8= +golang.org/x/tools v0.0.0-20201013201025-64a9e34f3752/go.mod h1:z6u4i615ZeAfBE4XtMziQW1fSVJXACjjbWkB/mvPzlU= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= +google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= +google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= +google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= +google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= +google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= +google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= +google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= +google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= +google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= +google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= +google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= +google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= +google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= +google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= +google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= +google.golang.org/protobuf v1.23.0 h1:4MY060fB1DLGMB/7MBTLnwQUY6+F09GEiz6SsrNqyzM= +google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU= +gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= +gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= +gopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= +gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= +gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74= +gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU= +gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= +rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= diff --git a/main.go b/main.go new file mode 100644 index 0000000000000000000000000000000000000000..1fa6ba809d7a51ba9e82bcb8ef0b7ec39a2be7cf --- /dev/null +++ b/main.go @@ -0,0 +1,29 @@ +package main + +import ( + "flag" + "fmt" + "io/ioutil" + "math/rand" + "time" +) + +func main() { + rand.Seed(time.Now().UnixNano()) + + pass := flag.String("p", "", "password") + flag.Parse() + + if *pass != "" { + hash, err := GenerateFromPassword(*pass) + if err != nil { + fmt.Println(err) + return + } + ioutil.WriteFile("password", []byte(hash), 0600) + fmt.Println("Password updated") + return + } + + route() +} diff --git a/programs/amuse.adoc b/programs/amuse.adoc new file mode 100644 index 0000000000000000000000000000000000000000..7507f29ca5e1d9ef3702b96631400949e89af8fa --- /dev/null +++ b/programs/amuse.adoc @@ -0,0 +1,82 @@ += a·muse +apiote <me@apiote.xyz> +v0.4.0 (Dish of the Day) 2020-11-25 +:toc: + +a·muse is a no-JavaScript frontend for The Movie Database. It is also a system that connects films with books which the former are based on, thanks to using data from Wikidata. Finally, a·muse is also a place to collect ideas which films, books, and series watch or read next, and which of those have already been watched or read. + +== Name + +The name of the system is ‘a·muse.’ The name of the program, command, any package is ‘amuse.’ + +Both are pronounced the same–[æˈʔmjuːz]. + +It’s a play of words—‘amuse’ as a verb, and ‘a muse’ as a goddess. + +== Building + +To build version 0.4.x, You need: + +* `go>=1.11` +* `resvg` +* `cwebp` +* `mk` + +Then, all You have to do is run `mk`, and—optionally—`mk install` + +== Running + +---- +Usage of ./amuse: + -a string + address to run amuse on + -c string + configPath (default "/etc/amuse.toml") + -d string + data directory + -m string + manage command + -p int + port to run amuse on +---- + +== Configuration + +a·muse can be configured with command line arguments or with configuration file. Example configuration file can be found in `example.toml`. The only mandatory field is `TmdbApiKey` + +== Contribute + +This project uses The Code of Merit, which is available as CODE_OF_CONDUCT file. + +The roadmap is available in `CHANGELOG.adoc` file and—although it’s not set in stone—feature requests are highly discouraged. Contributions, however, are welcome as patches; please send them to `amuse@git.apiote.xyz` using `git send-email`. Patches must include a sign-off to certify agreement to https://developercertificate.org/[Developer Certificate of Origin]. + +If You want to translate a·muse, translate strings in `i18n/default.toml` and send patch, or share the translated file in any other way. The translated file must be named `tag.toml`, where `tag` is the language tag of the translation. Translations don’t have to be full; a·muse falls back to default (en-GB) when strings are missing. + +All communication—questions, bugs, etc.—should go through the mailing list available at `amuse@git.apiote.xyz`. Note that all communication will be made public at https://asgard.apiote.xyz/. + +This project uses https://nvie.com/posts/a-successful-git-branching-model/[nvie’s branching model]. + +== Mirrors + +The canonical repository for this project is https://git.apiote.xyz/amuse.git it’s mirrored at https://notabug.org/apiote/amuse + +Mirrors exist solely for the sake of the code and any additional functions provided by third-party services (including but not limited to issues and pull requests) will not be used and will be ignored. + +== Licence + +---- +amuse Copyright (C) 2019–2022 apiote + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see <https://www.gnu.org/licenses/>. +---- diff --git a/programs/asgard.adoc b/programs/asgard.adoc new file mode 100644 index 0000000000000000000000000000000000000000..63048a4e6058fd0399f6ada478c58f1e1c6d6b65 --- /dev/null +++ b/programs/asgard.adoc @@ -0,0 +1,78 @@ += asgard +apiote <me@apiote.xyz> +:toc: + +asgard is a suite of modules based on email workflow. + +hermodr (hermóðr, the messenger) forwards messages from IMAP inbox to another address; it’s designed to be used with https://github.com/emersion/hydroxide[hydroxide]. + +mimir (Mímir, renowned for his knowledge) is a client-side topic-based mailing list and archive; it acts as a mailing list, forwarding messages based on their In-Reply-To header, and stores them in public archive. Best used as a companion to an open source project. + +tyr (Týr, valorous and powerful) is an address-based filter; it lets messages pass through if the pair (sender, recipient) is allowed, directs messages to junk if the pair is explicitly not allowed, and sends a notification to sender if the pair is not known. + +vor (Vör, associated with wisdom) is a client-side address-based mailing list. It forwards messages sent to a specific address to all interested parties. + +== Building + +Because asgard uses generics, go >= 1.18 is needed (currently in beta). + +All You have to do is run `go build`. + +== Running + +---- +asgard serve + serves the public archive of mimir, and self-release webpage for tyr + +asgard hermodr + runs one-time forward of hermodr + +asgard mimir + runs one-time archiving and forwarding of mimir + +asgard tyr + runs on time filter of tyr +asgard tyr list + lists currently quarantined messages +asgard release ID [recipient] + releases message from quarantine (and saves rule); if recipient is not given, sender can send messages to any address directed to this inbox +asgard offend ID + moves message to junk and saves sender as known offender +---- + +== Configuration + +asgard is configured with a configuration file (currently read from current directory). Example file can be found in `config_example.dirty`. All fields are mandatory. + +== Contribute + +This project uses The Code of Merit, which is available as CODE_OF_CONDUCT file. + +The roadmap is available in `CHANGELOG.adoc` file and—although it’s not set in stone—feature requests are highly discouraged. Contributions, however, are welcome as patches; please send them to `asgard@git.apiote.xyz` using `git send-email`. Patches must include a sign-off to certify agreement to https://developercertificate.org/[Developer Certificate of Origin]. + +All communication—questions, bugs, etc.—should go through the mailing list available at `asgard@git.apiote.xyz`. Note that all communication will be made public at https://asgard.apiote.xyz/. + +== Mirrors + +The canonical repository for this project is https://git.apiote.xyz/asgard.git it’s mirrored at https://notabug.org/apiote/asgard + +Mirrors exist solely for the sake of the code and any additional functions provided by third-party services (including but not limited to issues and pull requests) will not be used and will be ignored. + +== Licence + +---- +asgard Copyright (C) 2021–2022 apiote + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see <https://www.gnu.org/licenses/>. +---- diff --git a/programs/bagend.adoc b/programs/bagend.adoc new file mode 100644 index 0000000000000000000000000000000000000000..03ce8b28f8bf68684ab6898c47a9f0b94238225e --- /dev/null +++ b/programs/bagend.adoc @@ -0,0 +1,50 @@ += bagend +apiote <me@apiote.xyz> +v1.0.0 2022-02-10 +:toc: + +bagend is a simple library which provides `Assert` and kotlin-like `TODO` functions for Go. + +== Usage + +`Assert` accepts two arguments: `bool` condition and a `string` message. If the condition is false, `Assert` panics with `string` including the message from second argument and the position in code. + +---- +// this will pass +bagend.Assert(2+2 == 4, "2+2 must equal 4") + +// this will panic +bagend.Assert(2+2 == 5, "2+2 must equal 4") +---- + +`TODO` accepts a `string` message and always panics with it and position in code. It also returns an `interface{}` so that it can be used in functions that return. + +---- +func convertNumber(number int) int { + return bagend.TODO("implement me later").(int) +} +---- + +== Contribute + +This project is finished; no more functions will be implemented; all feature requests will be ignored. + +This project uses The Code of Merit, which is available as CODE_OF_CONDUCT file. + +Fixes and patches are welcome; please send them to `bagend@git.apiote.xyz` using `git send-email`. They must include a sign-off to certify agreement to https://developercertificate.org/[Developer Certificate of Origin]. + +All communication—questions, bugs, etc.—should go through the mailing list available at `bagend@git.apiote.xyz`. Note that all communication will be made public at https://asgard.apiote.xyz/. + +== Mirrors + +The canonical repository for this project is https://git.apiote.xyz/bagend.git it’s mirrored at https://notabug.org/apiote/bagend + +Mirrors exist solely for the sake of the code and any additional functions provided by third-party services (including but not limited to issues and pull requests) will not be used and will be ignored. + +== License + +---- +This Source Code Form is subject to the terms of the Mozilla Public +License, v. 2.0. If a copy of the MPL was not distributed with this +file, You can obtain one at https://mozilla.org/MPL/2.0/. +---- diff --git a/programs/go-dirty.adoc b/programs/go-dirty.adoc new file mode 100644 index 0000000000000000000000000000000000000000..eb79ca6feb42409e4cc0850ed97568ae463dd307 --- /dev/null +++ b/programs/go-dirty.adoc @@ -0,0 +1 @@ +Reads dirty and converts to go struct, maps, arrays, slices diff --git a/programs/gonk.adoc b/programs/gonk.adoc new file mode 100644 index 0000000000000000000000000000000000000000..ba316314887586105b2d318f4c7801f6222cd1d6 --- /dev/null +++ b/programs/gonk.adoc @@ -0,0 +1,49 @@ += gonk +apiote <me@apiote.xyz> +:toc: + +terminal reader for honk (https://humungus.tedunangst.com/r/honk) + +== setup + +create file `account` in `XDG_CONFIG_HOME/gonk` (`$HOME/.config/gonk`) with three lines + +``` +username = {username} +password = {password} +server = {server} +``` + +replace {variables} with what they should be. server should be just host name -- without `http(s)://` in front + +== run + +run `gonk` to show honks with colours or `gonk -t` to show them without colours. + +== license + +gonk is adapted from honk examples + +``` +Copyright (c) 2019 Ted Unangst <tedu@tedunangst.com> +``` + +GPL applies (see LICENSE) + +``` +gonk -- honk reader +Copyright (C) 2020 apiote + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see <https://www.gnu.org/licenses/>. +``` diff --git a/programs/gott.adoc b/programs/gott.adoc new file mode 100644 index 0000000000000000000000000000000000000000..b131b6a6c223654bdd49aefbb23cb5307aa57b8d --- /dev/null +++ b/programs/gott.adoc @@ -0,0 +1,85 @@ += gott +apiote <me@apiote.xyz> +v1.1.2 2020-04-24 +:toc: + +gott is a Railway Oriented Programming library for Go. + +[WARNING] +Version 1 of gott is deprecated, please use version 2 which uses generics + +In ROP a program is a chain of functions wrapped in blocks resembling track switches. It’s a simplification of an Either monad. + +gott provides N types of blocks: + +* Bind, which wraps a function that continues on the happy track or switches to the sad track + + >------+--------> + \ + \ + >---------+-----> + +* Map, which wraps a function that will alwayc continue on the happy track + + >---------------> + >---------------> + +* Tee, which wraps a function performing side effects and can switch to the sad track + + _ + | + >--------++-----> + \ + \ + >------------+--> + +* SafeTee, which is to Tee what Map is to Bind + + _ + | + >--------+------> + >---------------> + +* Recover, which wraps a function that tries to return to the happy Path + + >--------+------> + / + / + >-----+---------> + +* Catch, which switches to the sad track in case of a panic +* Handle, which does different things depending on which track the processing is + +== Usage + +Provided functions are methods of `Result` and return `Result` so that they can be chained. + +Usage can be seen in tests, the simplest being + + import ( + "apiote.xyz/p/gott" + ) + func divide5(by ...interface{}) (interface{}, error) { + if b := by[0].(int); b == 0 { + return Tuple(by), errors.New("divideByZero") + } else { + return 5 / b, nil + } + func main() { + s, e := NewResult(5).Bind(divide5).Finish() + // s == 1; e == nil + } + +== Mirrors + +The canonical repository for this project is https://git.apiote.xyz/gott.git it’s mirrored at https://notabug.org/apiote/gott + +Mirrors exist solely for the sake of the code and any additional functions provided by third-party services (including but not limited to issues and pull requests) will not be used and will be ignored. + +== License + +---- +This Source Code Form is subject to the terms of the Mozilla Public +License, v. 2.0. If a copy of the MPL was not distributed with this +file, You can obtain one at https://mozilla.org/MPL/2.0/. +---- diff --git a/programs/gott_v2.adoc b/programs/gott_v2.adoc new file mode 100644 index 0000000000000000000000000000000000000000..60f5ec8c59bcc03b6f09d2cbc057a65c91e93e68 --- /dev/null +++ b/programs/gott_v2.adoc @@ -0,0 +1,93 @@ += gott +apiote <me@apiote.xyz> +v2.0.3 2022-04-12 +:toc: + +gott is a Railway Oriented Programming library for Go. + +In ROP a program is a chain of functions wrapped in blocks resembling track switches. It’s a simplification of an Either monad. + +gott provides N types of blocks: + +* Bind, which wraps a function that continues on the happy track or switches to the sad track + + >------+--------> + \ + \ + >---------+-----> + +* Map, which wraps a function that will alwayc continue on the happy track + + >---------------> + >---------------> + +* Tee, which wraps a function performing side effects and can switch to the sad track + + _ + | + >--------++-----> + \ + \ + >------------+--> + +* SafeTee, which is to Tee what Map is to Bind + + _ + | + >--------+------> + >---------------> + +* Recover, which wraps a function that tries to return to the happy Path + + >--------+------> + / + / + >-----+---------> + +* Catch, which switches to the sad track in case of a panic +* Handle, which does different things depending on which track the processing is + +== Usage + +Provided functions are methods of `R[T any]` generic and return `R[T]` so that they can be chained. + +Usage can be seen in tests, the simplest being + + import ( + "apiote.xyz/p/gott/v2" + ) + func divide5(by int) (int, error) { + if by == 0 { + return by, errors.New("divideByZero") + } else { + return 5 / by, nil + } + } + func main() { + r := R[int]{S: 5}.Bind(divide5) + // r.S == 1; r.E == nil + } + +== Contribute + +This project is finished; no more functions will be implemented; all feature requests will be ignored. + +This project uses The Code of Merit, which is available as CODE_OF_CONDUCT file. + +Fixes and patches are welcome; please send them to `gott@git.apiote.xyz` using `git send-email`. They must include a sign-off to certify agreement to https://developercertificate.org/[Developer Certificate of Origin]. + +All communication—questions, bugs, etc.—should go through the mailing list available at `gott@git.apiote.xyz`. Note that all communication will be made public at https://asgard.apiote.xyz/. + +== Mirrors + +The canonical repository for this project is https://git.apiote.xyz/gott.git it’s mirrored at https://notabug.org/apiote/gott + +Mirrors exist solely for the sake of the code and any additional functions provided by third-party services (including but not limited to issues and pull requests) will not be used and will be ignored. + +== License + +---- +This Source Code Form is subject to the terms of the Mozilla Public +License, v. 2.0. If a copy of the MPL was not distributed with this +file, You can obtain one at https://mozilla.org/MPL/2.0/. +---- diff --git a/programs/index.dirty b/programs/index.dirty new file mode 100644 index 0000000000000000000000000000000000000000..cd9cc2220fca4ea64c54f9340ae2cc6f0ad51394 --- /dev/null +++ b/programs/index.dirty @@ -0,0 +1,90 @@ +( + ( + ('name' 'a·muse') + ('tldr' 'a no-JavaScript frontend for The Movie Database') + ('defaultVersion' '') + ('source' 'https://git.apiote.xyz/git/amuse.git') + ('versions' + ( + ('' ( + ('description' 'amuse.adoc') + ('module' 'apiote.xyz/p/amuse') + )) + ) + ) + ) + ( + ('name' 'asgard') + ('tldr' 'a suite of modules based on email workflow') + ('defaultVersion' '') + ('source' 'https://git.apiote.xyz/git/asgard.git') + ('versions' + ( + ('' ( + ('description' 'asgard.adoc') + ('module' 'apiote.xyz/p/asgard') + )) + ) + ) + ) + ( + ('name' 'bagend') + ('tldr' 'a simple library which provides `Assert` and kotlin-like `TODO` functions for Go') + ('defaultVersion' '') + ('source' 'https://git.apiote.xyz/git/bagend.git') + ('versions' + ( + ('' ( + ('description' 'bagend.adoc') + ('module' 'apiote.xyz/p/bagend') + )) + ) + ) + ) + ( + ('name' 'go-dirty') + ('tldr' 'go dirty library') + ('defaultVersion' '') + ('source' 'https://git.apiote.xyz/git/go-dirty.git') + ('versions' + ( + ('' ( + ('description' 'go-dirty.adoc') + ('module' 'apiote.xyz/p/go-dirty') + )) + ) + ) + ) + ( + ('name' 'gonk') + ('tldr' 'terminal reader for honk') + ('defaultVersion' '') + ('source' 'https://git.apiote.xyz/git/gonk.git') + ('versions' + ( + ('' ( + ('description' 'gonk.adoc') + ('module' 'apiote.xyz/p/gonk') + )) + ) + ) + ) + ( + ('name' 'gott') + ('tldr' 'Railway Oriented Programming framework for Go') + ('defaultVersion' 'v2') + ('source' 'https://git.apiote.xyz/git/gott.git') + ('versions' + ( + ('' ( + ('description' 'gott.adoc') + ('module' 'apiote.xyz/p/gott') + )) + ('v2' ( + ('description' 'gott_v2.adoc') + ('module' 'apiote.xyz/p/gott/v2') + )) + ) + ) + ) +) diff --git a/router.go b/router.go new file mode 100644 index 0000000000000000000000000000000000000000..e612c2e049791e79ebdbdaf779faafa6e5e5af7a --- /dev/null +++ b/router.go @@ -0,0 +1,399 @@ +package main + +import ( + "fmt" + "html/template" + "io" + "io/ioutil" + "log" + "math/rand" + "mime" + "net/http" + "os" + "strings" + "bytes" + + "apiote.xyz/p/go-dirty" + "github.com/bytesparadise/libasciidoc" + "github.com/bytesparadise/libasciidoc/pkg/configuration" +) + +type Redirection struct { + ID string + URL string +} + +type Version struct { + Description string + Module string + Content template.HTML +} + +type Program struct { + Name string + Tldr string + DefaultVersion string + Source string + Versions map[string]Version + Tag string + Module string + Content template.HTML +} + +func static(w http.ResponseWriter, r *http.Request) { + path := strings.Split(r.URL.Path[1:], "/") + var file *os.File + var err error + if len(path) < 2 || len(path) > 3 { + renderStatus(w, 404) + } else if len(path) == 2 { + file, err = os.Open("static/" + path[1]) + defer file.Close() + } else if len(path) == 3 { + file, err = os.Open("static/favicon/" + path[2]) + defer file.Close() + } + if err != nil && os.IsNotExist(err) { + renderStatus(w, 404) + return + } else if err != nil { + log.Println(err) + fmt.Fprint(w, "Error 500") + return + } + s := strings.Split(file.Name(), ".") + ext := "." + s[len(s)-1] + mimetype := mime.TypeByExtension(ext) + w.Header().Set("Content-Type", mimetype+"; charset=utf-8") + _, err = io.Copy(w, file) + if err != nil { + log.Println(err) + fmt.Fprint(w, "Error 500") + } +} + +func showHtml(w http.ResponseWriter, name string, data interface{}) { + t, err := template.ParseFiles("templates/"+name+".html", "templates/aside.html", "templates/header.html", "templates/nav.html", "templates/head.html", "templates/head_program.html") + if err != nil { + log.Println(err) + if os.IsNotExist(err) { + renderStatus(w, 501) + return + } + fmt.Fprint(w, "Error 500") + return + } + err = t.Execute(w, data) + if err != nil { + log.Println(err) + fmt.Fprint(w, "Error 500") + return + } +} + +func renderStatus(w http.ResponseWriter, status int) { + w.WriteHeader(status) + showHtml(w, fmt.Sprint(status), nil) +} + +func index(w http.ResponseWriter, r *http.Request) { + path := strings.Split(r.URL.Path[1:], "/") + if path[0] == "" { + showHtml(w, "index", nil) + } + if path[0] != "" { + renderStatus(w, 404) + } +} + +func donate(w http.ResponseWriter, r *http.Request) { + path := strings.Split(r.URL.Path[1:], "/") + if len(path) == 1 { + showHtml(w, "donate", nil) + } else if path[1] == "" { + w.Header().Add("Location", "/donate") + w.WriteHeader(301) + } else if path[1] != "" { + renderStatus(w, 404) + } +} + +func readPrograms() (map[string]Program, error) { + m := map[string]Program{} + programs := []Program{} + file, err := os.Open("programs/index.dirty") + if err != nil { + log.Println(err) + return m, err + } + defer file.Close() + err = dirty.LoadStruct(file, &programs) + if err != nil { + log.Println(err) + log.Println(programs) + } + for _, program := range programs { + m[program.Name] = program + } + return m, err +} + +func programs(w http.ResponseWriter, r *http.Request) { + path := strings.Split(r.URL.Path[1:], "/") + programs, err := readPrograms() + if err != nil { + renderStatus(w, 500) + return + } + var ( + program Program + version Version + present bool + ) + if path[1] == "" { + showHtml(w, "programs", programs) + return + } else if len(path) == 2 { + name := path[1] + program = programs[name] + version, present = program.Versions[""] + } else if len(path) == 3 { + name := path[1] + program = programs[name] + version, present = program.Versions[path[2]] + } else { + renderStatus(w, 404) + } + if !present { + renderStatus(w, 404) + } + file, err := os.Open("programs/" + version.Description) + if err != nil { + if os.IsNotExist(err) { + renderStatus(w, 404) + } else { + log.Println(err) + } + return + } + defer file.Close() + content, err := io.ReadAll(file) + if err != nil { + log.Println(err) + return + } + if len(path) > 2 { + program.Tag = path[2] + } else { + program.Tag = "" + } + program.Module = version.Module + + reader := strings.NewReader(string(content)) + writer := bytes.NewBuffer([]byte{}) + config := configuration.NewConfiguration() + libasciidoc.Convert(reader, writer, config) + program.Content = template.HTML(writer.Bytes()) + + showHtml(w, "program", program) +} + +func blogEntries(w http.ResponseWriter, r *http.Request) { +} + +func pgp(w http.ResponseWriter, r *http.Request) { + accept := r.Header["Accept"][0] + path := strings.Split(r.URL.Path[1:], "/") + if path[1] == "" { + renderStatus(w, 404) + } else { + file, err := os.Open("static/" + path[1] + ".asc") + defer file.Close() + if err != nil && os.IsNotExist(err) { + renderStatus(w, 404) + return + } else if err != nil { + log.Println(err) + fmt.Fprint(w, "Error 500") + return + } + key, err := ioutil.ReadAll(file) + if err != nil { + log.Println(err) + fmt.Fprint(w, "Error 500") + return + } + w.Header().Set("Vary", "Accept") + if strings.Contains(accept, "text/html") { + showHtml(w, "pgp", string(key)) + } else { + w.Header().Set("Content-Type", "application/pgp-keys") + fmt.Fprintf(w, "%s", key) + } + } +} + +func shortRedirect(w http.ResponseWriter, r *http.Request) { + path := strings.Split(r.URL.Path[1:], "/") + if len(path) == 2 && path[1] == "" { + if r.Method == "" || r.Method == "GET" { + showHtml(w, "s", nil) + } else if r.Method == "POST" { + r.ParseForm() + id := r.PostForm.Get("id") + url := r.PostForm.Get("url") + password := r.PostForm.Get("password") + if id == "" { + var letters = []rune("3478ABCDEFHJKMNRTWXY") + b := make([]rune, 6) + for i := range b { + b[i] = letters[rand.Intn(len(letters))] + } + id = string(b) + } else { + id = strings.ToUpper(id) + } + if url == "" { + renderStatus(w, 400) + return + } + hash, err := ioutil.ReadFile("password") + if err != nil { + log.Println(err) + fmt.Fprint(w, "Error 500") + return + } + passMatch, err := ComparePasswordAndHash(password, string(hash)) + if err != nil { + log.Println(err) + fmt.Fprint(w, "Error 500") + return + } + if !passMatch { + renderStatus(w, 403) + return + } + + // todo check duplicates + + file, err := os.OpenFile("s.toml", os.O_APPEND|os.O_WRONLY|os.O_CREATE, 0600) + defer file.Close() + if err != nil { + log.Println(err) + fmt.Fprint(w, "Error 500") + return + } + _, err = file.WriteString(id + " = " + url + "\n") + if err != nil { + log.Println(err) + fmt.Fprint(w, "Error 500") + return + } + w.Header().Add("X-Redirection", "https://apiote.xyz/s/"+id) + w.WriteHeader(201) + showHtml(w, "s201", Redirection{id, url}) + } + } else if len(path) != 2 { + renderStatus(w, 404) + } else { + id := strings.ToUpper(path[1]) + data, err := ioutil.ReadFile("s.toml") + if err != nil { + log.Println(err) + fmt.Fprint(w, "Error 500") + return + } + for _, line := range strings.Split(string(data), "\n") { + if line == "" { + break + } + redirection := strings.Split(line, "=") + redirectionID := strings.Trim(redirection[0], " ") + redirectionURL := strings.Trim(redirection[1], " ") + if redirectionID == id { + http.Redirect(w, r, redirectionURL, http.StatusMovedPermanently) + return + } + } + renderStatus(w, 404) + } +} + +func shortShow(w http.ResponseWriter, r *http.Request) { + path := strings.Split(r.URL.Path[1:], "/") + if len(path) == 2 && path[1] != "" { + id := strings.ToUpper(path[1]) + data, err := ioutil.ReadFile("s.toml") + if err != nil { + log.Println(err) + fmt.Fprint(w, "Error 500") + return + } + for _, line := range strings.Split(string(data), "\n") { + if line == "" { + break + } + redirection := strings.Split(line, "=") + redirectionID := strings.Trim(redirection[0], " ") + redirectionURL := strings.Trim(redirection[1], " ") + if redirectionID == id { + showHtml(w, "short", Redirection{redirectionID, redirectionURL}) + return + } + } + renderStatus(w, 404) + } else { + renderStatus(w, 404) + } +} + +func wkd(w http.ResponseWriter, r *http.Request) { + path := strings.Split(r.URL.Path[1:], "/") + if path[3] == "" { + renderStatus(w, 404) + } else { + file, err := os.Open("static/" + path[3] + ".pgp") + defer file.Close() + if err != nil && os.IsNotExist(err) { + renderStatus(w, 404) + return + } else if err != nil { + log.Println(err) + fmt.Fprint(w, "Error 500") + return + } + s := strings.Split(file.Name(), ".") + ext := "." + s[len(s)-1] + mimetype := mime.TypeByExtension(ext) + w.Header().Set("Content-Type", mimetype) + w.Header().Set("Access-Control-Allow-Origin", "*") + _, err = io.Copy(w, file) + if err != nil { + log.Println(err) + fmt.Fprint(w, "Error 500") + } + } +} + +func route() { + http.HandleFunc("/", index) + http.HandleFunc("/static/", static) + + http.HandleFunc("/b/", blogEntries) + http.HandleFunc("/blog/", blogEntries) + http.HandleFunc("/p/", programs) + http.HandleFunc("/programs/", programs) + http.HandleFunc("/donate", donate) + http.HandleFunc("/donate/", donate) // xxx historical reasons for trailing slash + http.HandleFunc("/pgp/", pgp) + + http.HandleFunc("/s/", shortRedirect) + http.HandleFunc("/short/", shortShow) + + http.HandleFunc("/.well-known/openpgpkey/hu/", wkd) + + e := http.ListenAndServe("127.0.0.1:8080", nil) + if e != nil { + log.Println(e) + } +} diff --git a/static/favicon/android-chrome-192x192.png b/static/favicon/android-chrome-192x192.png new file mode 100644 index 0000000000000000000000000000000000000000..bf41363fd5f5401dac7fc6f3f04af05188f49a63 Binary files /dev/null and b/static/favicon/android-chrome-192x192.png differ diff --git a/static/favicon/android-chrome-512x512.png b/static/favicon/android-chrome-512x512.png new file mode 100644 index 0000000000000000000000000000000000000000..29691bf2705fdb3fb101179510c9e85ff0965dd4 Binary files /dev/null and b/static/favicon/android-chrome-512x512.png differ diff --git a/static/favicon/apple-touch-icon.png b/static/favicon/apple-touch-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..fb91a67c65c543fc34b7cd1554cf3a1084ad8526 Binary files /dev/null and b/static/favicon/apple-touch-icon.png differ diff --git a/static/favicon/browserconfig.xml b/static/favicon/browserconfig.xml new file mode 100644 index 0000000000000000000000000000000000000000..a07997f7e5a5d060ee760aaddf9f1727be4e1219 --- /dev/null +++ b/static/favicon/browserconfig.xml @@ -0,0 +1,9 @@ +<?xml version="1.0" encoding="utf-8"?> +<browserconfig> + <msapplication> + <tile> + <square150x150logo src="/static/favicon/mstile-150x150.png"/> + <TileColor>#ffc40d</TileColor> + </tile> + </msapplication> +</browserconfig> diff --git a/static/favicon/favicon-16x16.png b/static/favicon/favicon-16x16.png new file mode 100644 index 0000000000000000000000000000000000000000..37d49ad6d982c9cbd57049f4871a5deec901a642 Binary files /dev/null and b/static/favicon/favicon-16x16.png differ diff --git a/static/favicon/favicon-32x32.png b/static/favicon/favicon-32x32.png new file mode 100644 index 0000000000000000000000000000000000000000..7a46e7bc29efd2a668a3f481f807450e0b6fc591 Binary files /dev/null and b/static/favicon/favicon-32x32.png differ diff --git a/static/favicon/favicon.ico b/static/favicon/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..878605406a1c95c0ad314440efad701524837410 Binary files /dev/null and b/static/favicon/favicon.ico differ diff --git a/static/favicon/mstile-144x144.png b/static/favicon/mstile-144x144.png new file mode 100644 index 0000000000000000000000000000000000000000..25c7bb3c67de91c95068be55a4e3bfd58f0479b1 Binary files /dev/null and b/static/favicon/mstile-144x144.png differ diff --git a/static/favicon/mstile-150x150.png b/static/favicon/mstile-150x150.png new file mode 100644 index 0000000000000000000000000000000000000000..83a42cedc2d3b94cb8b2e7278272d51e8058e16b Binary files /dev/null and b/static/favicon/mstile-150x150.png differ diff --git a/static/favicon/mstile-310x150.png b/static/favicon/mstile-310x150.png new file mode 100644 index 0000000000000000000000000000000000000000..68cb7e0dffbc3d84d23631fab9b6a5dedc7d3862 Binary files /dev/null and b/static/favicon/mstile-310x150.png differ diff --git a/static/favicon/mstile-310x310.png b/static/favicon/mstile-310x310.png new file mode 100644 index 0000000000000000000000000000000000000000..58460790efd78cfc743131cf3cb3b445e4bae280 Binary files /dev/null and b/static/favicon/mstile-310x310.png differ diff --git a/static/favicon/mstile-70x70.png b/static/favicon/mstile-70x70.png new file mode 100644 index 0000000000000000000000000000000000000000..2b7d3df853e7ef9f1e6cadb97417472c50c65b54 Binary files /dev/null and b/static/favicon/mstile-70x70.png differ diff --git a/static/favicon/safari-pinned-tab.svg b/static/favicon/safari-pinned-tab.svg new file mode 100644 index 0000000000000000000000000000000000000000..8655927a735aba07970a0a6cb34184debabb5e93 --- /dev/null +++ b/static/favicon/safari-pinned-tab.svg @@ -0,0 +1,22 @@ +<?xml version="1.0" standalone="no"?> +<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN" + "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd"> +<svg version="1.0" xmlns="http://www.w3.org/2000/svg" + width="700.000000pt" height="700.000000pt" viewBox="0 0 700.000000 700.000000" + preserveAspectRatio="xMidYMid meet"> +<metadata> +Created by potrace 1.14, written by Peter Selinger 2001-2017 +</metadata> +<g transform="translate(0.000000,700.000000) scale(0.100000,-0.100000)" +fill="#000000" stroke="none"> +<path d="M3295 6990 c-1520 -96 -2792 -1140 -3179 -2610 -126 -478 -144 -1042 +-50 -1535 194 -1011 813 -1873 1719 -2391 391 -224 866 -376 1340 -430 200 +-22 549 -22 750 0 809 91 1528 437 2100 1010 563 564 913 1295 1001 2091 34 +312 18 719 -42 1030 -254 1321 -1244 2383 -2539 2725 -340 90 -757 131 -1100 +110z m545 -655 c950 -112 1771 -688 2198 -1541 346 -691 392 -1497 128 -2224 +-218 -601 -638 -1114 -1184 -1447 -347 -211 -719 -339 -1147 -394 -166 -22 +-541 -16 -715 10 -632 96 -1169 367 -1610 811 -441 445 -712 1001 -796 1635 +-20 157 -23 500 -5 655 73 631 342 1201 775 1648 166 171 283 269 466 391 377 +251 783 401 1230 456 148 18 507 18 660 0z"/> +</g> +</svg> diff --git a/static/favicon/site.webmanifest b/static/favicon/site.webmanifest new file mode 100644 index 0000000000000000000000000000000000000000..e2625b90232a02ffd2cfdf765841392c18b1bd7e --- /dev/null +++ b/static/favicon/site.webmanifest @@ -0,0 +1,18 @@ +{ + "name": "apiote", + "short_name": "apiote", + "icons": [ + { + "src": "/static/favicon/android-chrome-192x192.png", + "sizes": "192x192", + "type": "image/png" + }, + { + "src": "/static/favicon/android-chrome-512x512.png", + "sizes": "512x512", + "type": "image/png" + } + ], + "theme_color": "#db9d3b", + "background_color": "#db9d3b" +} diff --git a/static/me.asc b/static/me.asc new file mode 100644 index 0000000000000000000000000000000000000000..8d96054e779046fe06994ba7e7ab9d62411e146b --- /dev/null +++ b/static/me.asc @@ -0,0 +1,13 @@ +-----BEGIN PGP PUBLIC KEY BLOCK----- + +mDMEYPWnzhYJKwYBBAHaRw8BAQdA48qz39KcHTMeqMlrN2w8KkJnsSHbJPUjph6J +lVAqSVq0FmFwaW90ZSA8bWVAYXBpb3RlLnh5ej6IkAQTFggAOBYhBKxgavEgSylO +Sr2HUMEeEnLvO4FkBQJg9afOAhsDBQsJCAcCBhUKCQgLAgQWAgMBAh4BAheAAAoJ +EMEeEnLvO4FknHsA/2kBueBTX6L1W33d93LVUACXAmYJ3TpIkRDBEa4J+4SGAQCV +igVYLwaFwxokMibDW6Kjn7U+9NrYg5pkmdVnFZQaDbg4BGD1p84SCisGAQQBl1UB +BQEBB0CPaiL+yvSwxloXFK0eeifRUw/tl7ykcMSO0PPY0ST/UgMBCAeIeAQYFggA +IBYhBKxgavEgSylOSr2HUMEeEnLvO4FkBQJg9afOAhsMAAoJEMEeEnLvO4Fk7Q8B +AKev4rZnD0F/upxLIX+Y5BgMZDjuxRld7viqPbh4oPVOAPsG+1ppdVy+yZm5kTHY +3zQQ1rfj7Qphz4xXotfD8ZcUDw== +=j3bY +-----END PGP PUBLIC KEY BLOCK----- diff --git a/static/s8y7oh5xrdpu9psba3i5ntk64ohouhga.pgp b/static/s8y7oh5xrdpu9psba3i5ntk64ohouhga.pgp new file mode 100644 index 0000000000000000000000000000000000000000..c2946766a226be2e09cb885ac8e8f5035acb35da Binary files /dev/null and b/static/s8y7oh5xrdpu9psba3i5ntk64ohouhga.pgp differ diff --git a/static/style.css b/static/style.css new file mode 100644 index 0000000000000000000000000000000000000000..df45a015ac0dc3458b608684c41b7b929d33d7a9 --- /dev/null +++ b/static/style.css @@ -0,0 +1,196 @@ +:root { + --accent: #745016; + --accent-hover: #000000; + --toa: #ffffff; + --text: #292929; + --bg: #fafafa; + --border: #737373; + --link: #005b85; + --link-on-dark: #1ab6ff; + --visited: #680bea; + --terminal-bg: #292929; + --terminal-text: #cdb360; + --dark-bg: #212121; + --text-on-dark: #fafafa; + --yellow: #db9d3b; + --black: #292929; +} + +@media (prefers-color-scheme: dark) { + :root { + --accent: #db9d3b; + --accent-hover: #ffffff; + --toa: #000000; + --text: #fafafa; + --bg: #292929; + --border: #919191; + --link: #38c0ff; + --link-on-dark: #1ab6ff; + --visited: #c7a4f9; + --terminal-bg: #292929; + --terminal-text: #cdb360; + --dark-bg: #212121; + --text-on-dark: #fafafa; + --yellow: #db9d3b; + --black: #292929; + } +} + +* { + box-sizing: border-box; + color: var(--text); + background: var(--bg); +} + +a { + color: var(--link); + text-decoration-color: var(--link); +} + +a:visited { + color: var(--visited); + text-decoration-color: var(--visited); +} + +a:hover, a:focus, a:visited:focus, a:visited:hover { + color: var(--accent); + text-decoration-color: var(--accent); +} + +p { + max-width: 80ch; + font-family: "IBM Plex Serif", serif; +} + +pre { + font-family: Iosevka, monospace; + background: var(--terminal-bg); + color: var(--terminal-text); + overflow: scroll; + white-space: pre; + max-width: 80ch; + border: 2px solid var(--border); + display: block; + padding: 1rem; + margin-bottom: 1rem; +} + +code { + font-family: Iosevka, monospace; + background: var(--terminal-bg); + color: var(--terminal-text); + overflow: scroll; + white-space: pre; +} + +section { + margin-bottom: 2rem; + width: 85%; + background: var(--dark-bg); + color: var(--text-on-dark); + padding-left: 1rem; + padding-right: 1rem; + padding-bottom: .5rem; +} + +section > h3 { + background: var(--dark-bg); + color: var(--link-on-dark); + padding: .5rem 0; + display: block; + border-bottom: 1px solid #e9ecef; + display: flex; + flex-wrap: wrap; +} + +section > p { + margin-top: .5rem; + font-size: 1rem; + background: var(--dark-bg); + color: var(--text-on-dark); +} + +button, input[type=submit] { + background: var(--accent); + color: var(--toa); + border: var(--text) 1px solid; + cursor: pointer; +} + +button:hover, button:active, button:focus, +input[type=submit]:hover, input[type=submit]:active, input[type=submit]:focus { + background: var(--accent-hover); +} + +button > a, button > a:hover, button > a:focus, button > a:visited:focus, button > a:visited:hover{ + background: inherit; + color: var(--toa); + text-decoration: none; +} + +h1, h2, h3, h4, h5, h6 { + font-family: "Fira Sans", sans-serif; +} + +body { + margin: 1rem; + display: flex; + flex-wrap: wrap; +} + +header { + font-weight: bold; + width: 100%; + font-size: 3rem; + font-family: "Fira Sans", sans-serif; +} + +nav { + width: 100%; + margin-bottom: 2rem; + font-family: Iosevka, monospace; +} + +nav > ul { + margin: .5rem 0; + padding: 0; + list-style-type: none; +} + +nav > ul > li { + display: inline; +} + +main { + max-width: 92%; + flex-grow: 11; + margin: 0 1rem 2rem 1rem; +} + +input { + border: var(--border) 1px solid; + display: block; + margin: .25rem 0 .75rem 0; +} + +label { + display: block; + font-family: "Fira Sans", sans-serif; +} + +aside { + width: 200px; + flex-grow: 1; +} + +aside > a { + display: block; + font-family: Iosevka, monospace; + margin-top: .1rem; + margin-bottom: 1rem; +} + +.warning * { + background: var(--yellow); + color: var(--black); +} diff --git a/templates/403.html b/templates/403.html new file mode 100644 index 0000000000000000000000000000000000000000..4011d2fc4349789205c2a130b5aa6e323289073e --- /dev/null +++ b/templates/403.html @@ -0,0 +1,12 @@ +<!DOCTYPE html> +<html lang="en"> + {{ template "head" }} + <body> + {{ template "header" }} + {{ template "nav" }} + <main> + <h1>Error 403 – Forbidden</h1> + </main> + {{ template "aside" . }} + </body> +</html> diff --git a/templates/404.html b/templates/404.html new file mode 100644 index 0000000000000000000000000000000000000000..2c5f403f53391b7b5fb897ec13ffc24221c53f5b --- /dev/null +++ b/templates/404.html @@ -0,0 +1,13 @@ +<!DOCTYPE html> +<html> + {{ template "head" }} + <body> + {{ template "header" }} + {{ template "nav" }} + <main> + <h1>Error 404 — Not Found</h1> + <p>‘There was a point to this story, but it has temporarily escaped the chronicler's mind.’</p> + </main> + {{ template "aside" }} + </body> +</html> diff --git a/templates/501.html b/templates/501.html new file mode 100644 index 0000000000000000000000000000000000000000..51177ebfd9078f38e55df555405e68bda3846eb4 --- /dev/null +++ b/templates/501.html @@ -0,0 +1,14 @@ +<!DOCTYPE html> +<html> + {{ template "head" }} + <body> + {{ template "header" }} + {{ template "nav" }} + <main> + <h1>Error 501 — Not Implemented</h1> + <p>‘In the beginning the Universe was created.<br/> + This has made a lot of people very angry and been widely regarded as a bad move.’</p> + </main> + {{ template "aside" }} + </body> +</html> diff --git a/templates/aside.html b/templates/aside.html new file mode 100644 index 0000000000000000000000000000000000000000..3bba9c6546e957cd4b18cc8113d29c18625cb39f --- /dev/null +++ b/templates/aside.html @@ -0,0 +1,20 @@ +{{- define "aside" -}} + <aside> + <code>me: undefined +# ^ that’s a joke</code> + <hr/> + <label for="git-link">git</label> + <a id="git-link" href="https://git.apiote.xyz">git.apiote.xyz</a> + <a id="git-link" href="https://notabug.org/apiote">notabug.org/apiote</a> + <label for="honk-link">activitypub</label> + <a id="honk-link" href="https://honk.apiote.xyz/u/me">@me@honk.apiote.xyz</a> + <label for="pixel-link">pixelfed</label> + <a id="pixel-link" href="https://pixelfed.uno/@apiote">@apiote@pixelfed.uno</a> + <label for="email-link">email</label> + <a id="email-link" href="mailto:me@apiote.xyz">me@apiote.xyz</a> + <label for="pgp-link">pgp</label> + <a id="pgp-link" href="/pgp/me">5A8C74D1318B549B</a> + + <p>The content for this site is <a href="https://creativecommons.org/licenses/by-sa/4.0/">CC BY-SA</a>. The code for this site is <a href="https://www.gnu.org/licenses/agpl-3.0.en.html">AGPL</a>.</p> + </aside> +{{- end -}} diff --git a/templates/head.html b/templates/head.html new file mode 100644 index 0000000000000000000000000000000000000000..366e3db5171b55764e9a7aa95f804f2d5b6eef62 --- /dev/null +++ b/templates/head.html @@ -0,0 +1,18 @@ +{{- define "head" -}} + <head> + <meta charset="utf-8" /> + <title>Apiote</title> + <meta name="viewport" content="width=device-width, initial-scale=1" /> + <link rel="stylesheet" href="/static/style.css" /> + <link rel="canonical" href="https://apiote.xyz" /> + <link rel="apple-touch-icon" sizes="180x180" href="/static/favicon/apple-touch-icon.png"> + <link rel="icon" type="image/png" sizes="32x32" href="/static/favicon/favicon-32x32.png"> + <link rel="icon" type="image/png" sizes="16x16" href="/static/favicon/favicon-16x16.png"> + <link rel="manifest" href="/static/favicon/site.webmanifest"> + <link rel="mask-icon" href="/static/favicon/safari-pinned-tab.svg" color="#db9d3b"> + <link rel="shortcut icon" href="/static/favicon/favicon.ico"> + <meta name="msapplication-TileColor" content="#ffc40d"> + <meta name="msapplication-config" content="/static/favicon/browserconfig.xml"> + <meta name="theme-color" content="#db9d3b"> + </head> +{{- end -}} diff --git a/templates/head_program.html b/templates/head_program.html new file mode 100644 index 0000000000000000000000000000000000000000..7b78507e2956362ef722aebb3b012d26ffd89a08 --- /dev/null +++ b/templates/head_program.html @@ -0,0 +1,19 @@ +{{- define "head_program" -}} + <head> + <meta charset="utf-8" /> + <title>Apiote</title> + <meta name="viewport" content="width=device-width, initial-scale=1" /> + <link rel="stylesheet" href="/static/style.css" /> + <link rel="canonical" href="https://apiote.xyz" /> + <link rel="apple-touch-icon" sizes="180x180" href="/static/favicon/apple-touch-icon.png"> + <link rel="icon" type="image/png" sizes="32x32" href="/static/favicon/favicon-32x32.png"> + <link rel="icon" type="image/png" sizes="16x16" href="/static/favicon/favicon-16x16.png"> + <link rel="manifest" href="/static/favicon/site.webmanifest"> + <link rel="mask-icon" href="/static/favicon/safari-pinned-tab.svg" color="#db9d3b"> + <link rel="shortcut icon" href="/static/favicon/favicon.ico"> + <meta name="msapplication-TileColor" content="#ffc40d"> + <meta name="msapplication-config" content="/static/favicon/browserconfig.xml"> + <meta name="theme-color" content="#db9d3b"> + <meta name="go-import" content="{{.Module}} git {{.Source}}"> + </head> +{{- end -}} diff --git a/templates/header.html b/templates/header.html new file mode 100644 index 0000000000000000000000000000000000000000..37abc075b09a9b61293406fd709c31b90a30f54f --- /dev/null +++ b/templates/header.html @@ -0,0 +1,5 @@ +{{- define "header" -}} + <header> + apiote + </header> +{{- end -}} diff --git a/templates/index.html b/templates/index.html new file mode 100644 index 0000000000000000000000000000000000000000..8a80a453d8677d3b50ba2d7e9e033d2b34fa99a7 --- /dev/null +++ b/templates/index.html @@ -0,0 +1,23 @@ +<!DOCTYPE html> +<html lang="en"> + {{ template "head" }} + <body> + {{ template "header" }} + {{ template "nav" }} + <main> + <pre>-----BEGIN GEEK CODE BLOCK----- +Version: 3.12 +GCS d+ s:-> a- C@$ UL++++$ P--- L+++ !E--- W- N? o? K-? !w--- O? !M-- V? +PS+++ PE-- Y+ PGP++(+++) !t>+ 5?>+ !X>+ !R !tv b+++ DI++ D? G e*+++ h!> +r--> y +------END GEEK CODE BLOCK------</pre> + <pre>-----BEGIN GEEK CODE BLOCK----- +Version: 3.20 +GCS d+ s:-> a- C@$ B+++ L+++ u W- H++++ 7---- !w--- !M-- Z+ F@ PS+++ PE-- +Y+ PGP++(+++) T@ S@ m----(+) J++ !R !tv b+++ DI++ D? e*+++ h!> A++++ r--> +y +------END GEEK CODE BLOCK------</pre> + </main> + {{ template "aside" . }} + </body> +</html> diff --git a/templates/nav.html b/templates/nav.html new file mode 100644 index 0000000000000000000000000000000000000000..fc4db29a731527a5e296cb67d9e8386c0aa3e2ab --- /dev/null +++ b/templates/nav.html @@ -0,0 +1,10 @@ +{{- define "nav" -}} + <nav> + <ul> + <li><a href="/">:home</a></li> + <!--<li><a href="/kaurselylehu">:kaurselyle’u</a></li>--> + <li><a href="/programs/">:programs</a></li> + <!--<li><a href="/blog">:blog</a></li>--> + </ul> + </nav> +{{- end -}} diff --git a/templates/pgp.html b/templates/pgp.html new file mode 100644 index 0000000000000000000000000000000000000000..02bc8d4abeee7e20d49423e13014105216017508 --- /dev/null +++ b/templates/pgp.html @@ -0,0 +1,14 @@ +<!DOCTYPE html> +<html lang="en"> + {{ template "head" }} + <body> + {{ template "header" }} + {{ template "nav" }} + <main> + <code><pre> +{{ . }} + </pre></code> + </main> + {{ template "aside" . }} + </body> +</html> diff --git a/templates/program.html b/templates/program.html new file mode 100644 index 0000000000000000000000000000000000000000..404384e84c4138e33037bddfd9e446b47d2718c0 --- /dev/null +++ b/templates/program.html @@ -0,0 +1,18 @@ +<!DOCTYPE html> +<html lang="en"> + {{ template "head_program" . }} + <body> + {{ template "header" }} + {{ template "nav" }} + <main> + <h2>{{.Name}}</h2> + {{if gt (len .Versions) 1}}<ul> + {{range $tag, $_ := .Versions}}<li>{{if $tag}}<a href="/p/{{$.Name}}/{{$tag}}">{{$tag}}</a>{{else}}<a href="/p/{{$.Name}}">v1</a>{{end}}</li>{{end}} + </ul>{{end}} + <code>{{.Source}}</code> + + <div>{{.Content}}</div> + </main> + {{ template "aside" . }} + </body> +</html> diff --git a/templates/programs.html b/templates/programs.html new file mode 100644 index 0000000000000000000000000000000000000000..2837a78d2ce7bb9914ac38339bc274d52521eb32 --- /dev/null +++ b/templates/programs.html @@ -0,0 +1,19 @@ +<!DOCTYPE html> +<html lang="en"> + {{ template "head" }} + <body> + {{ template "header" }} + {{ template "nav" }} + <main> + {{range .}} + <a href="{{.Name}}{{if .DefaultVersion}}/{{.DefaultVersion}}{{end}}" style="text-decoration: none;"> + <section> + <h3>{{.Name}}</h3> + <p>{{.Tldr}}</p> + </section> + </a> + {{end}} + </main> + {{ template "aside" . }} + </body> +</html> diff --git a/templates/s.html b/templates/s.html new file mode 100644 index 0000000000000000000000000000000000000000..863286441c5be4f9653adfb05bba13c71a45379b --- /dev/null +++ b/templates/s.html @@ -0,0 +1,21 @@ +<!DOCTYPE html> +<html lang="en"> + {{ template "head" }} + <body> + {{ template "header" }} + {{ template "nav" }} + <main> + <h1>Redirect</h1> + <form method="POST" > + <label for="url">URL</label> + <input type="url" id="url" name="url" required /> + <label for="password">Password</label> + <input type="password" id="password" name="password" required /> + <label for="id">ID</label> + <input id="id" name="id" /> + <input type="submit" value="create" > + </form> + </main> + {{ template "aside" . }} + </body> +</html> diff --git a/templates/s201.html b/templates/s201.html new file mode 100644 index 0000000000000000000000000000000000000000..832c8725e810e14e2e1cde015aa0372f97238012 --- /dev/null +++ b/templates/s201.html @@ -0,0 +1,13 @@ +<!DOCTYPE html> +<html lang="en"> + {{ template "head" }} + <body> + {{ template "header" }} + {{ template "nav" }} + <main> + <h1>Redirection created</h1> + <p>ID (<code>{{ .ID }}</code>) will redirect to <code>{{ .URL }}</code>.</p> + </main> + {{ template "aside" . }} + </body> +</html> diff --git a/templates/short.html b/templates/short.html new file mode 100644 index 0000000000000000000000000000000000000000..59bc43c7d901696fd97edeb5e82af0d11dfc82a0 --- /dev/null +++ b/templates/short.html @@ -0,0 +1,15 @@ +<!DOCTYPE html> +<html lang="en"> + {{ template "head" }} + <body> + {{ template "header" }} + {{ template "nav" }} + <main> + <h1>Redirection</h1> + <p>This ID (<code>{{ .ID }}</code>) will redirect to <code>{{ .URL }}</code>.</p> + + <button><a href="{{ .URL }}">Yes, take me there »</a></button> + </main> + {{ template "aside" . }} + </body> +</html>