Compare commits
No commits in common. "93716a7f0f7cd5ff98838ac6bff92918a2d9f8f8" and "f0bdfd94433fef8c81ee44e017a2ed1bd80bbe99" have entirely different histories.
93716a7f0f
...
f0bdfd9443
@ -17,11 +17,6 @@ const (
|
||||
actBeer // note prev indicates whether the shell was live
|
||||
actCuff
|
||||
actKnife
|
||||
actAdrenaline
|
||||
actPhone
|
||||
actInverter
|
||||
actPillsHeal
|
||||
actPillsHurt
|
||||
|
||||
actDealerConcedes // dealer concedes
|
||||
actChallengerConcedes // challenger concedes
|
||||
|
@ -19,18 +19,13 @@ func _() {
|
||||
_ = x[actBeer-8]
|
||||
_ = x[actCuff-9]
|
||||
_ = x[actKnife-10]
|
||||
_ = x[actAdrenaline-11]
|
||||
_ = x[actPhone-12]
|
||||
_ = x[actInverter-13]
|
||||
_ = x[actPillsHeal-14]
|
||||
_ = x[actPillsHurt-15]
|
||||
_ = x[actDealerConcedes-16]
|
||||
_ = x[actChallengerConcedes-17]
|
||||
_ = x[actDealerConcedes-11]
|
||||
_ = x[actChallengerConcedes-12]
|
||||
}
|
||||
|
||||
const _action_name = "StartShootGameEndBeerGameEndChallengerWinsDealerWinsLensCigBeerCuffKnifeAdrenalinePhoneInverterPillsHealPillsHurtDealerConcedesChallengerConcedes"
|
||||
const _action_name = "StartShootGameEndBeerGameEndChallengerWinsDealerWinsLensCigBeerCuffKnifeDealerConcedesChallengerConcedes"
|
||||
|
||||
var _action_index = [...]uint8{0, 5, 10, 17, 28, 42, 52, 56, 59, 63, 67, 72, 82, 87, 95, 104, 113, 127, 145}
|
||||
var _action_index = [...]uint8{0, 5, 10, 17, 28, 42, 52, 56, 59, 63, 67, 72, 86, 104}
|
||||
|
||||
func (i action) String() string {
|
||||
if i >= action(len(_action_index)-1) {
|
||||
|
43
game/game.go
43
game/game.go
@ -5,13 +5,12 @@
|
||||
// It ends when the challenger wins three rounds or the dealer wins once.
|
||||
// - A round is an instance of gameplay. Both players start each round with
|
||||
// the same HP, and it continues until either player reaches zero.
|
||||
// - A game is a set of 2-8 shells and 2-5 items delivered to each player.
|
||||
// - A game is a set of 2-8 shells and 1-4 items delivered to each player.
|
||||
// The challenger always moves first at the start of each game.
|
||||
package game
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"math/rand/v2"
|
||||
"time"
|
||||
|
||||
"git.sunturtle.xyz/studio/shotgun/player"
|
||||
@ -19,6 +18,8 @@ import (
|
||||
)
|
||||
|
||||
type Match struct {
|
||||
// rng is the PRNG state used for this match.
|
||||
rng xoshiro
|
||||
// players are the players in the match. The first element is the dealer
|
||||
// and the second is the challenger.
|
||||
players [2]playerState
|
||||
@ -36,9 +37,6 @@ type Match struct {
|
||||
// reveal indicates whether the current player has revealed the shell that
|
||||
// will fire next.
|
||||
reveal bool
|
||||
// adrenaline indicates whether the current player has adrenaline in
|
||||
// effect, requiring them to use an opponent's item.
|
||||
adrenaline bool
|
||||
// prev is a pointer to the element of shellArray which was fired last this
|
||||
// game, or nil if none has been.
|
||||
prev *bool
|
||||
@ -52,6 +50,7 @@ type Match struct {
|
||||
// New creates a new match started at round 1.
|
||||
func New(dealer, challenger player.ID) *Match {
|
||||
g := &Match{
|
||||
rng: newRNG(),
|
||||
players: [2]playerState{
|
||||
{id: dealer},
|
||||
{id: challenger},
|
||||
@ -63,7 +62,7 @@ func New(dealer, challenger player.ID) *Match {
|
||||
|
||||
// NextRound starts the next round of a match.
|
||||
func (g *Match) NextRound() {
|
||||
g.hp = int8(rand.IntN(3) + 2)
|
||||
g.hp = int8(g.rng.Intn(3) + 2)
|
||||
g.players[0].startRound(g.hp)
|
||||
g.players[1].startRound(g.hp)
|
||||
g.round++
|
||||
@ -72,10 +71,10 @@ func (g *Match) NextRound() {
|
||||
|
||||
// NextGame starts the next game of a round.
|
||||
func (g *Match) NextGame() {
|
||||
items := rand.IntN(4) + 2
|
||||
g.players[0].startGame(items)
|
||||
g.players[1].startGame(items)
|
||||
shells := rand.IntN(6) + 2
|
||||
items := g.rng.Intn(4) + 1
|
||||
g.players[0].startGame(&g.rng, items)
|
||||
g.players[1].startGame(&g.rng, items)
|
||||
shells := g.rng.Intn(6) + 2
|
||||
for i := 0; i < shells/2; i++ {
|
||||
g.shellArray[i] = true
|
||||
}
|
||||
@ -83,7 +82,7 @@ func (g *Match) NextGame() {
|
||||
g.shellArray[i] = false
|
||||
}
|
||||
g.shells = g.shellArray[:shells]
|
||||
shuffle(g.shells)
|
||||
shuffle(&g.rng, g.shells)
|
||||
g.turn = 0
|
||||
g.prev = nil
|
||||
g.nextTurn()
|
||||
@ -120,22 +119,17 @@ func (g *Match) Opponent() *playerState {
|
||||
// Apply uses an item by index for the current player.
|
||||
// If this causes the current game to end (a beer discharges the last shell),
|
||||
// returns ErrGameEnded but does not start the next game.
|
||||
// Returns ErrWrongTurn if id does not correspond to the current player
|
||||
// (with appropriate exception for adrenaline).
|
||||
// Returns ErrWrongTurn if id does not correspond to the current player.
|
||||
func (g *Match) Apply(id player.ID, item int) error {
|
||||
p := g.CurrentPlayer()
|
||||
if g.adrenaline {
|
||||
p = g.Opponent()
|
||||
}
|
||||
if p.id != id {
|
||||
cur := g.CurrentPlayer()
|
||||
if cur.id != id {
|
||||
return ErrWrongTurn
|
||||
}
|
||||
if item < 0 || item >= len(p.items) {
|
||||
if item < 0 || item >= len(cur.items) {
|
||||
return errors.New("item index out of bounds")
|
||||
}
|
||||
if p.items[item].apply(g) {
|
||||
p.items[item] = itemNone
|
||||
g.adrenaline = false
|
||||
if cur.items[item].apply(g) {
|
||||
cur.items[item] = itemNone
|
||||
}
|
||||
if g.Empty() {
|
||||
return ErrGameEnded
|
||||
@ -191,11 +185,10 @@ func (g *Match) MatchWinner() *playerState {
|
||||
// player if self is true. Advances the turn if appropriate.
|
||||
// Returns ErrRoundEnded if this causes the round to end.
|
||||
// Returns ErrGameEnded if this causes the game but not the round to end.
|
||||
// Returns ErrWrongTurn if id does not correspond to the current player
|
||||
// or if adrenaline is in effect.
|
||||
// Returns ErrWrongTurn if id does not correspond to the current player.
|
||||
func (g *Match) Shoot(id player.ID, self bool) error {
|
||||
cur := g.CurrentPlayer()
|
||||
if cur.id != id || g.adrenaline {
|
||||
if cur.id != id {
|
||||
return ErrWrongTurn
|
||||
}
|
||||
target := g.Opponent()
|
||||
|
49
game/item.go
49
game/item.go
@ -1,7 +1,5 @@
|
||||
package game
|
||||
|
||||
import "math/rand/v2"
|
||||
|
||||
type item int8
|
||||
|
||||
const (
|
||||
@ -11,14 +9,10 @@ const (
|
||||
itemBeer
|
||||
itemCuff
|
||||
itemKnife
|
||||
itemAdrenaline
|
||||
itemPhone
|
||||
itemInverter
|
||||
itemPill
|
||||
)
|
||||
|
||||
func newItem() item {
|
||||
return item(rand.IntN(9)) + 1
|
||||
func newItem(rng *xoshiro) item {
|
||||
return item(rng.Intn(5)) + 1
|
||||
}
|
||||
|
||||
func (i item) apply(g *Match) bool {
|
||||
@ -61,49 +55,12 @@ func (i item) apply(g *Match) bool {
|
||||
g.action = actKnife
|
||||
g.damage = 2
|
||||
return true
|
||||
case itemAdrenaline:
|
||||
if g.adrenaline {
|
||||
// Adrenaline forbids using adrenaline.
|
||||
return false
|
||||
}
|
||||
g.action = actAdrenaline
|
||||
g.adrenaline = true
|
||||
return true
|
||||
case itemPhone:
|
||||
g.action = actPhone
|
||||
// TODO(zeph): implement
|
||||
return true
|
||||
case itemInverter:
|
||||
g.action = actInverter
|
||||
g.shells[0] = !g.shells[0]
|
||||
return true
|
||||
case itemPill:
|
||||
cur := g.CurrentPlayer()
|
||||
if rand.Uint64() <= (1<<65)/5 {
|
||||
g.action = actPillsHeal
|
||||
cur.hp = min(cur.hp+2, g.hp)
|
||||
} else {
|
||||
g.action = actPillsHurt
|
||||
cur.hp--
|
||||
}
|
||||
return true
|
||||
default:
|
||||
panic("shotgun: unknown item")
|
||||
}
|
||||
}
|
||||
|
||||
var itemNames = [...]string{
|
||||
itemNone: "",
|
||||
itemLens: "🔍",
|
||||
itemCig: "🚬",
|
||||
itemBeer: "🍺",
|
||||
itemCuff: "👮",
|
||||
itemKnife: "🔪",
|
||||
itemAdrenaline: "💉",
|
||||
itemPhone: "📱",
|
||||
itemInverter: "🧲",
|
||||
itemPill: "💊",
|
||||
}
|
||||
var itemNames = [...]string{"", "🔍", "🚬", "🍺", "👮", "🔪"}
|
||||
|
||||
func (i item) String() string {
|
||||
return itemNames[i]
|
||||
|
@ -13,10 +13,6 @@ func TestItemStrings(t *testing.T) {
|
||||
{itemBeer, "🍺"},
|
||||
{itemCuff, "👮"},
|
||||
{itemKnife, "🔪"},
|
||||
{itemAdrenaline, "💉"},
|
||||
{itemPhone, "📱"},
|
||||
{itemInverter, "🧲"},
|
||||
{itemPill, "💊"},
|
||||
}
|
||||
for _, c := range cases {
|
||||
got := c.item.String()
|
||||
|
@ -19,13 +19,13 @@ func (p *playerState) startRound(hp int8) {
|
||||
clear(p.items[:])
|
||||
}
|
||||
|
||||
func (p *playerState) startGame(items int) {
|
||||
func (p *playerState) startGame(rng *xoshiro, items int) {
|
||||
for i := 0; i < items; i++ {
|
||||
k := slices.Index(p.items[:], itemNone)
|
||||
if k < 0 {
|
||||
break
|
||||
}
|
||||
p.items[k] = newItem()
|
||||
p.items[k] = newItem(rng)
|
||||
}
|
||||
p.cuffs = uncuffed
|
||||
}
|
||||
|
61
game/rng.go
61
game/rng.go
@ -1,10 +1,65 @@
|
||||
package game
|
||||
|
||||
import "math/rand/v2"
|
||||
import (
|
||||
"crypto/rand"
|
||||
"encoding/binary"
|
||||
"math/bits"
|
||||
)
|
||||
|
||||
func shuffle[E any, S ~[]E](s S) {
|
||||
// xoshiro is a random number generator for shotgun.
|
||||
//
|
||||
// Currently xoshiro256**. Subject to change.
|
||||
type xoshiro struct {
|
||||
w, x, y, z uint64
|
||||
}
|
||||
|
||||
// newRNG produces a new, uniquely seeded RNG.
|
||||
func newRNG() xoshiro {
|
||||
r := xoshiro{}
|
||||
b := make([]byte, 8*4)
|
||||
// Loop to ensure the state is never all-zero, which is an invalid state
|
||||
// for xoshiro.
|
||||
for r.w == 0 && r.x == 0 && r.y == 0 && r.z == 0 {
|
||||
rand.Read(b)
|
||||
r.w = binary.LittleEndian.Uint64(b)
|
||||
r.x = binary.LittleEndian.Uint64(b[8:])
|
||||
r.y = binary.LittleEndian.Uint64(b[16:])
|
||||
r.z = binary.LittleEndian.Uint64(b[24:])
|
||||
}
|
||||
return r
|
||||
}
|
||||
|
||||
// Uint64 produces a 64-bit pseudo-random value.
|
||||
func (rng *xoshiro) Uint64() uint64 {
|
||||
w, x, y, z := rng.w, rng.x, rng.y, rng.z
|
||||
r := bits.RotateLeft64(x*5, 7) * 9
|
||||
t := x << 17
|
||||
y ^= w
|
||||
z ^= x
|
||||
x ^= y
|
||||
w ^= z
|
||||
y ^= t
|
||||
z = bits.RotateLeft64(z, 45)
|
||||
rng.w, rng.x, rng.y, rng.z = w, x, y, z
|
||||
return r
|
||||
}
|
||||
|
||||
// Intn produces an int in [0, n). Panics if n <= 0.
|
||||
func (rng *xoshiro) Intn(n int) int {
|
||||
if n <= 0 {
|
||||
panic("shotgun: rng.Intn max below zero")
|
||||
}
|
||||
bad := ^uint(0) - ^uint(0)%uint(n)
|
||||
x := uint(rng.Uint64())
|
||||
for x > bad {
|
||||
x = uint(rng.Uint64())
|
||||
}
|
||||
return int(x % uint(n))
|
||||
}
|
||||
|
||||
func shuffle[E any, S ~[]E](rng *xoshiro, s S) {
|
||||
for i := len(s) - 1; i > 0; i-- {
|
||||
j := rand.IntN(i + 1)
|
||||
j := rng.Intn(i + 1)
|
||||
s[i], s[j] = s[j], s[i]
|
||||
}
|
||||
}
|
||||
|
44
go.mod
44
go.mod
@ -1,40 +1,32 @@
|
||||
module git.sunturtle.xyz/studio/shotgun
|
||||
|
||||
go 1.22.2
|
||||
go 1.21.6
|
||||
|
||||
require (
|
||||
github.com/go-chi/chi/v5 v5.0.12
|
||||
github.com/google/uuid v1.6.0
|
||||
github.com/go-chi/chi/v5 v5.0.11
|
||||
github.com/google/uuid v1.5.0
|
||||
gitlab.com/zephyrtronium/sq v1.0.1
|
||||
golang.org/x/crypto v0.22.0
|
||||
modernc.org/sqlite v1.29.5
|
||||
nhooyr.io/websocket v1.8.11
|
||||
golang.org/x/crypto v0.18.0
|
||||
modernc.org/sqlite v1.28.0
|
||||
nhooyr.io/websocket v1.8.10
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/dustin/go-humanize v1.0.1 // indirect
|
||||
github.com/hashicorp/golang-lru/v2 v2.0.7 // indirect
|
||||
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 // indirect
|
||||
github.com/mattn/go-isatty v0.0.20 // indirect
|
||||
github.com/ncruces/go-strftime v0.1.9 // indirect
|
||||
github.com/mattn/go-isatty v0.0.16 // indirect
|
||||
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect
|
||||
golang.org/x/mod v0.17.0 // indirect
|
||||
golang.org/x/sync v0.7.0 // indirect
|
||||
golang.org/x/sys v0.19.0 // indirect
|
||||
golang.org/x/tools v0.20.0 // indirect
|
||||
golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028 // indirect
|
||||
lukechampine.com/uint128 v1.3.0 // indirect
|
||||
modernc.org/cc/v3 v3.41.0 // indirect
|
||||
modernc.org/cc/v4 v4.20.0 // indirect
|
||||
modernc.org/ccgo/v3 v3.17.0 // indirect
|
||||
modernc.org/ccgo/v4 v4.16.0 // indirect
|
||||
modernc.org/gc/v2 v2.4.1 // indirect
|
||||
modernc.org/gc/v3 v3.0.0-20240107210532-573471604cb6 // indirect
|
||||
modernc.org/libc v1.49.2 // indirect
|
||||
golang.org/x/mod v0.3.0 // indirect
|
||||
golang.org/x/sys v0.16.0 // indirect
|
||||
golang.org/x/tools v0.0.0-20201124115921-2c860bdd6e78 // indirect
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect
|
||||
lukechampine.com/uint128 v1.2.0 // indirect
|
||||
modernc.org/cc/v3 v3.40.0 // indirect
|
||||
modernc.org/ccgo/v3 v3.16.13 // indirect
|
||||
modernc.org/libc v1.29.0 // indirect
|
||||
modernc.org/mathutil v1.6.0 // indirect
|
||||
modernc.org/memory v1.8.0 // indirect
|
||||
modernc.org/memory v1.7.2 // indirect
|
||||
modernc.org/opt v0.1.3 // indirect
|
||||
modernc.org/sortutil v1.2.0 // indirect
|
||||
modernc.org/strutil v1.2.0 // indirect
|
||||
modernc.org/token v1.1.0 // indirect
|
||||
modernc.org/strutil v1.1.3 // indirect
|
||||
modernc.org/token v1.0.1 // indirect
|
||||
)
|
||||
|
51
go.sum
51
go.sum
@ -2,28 +2,18 @@ github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkp
|
||||
github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto=
|
||||
github.com/go-chi/chi/v5 v5.0.11 h1:BnpYbFZ3T3S1WMpD79r7R5ThWX40TaFB7L31Y8xqSwA=
|
||||
github.com/go-chi/chi/v5 v5.0.11/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8=
|
||||
github.com/go-chi/chi/v5 v5.0.12 h1:9euLV5sTrTNTRUU9POmDUvfxyj6LAABLUcEWO+JJb4s=
|
||||
github.com/go-chi/chi/v5 v5.0.12/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8=
|
||||
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
|
||||
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||
github.com/google/pprof v0.0.0-20221118152302-e6195bd50e26 h1:Xim43kblpZXfIBQsbuBVKCudVG457BR2GZFIz3uw3hQ=
|
||||
github.com/google/pprof v0.0.0-20221118152302-e6195bd50e26/go.mod h1:dDKJzRmX4S37WGHujM7tX//fmj1uioxKzKxz3lo4HJo=
|
||||
github.com/google/uuid v1.5.0 h1:1p67kYwdtXjb0gL0BPiP1Av9wiZPo5A8z2cWkTZ+eyU=
|
||||
github.com/google/uuid v1.5.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
|
||||
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/hashicorp/golang-lru/v2 v2.0.7 h1:a+bsQ5rvGLjzHuww6tVxozPZFVghXaHOwFs4luLUK2k=
|
||||
github.com/hashicorp/golang-lru/v2 v2.0.7/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM=
|
||||
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 h1:Z9n2FFNUXsshfwJMBgNA0RU6/i7WVaAegv3PtuIHPMs=
|
||||
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51/go.mod h1:CzGEWj7cYgsdH8dAjBGEr58BoE7ScuLd+fwFZ44+/x8=
|
||||
github.com/mattn/go-isatty v0.0.16 h1:bq3VjFmv/sOjHtdEhmkEV4x1AJtvUvOJ2PFAZ5+peKQ=
|
||||
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
|
||||
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
|
||||
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
|
||||
github.com/mattn/go-sqlite3 v1.14.16 h1:yOQRA0RpS5PFz/oikGwBEqvAWhWg5ufRz4ETLjwpU1Y=
|
||||
github.com/mattn/go-sqlite3 v1.14.16/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg=
|
||||
github.com/ncruces/go-strftime v0.1.9 h1:bY0MQC28UADQmHmaF5dgpLmImcShSi2kHU9XLdhx/f4=
|
||||
github.com/ncruces/go-strftime v0.1.9/go.mod h1:Fwc5htZGVVkseilnfgOVb9mKy6w1naJmn9CehxcKcls=
|
||||
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/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec h1:W09IVJc94icq4NjY3clb7Lk8O1qJ8BdBEF8z0ibU0rE=
|
||||
@ -36,97 +26,56 @@ golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8U
|
||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.18.0 h1:PGVlW0xEltQnzFZ55hkuX5+KLyrMYhHld1YHO4AKcdc=
|
||||
golang.org/x/crypto v0.18.0/go.mod h1:R0j02AL6hcrfOiy9T4ZYp/rcWeMxM3L6QYxlOuEG1mg=
|
||||
golang.org/x/crypto v0.22.0 h1:g1v0xeRhjcugydODzvb3mEM9SQ0HGp9s/nh3COQ/C30=
|
||||
golang.org/x/crypto v0.22.0/go.mod h1:vr6Su+7cTlO45qkww3VDJlzDn0ctJvRgYbC2NvXHt+M=
|
||||
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/mod v0.17.0 h1:zY54UmvipHiNd+pm+m0x9KhZ9hl1/7QNMyxXbc6ICqA=
|
||||
golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
|
||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M=
|
||||
golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.16.0 h1:xWw16ngr6ZMtmxDyKyIgsE93KNKz5HKmMa3b8ALHidU=
|
||||
golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.19.0 h1:q5f1RH2jigJ1MoAWp2KTp3gm5zAGFUTarQZ5U386+4o=
|
||||
golang.org/x/sys v0.19.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20201124115921-2c860bdd6e78 h1:M8tBwCtWD/cZV9DZpFYRUgaymAYAr+aIUTWzDaM3uPs=
|
||||
golang.org/x/tools v0.0.0-20201124115921-2c860bdd6e78/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/tools v0.20.0 h1:hz/CVckiOxybQvFw6h7b/q80NTr9IUQb4s1IIzW7KNY=
|
||||
golang.org/x/tools v0.20.0/go.mod h1:WvitBU7JJf6A4jOdg4S1tviW9bhUxkgeCui/0JHctQg=
|
||||
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-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028 h1:+cNy6SZtPcJQH3LJVLOSmiC7MMxXNOb3PU/VUEz+EhU=
|
||||
golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028/go.mod h1:NDW/Ps6MPRej6fsCIbMTohpP40sJ/P/vI1MoTEGwX90=
|
||||
lukechampine.com/uint128 v1.2.0 h1:mBi/5l91vocEN8otkC5bDLhi2KdCticRiwbdB0O+rjI=
|
||||
lukechampine.com/uint128 v1.2.0/go.mod h1:c4eWIwlEGaxC/+H1VguhU4PHXNWDCDMUlWdIWl2j1gk=
|
||||
lukechampine.com/uint128 v1.3.0 h1:cDdUVfRwDUDovz610ABgFD17nXD4/uDgVHl2sC3+sbo=
|
||||
lukechampine.com/uint128 v1.3.0/go.mod h1:c4eWIwlEGaxC/+H1VguhU4PHXNWDCDMUlWdIWl2j1gk=
|
||||
modernc.org/cc/v3 v3.40.0 h1:P3g79IUS/93SYhtoeaHW+kRCIrYaxJ27MFPv+7kaTOw=
|
||||
modernc.org/cc/v3 v3.40.0/go.mod h1:/bTg4dnWkSXowUO6ssQKnOV0yMVxDYNIsIrzqTFDGH0=
|
||||
modernc.org/cc/v3 v3.41.0 h1:QoR1Sn3YWlmA1T4vLaKZfawdVtSiGx8H+cEojbC7v1Q=
|
||||
modernc.org/cc/v3 v3.41.0/go.mod h1:Ni4zjJYJ04CDOhG7dn640WGfwBzfE0ecX8TyMB0Fv0Y=
|
||||
modernc.org/cc/v4 v4.20.0 h1:45Or8mQfbUqJOG9WaxvlFYOAQO0lQ5RvqBcFCXngjxk=
|
||||
modernc.org/cc/v4 v4.20.0/go.mod h1:HM7VJTZbUCR3rV8EYBi9wxnJ0ZBRiGE5OeGXNA0IsLQ=
|
||||
modernc.org/ccgo/v3 v3.16.13 h1:Mkgdzl46i5F/CNR/Kj80Ri59hC8TKAhZrYSaqvkwzUw=
|
||||
modernc.org/ccgo/v3 v3.16.13/go.mod h1:2Quk+5YgpImhPjv2Qsob1DnZ/4som1lJTodubIcoUkY=
|
||||
modernc.org/ccgo/v3 v3.17.0 h1:o3OmOqx4/OFnl4Vm3G8Bgmqxnvxnh0nbxeT5p/dWChA=
|
||||
modernc.org/ccgo/v3 v3.17.0/go.mod h1:Sg3fwVpmLvCUTaqEUjiBDAvshIaKDB0RXaf+zgqFu8I=
|
||||
modernc.org/ccgo/v4 v4.16.0 h1:ofwORa6vx2FMm0916/CkZjpFPSR70VwTjUCe2Eg5BnA=
|
||||
modernc.org/ccgo/v4 v4.16.0/go.mod h1:dkNyWIjFrVIZ68DTo36vHK+6/ShBn4ysU61So6PIqCI=
|
||||
modernc.org/ccorpus v1.11.6 h1:J16RXiiqiCgua6+ZvQot4yUuUy8zxgqbqEEUuGPlISk=
|
||||
modernc.org/ccorpus v1.11.6/go.mod h1:2gEUTrWqdpH2pXsmTM1ZkjeSrUWDpjMu2T6m29L/ErQ=
|
||||
modernc.org/gc/v2 v2.4.1 h1:9cNzOqPyMJBvrUipmynX0ZohMhcxPtMccYgGOJdOiBw=
|
||||
modernc.org/gc/v2 v2.4.1/go.mod h1:wzN5dK1AzVGoH6XOzc3YZ+ey/jPgYHLuVckd62P0GYU=
|
||||
modernc.org/gc/v3 v3.0.0-20240107210532-573471604cb6 h1:5D53IMaUuA5InSeMu9eJtlQXS2NxAhyWQvkKEgXZhHI=
|
||||
modernc.org/gc/v3 v3.0.0-20240107210532-573471604cb6/go.mod h1:Qz0X07sNOR1jWYCrJMEnbW/X55x206Q7Vt4mz6/wHp4=
|
||||
modernc.org/httpfs v1.0.6 h1:AAgIpFZRXuYnkjftxTAZwMIiwEqAfk8aVB2/oA6nAeM=
|
||||
modernc.org/httpfs v1.0.6/go.mod h1:7dosgurJGp0sPaRanU53W4xZYKh14wfzX420oZADeHM=
|
||||
modernc.org/libc v1.29.0 h1:tTFRFq69YKCF2QyGNuRUQxKBm1uZZLubf6Cjh/pVHXs=
|
||||
modernc.org/libc v1.29.0/go.mod h1:DaG/4Q3LRRdqpiLyP0C2m1B8ZMGkQ+cCgOIjEtQlYhQ=
|
||||
modernc.org/libc v1.49.2 h1:Orwx0/7S7n5GCug2ANrqW0e7ZBu1mteep7xFkZCNydk=
|
||||
modernc.org/libc v1.49.2/go.mod h1:yMZuGkn7pXbKfoT/M35gFJOAEdSKdxL0q64sF7KqCDo=
|
||||
modernc.org/mathutil v1.6.0 h1:fRe9+AmYlaej+64JsEEhoWuAYBkOtQiMEU7n/XgfYi4=
|
||||
modernc.org/mathutil v1.6.0/go.mod h1:Ui5Q9q1TR2gFm0AQRqQUaBWFLAhQpCwNcuhBOSedWPo=
|
||||
modernc.org/memory v1.7.2 h1:Klh90S215mmH8c9gO98QxQFsY+W451E8AnzjoE2ee1E=
|
||||
modernc.org/memory v1.7.2/go.mod h1:NO4NVCQy0N7ln+T9ngWqOQfi7ley4vpwvARR+Hjw95E=
|
||||
modernc.org/memory v1.8.0 h1:IqGTL6eFMaDZZhEWwcREgeMXYwmW83LYW8cROZYkg+E=
|
||||
modernc.org/memory v1.8.0/go.mod h1:XPZ936zp5OMKGWPqbD3JShgd/ZoQ7899TUuQqxY+peU=
|
||||
modernc.org/opt v0.1.3 h1:3XOZf2yznlhC+ibLltsDGzABUGVx8J6pnFMS3E4dcq4=
|
||||
modernc.org/opt v0.1.3/go.mod h1:WdSiB5evDcignE70guQKxYUl14mgWtbClRi5wmkkTX0=
|
||||
modernc.org/sortutil v1.2.0 h1:jQiD3PfS2REGJNzNCMMaLSp/wdMNieTbKX920Cqdgqc=
|
||||
modernc.org/sortutil v1.2.0/go.mod h1:TKU2s7kJMf1AE84OoiGppNHJwvB753OYfNl2WRb++Ss=
|
||||
modernc.org/sqlite v1.28.0 h1:Zx+LyDDmXczNnEQdvPuEfcFVA2ZPyaD7UCZDjef3BHQ=
|
||||
modernc.org/sqlite v1.28.0/go.mod h1:Qxpazz0zH8Z1xCFyi5GSL3FzbtZ3fvbjmywNogldEW0=
|
||||
modernc.org/sqlite v1.29.5 h1:8l/SQKAjDtZFo9lkJLdk8g9JEOeYRG4/ghStDCCTiTE=
|
||||
modernc.org/sqlite v1.29.5/go.mod h1:S02dvcmm7TnTRvGhv8IGYyLnIt7AS2KPaB1F/71p75U=
|
||||
modernc.org/strutil v1.1.3 h1:fNMm+oJklMGYfU9Ylcywl0CO5O6nTfaowNsh2wpPjzY=
|
||||
modernc.org/strutil v1.1.3/go.mod h1:MEHNA7PdEnEwLvspRMtWTNnp2nnyvMfkimT1NKNAGbw=
|
||||
modernc.org/strutil v1.2.0 h1:agBi9dp1I+eOnxXeiZawM8F4LawKv4NzGWSaLfyeNZA=
|
||||
modernc.org/strutil v1.2.0/go.mod h1:/mdcBmfOibveCTBxUl5B5l6W+TTH1FXPLHZE6bTosX0=
|
||||
modernc.org/tcl v1.15.2 h1:C4ybAYCGJw968e+Me18oW55kD/FexcHbqH2xak1ROSY=
|
||||
modernc.org/tcl v1.15.2/go.mod h1:3+k/ZaEbKrC8ePv8zJWPtBSW0V7Gg9g8rkmhI1Kfs3c=
|
||||
modernc.org/token v1.0.1 h1:A3qvTqOwexpfZZeyI0FeGPDlSWX5pjZu9hF4lU+EKWg=
|
||||
modernc.org/token v1.0.1/go.mod h1:UGzOrNV1mAFSEB63lOFHIpNRUVMvYTc6yu1SMY/XTDM=
|
||||
modernc.org/token v1.1.0 h1:Xl7Ap9dKaEs5kLoOQeQmPWevfnk/DM5qcLcYlA8ys6Y=
|
||||
modernc.org/token v1.1.0/go.mod h1:UGzOrNV1mAFSEB63lOFHIpNRUVMvYTc6yu1SMY/XTDM=
|
||||
modernc.org/z v1.7.3 h1:zDJf6iHjrnB+WRD88stbXokugjyc0/pB91ri1gO6LZY=
|
||||
modernc.org/z v1.7.3/go.mod h1:Ipv4tsdxZRbQyLq9Q1M6gdbkxYzdlrciF2Hi/lS7nWE=
|
||||
nhooyr.io/websocket v1.8.10 h1:mv4p+MnGrLDcPlBoWsvPP7XCzTYMXP9F9eIGoKbgx7Q=
|
||||
nhooyr.io/websocket v1.8.10/go.mod h1:rN9OFWIUwuxg4fR5tELlYC04bXYowCP9GX47ivo2l+c=
|
||||
nhooyr.io/websocket v1.8.11 h1:f/qXNc2/3DpoSZkHt1DQu6rj4zGC8JmkkLkWss0MgN0=
|
||||
nhooyr.io/websocket v1.8.11/go.mod h1:rN9OFWIUwuxg4fR5tELlYC04bXYowCP9GX47ivo2l+c=
|
||||
|
Loading…
Reference in New Issue
Block a user