6 Commits

35 changed files with 1106 additions and 192 deletions

51
TODO.md
View File

@@ -1,9 +1,10 @@
## Levels: ## Levels:
- use first line as background image name
- ignore comments in lvl files - ignore comments in lvl files
- check when sphere bounces from one end to the other endlessly w/o - check when sphere bounces from one end to the other endlessly w/o
any solids in between. this is a game lock and equals game over any solids in between. this is a game lock and equals game over
- Start the game end timer and add a score FIXME: put the actual max - Start the game end timer and add a score FIXME: put the actual max
reachable score into the level definition along with the minimum reachable score into the level definition along with the minimum
steps required to reach it, also add a step counter steps required to reach it, also add a step counter
@@ -11,25 +12,35 @@
- Grid Observer: - Grid Observer:
https://github.com/mlange-42/arche/issues/374 https://github.com/mlange-42/arche/issues/374
Screenshot:
Yes, since *ebiten.Image implements the standard image.Image interface
I just made a screenshot example (in Draw() function):
if inpututil.IsKeyJustPressed(ebiten.KeyS) {
f, err := os.Create("screenshot.png")
if err != nil {
log.Fatal("can't create file: ", err)
}
png.Encode(f, screen)
}
- Add some final message when the player reaches the last level, start - Add some final message when the player reaches the last level, start
from scratch or a message to buy me some beer, whatever from scratch or a message to buy me some beer, whatever
- Calculate obstacle collision the same as solid collision with future - Check player-player collisions!
velocity and included snap in so that the player ends up right on
the edge of the obstacle and not inside as it is now - Add player mergers, possibly as an option, so maybe we could have
different primary and secondary players: one pair can merge, the
- Check player-player collisions! other not. Like S + s and M + m or something.
- Add shaders for animation (player destruction etc)
- Add player HUD + Stats (as hud_system!)
## Collider Rework
- do not use the map anymore for collision detection
- central collision_system
- add Collider component with callback funcs to call on certain events
- callback types:
- rect intersect (== future collision)
- collision resolve (set new position)
- pass over foreign rect (to e.g. change sprite while flying over sprite)
- pass over done (switch sprite)
- check for all moving objects against non-moving ones like moving
obstacle, player, bullet, laser
- check if executing callbacks within query loop is allowed
- callback function needs to be able to modify other components, so
possibly use observers for them, e.g.:
Collider.IntersectResolve => func(newpos) {player.pos = newpos; player.vel = stop}
- in the end it must be possible to add new entities without the need
to write a collision check for them, but have collision detection anyway!

View File

@@ -4,7 +4,7 @@ Background: background-lila
####### #######
# # #o #
# t # # t #
#> S <# #> S <#
# # # #

View File

@@ -4,11 +4,11 @@ Background: background-lila
############# #############
# # # t #
#> S # # #> S # #
# ># ># # ># ^#
#< # # #< #W#####
# v# <# # o v# o#
############# #############

View File

@@ -4,13 +4,13 @@ Background: background-lila
########## ########W#
# v# # v #
# # # #
#S s# #S s#
# # ############
#^ # # o #
########## ######## #

View File

@@ -0,0 +1,17 @@
Description: space
Background: background-lila
#
S
#

View File

@@ -25,18 +25,42 @@ type Tile struct {
Id byte Id byte
Sprite *ebiten.Image Sprite *ebiten.Image
Class string Class string
Solid bool Solid bool // wall brick
Player bool Player bool // player sphere
IsPrimary bool IsPrimary bool // primary player sphere
Renderable bool Renderable bool // visible, has sprite
Velocity bool Velocity bool // movable
Collectible bool Collectible bool // collectible, vanishes once collected
Transient bool Transient bool // turns into brick wall when traversed
Particle int // -1=unused, 0-3 = show image of slice Destroyable bool // turns into empty floor when bumped into twice
Tiles []*ebiten.Image Particle int // -1=unused, 0-3 = show image of slice
TileNames []string // same thing, only the names Tiles []*ebiten.Image // has N sprites
Obstacle bool TileNames []string // same thing, only the names
Direction int // obstacles Obstacle bool // is an obstacle/enemy
Direction int // obstacle business end shows into this direction
}
func (tile *Tile) Clone() *Tile {
newtile := &Tile{
Id: tile.Id,
Sprite: tile.Sprite,
Class: tile.Class,
Solid: tile.Solid,
Player: tile.Player,
IsPrimary: tile.IsPrimary,
Renderable: tile.Renderable,
Velocity: tile.Velocity,
Collectible: tile.Collectible,
Transient: tile.Transient,
Destroyable: tile.Destroyable,
Particle: tile.Particle,
Tiles: tile.Tiles,
TileNames: tile.TileNames,
Obstacle: tile.Obstacle,
Direction: tile.Direction,
}
return newtile
} }
const ( const (
@@ -128,7 +152,7 @@ func NewTileTranswall(class []string) *Tile {
} }
return &Tile{ return &Tile{
Id: '*', Id: 't',
Class: "transwall", Class: "transwall",
Solid: false, Solid: false,
Renderable: true, Renderable: true,
@@ -139,6 +163,27 @@ func NewTileTranswall(class []string) *Tile {
} }
} }
func NewTileHiddenDoor(class []string) *Tile {
sprites := []*ebiten.Image{}
names := []string{}
for _, sprite := range class {
sprites = append(sprites, Assets[sprite])
names = append(names, sprite)
}
return &Tile{
Id: 'W',
Class: "hiddendoor",
Solid: false,
Renderable: true,
Destroyable: true,
Tiles: sprites,
Sprite: sprites[0], // initially use the first
TileNames: names,
}
}
// used to map level data bytes to actual tiles // used to map level data bytes to actual tiles
type TileRegistry map[byte]*Tile type TileRegistry map[byte]*Tile
@@ -164,7 +209,8 @@ type RawLevel struct {
func InitTiles() TileRegistry { func InitTiles() TileRegistry {
return TileRegistry{ return TileRegistry{
' ': {Id: ' ', Class: "floor", Renderable: false}, ' ': {Id: ' ', Class: "floor", Renderable: false},
'#': NewTileBlock("block-grey32"), //'#': NewTileBlock("block-grey32"),
'#': NewTileBlock("block-greycolored"),
'B': NewTileBlock("block-orange-32"), 'B': NewTileBlock("block-orange-32"),
'S': NewTilePlayer(Primary), 'S': NewTilePlayer(Primary),
's': NewTilePlayer(Secondary), 's': NewTilePlayer(Secondary),
@@ -183,6 +229,7 @@ func InitTiles() TileRegistry {
"particle-ring-6", "particle-ring-6",
}), }),
't': NewTileTranswall([]string{"transwall", "block-orange-32"}), 't': NewTileTranswall([]string{"transwall", "block-orange-32"}),
'W': NewTileHiddenDoor([]string{"block-greycolored", "block-greycolored-damaged"}),
} }
} }

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.7 KiB

BIN
assets/sprites/hud.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

14
components/collider.go Normal file
View File

@@ -0,0 +1,14 @@
package components
import "github.com/mlange-42/arche/ecs"
// if the function returns true, the entity will be removed. The
// supplied entity is the target entitiy with which the checked one
// collided.
type Collider struct {
CollisionHandler func(*ecs.World, *Position, *Position, *Velocity, ecs.Entity) bool
EdgeHandler func(*ecs.World, *Position, *Position, *Velocity, ecs.Entity) bool
PassoverHandler func(*ecs.World, *Position, *Velocity, *ecs.Entity) bool
PassoverFinishedHandler func(*ecs.World, *Position, *Velocity, *ecs.Entity) bool
}

View File

@@ -16,10 +16,6 @@ type Particle struct {
Tiles []*ebiten.Image Tiles []*ebiten.Image
} }
type Speed struct {
Value int
}
// only tile entities will have those // only tile entities will have those
type Tilish struct{} type Tilish struct{}
type Solid struct{} type Solid struct{}

29
components/destroyable.go Normal file
View File

@@ -0,0 +1,29 @@
package components
import (
"log"
"github.com/hajimehoshi/ebiten/v2"
)
// A hidden door in a wall. If the player bumps into it once, it shows
// damage and it vanishes the next time.
type Destroyable struct {
Activated bool
Sprites []*ebiten.Image
Current int // sprite index
}
func (door *Destroyable) GetNext() *ebiten.Image {
if len(door.Sprites) > door.Current {
door.Current++
return door.Sprites[door.Current]
}
log.Fatalf("not enough sprites in transient tile, have %d sprites, index requested: %d",
len(door.Sprites), door.Current+1,
)
return nil
}

View File

@@ -34,7 +34,8 @@ func NewPosition(point image.Point, cellsize int) *Position {
func (position *Position) GetMoved(velosity *Velocity) *Position { func (position *Position) GetMoved(velosity *Velocity) *Position {
pos := &Position{} pos := &Position{}
pos.Update(position.X+velosity.Data.X, position.Y+velosity.Data.Y, position.Cellsize) pos.Update(position.X+(velosity.Data.X*velosity.Speed),
position.Y+(velosity.Data.Y*velosity.Speed), position.Cellsize)
return pos return pos
} }
@@ -70,13 +71,13 @@ func (position *Position) String() string {
) )
} }
func (position *Position) Move(velocity *Velocity, speed *Speed) { func (position *Position) Move(velocity *Velocity) {
// if velocity.Direction != 0 { // if velocity.Direction != 0 {
// slog.Debug("moving", "velocity", velocity, "speed", speed) // slog.Debug("moving", "velocity", velocity, "speed", speed)
// } // }
position.Update( position.Update(
position.X+(velocity.Data.X*speed.Value), position.X+(velocity.Data.X*velocity.Speed),
position.Y+(velocity.Data.Y*speed.Value), position.Y+(velocity.Data.Y*velocity.Speed),
) )
} }

View File

@@ -9,6 +9,7 @@ type Velocity struct {
Data Position Data Position
Direction int Direction int
PointingAt int PointingAt int
Speed int
} }
func (velocity *Velocity) Set(new *Velocity) { func (velocity *Velocity) Set(new *Velocity) {

77
config/config.go Normal file
View File

@@ -0,0 +1,77 @@
package config
import (
"fmt"
"os"
"strconv"
"strings"
"github.com/knadh/koanf"
"github.com/knadh/koanf/providers/env"
"github.com/knadh/koanf/providers/posflag"
flag "github.com/spf13/pflag"
)
const Usage string = `openquell [options]
-t --tps <ticks> Set ticks per second, default 60.
-d --debug Enable debugging output.
`
type Config struct {
TPS int `koanf:"tps"`
Loglevel string `koanf:"loglevel"`
Debug bool `koanf:"debug"` // loglevel=debug
Startlevel int
}
func InitConfig() (*Config, error) {
var kloader = koanf.New(".")
flagset := flag.NewFlagSet("config", flag.ContinueOnError)
flagset.BoolP("debug", "d", false, "enable debug log")
flagset.Usage = func() {
fmt.Println(Usage)
os.Exit(0)
}
flagset.IntP("tps", "t", 0, "TPS")
if err := flagset.Parse(os.Args[1:]); err != nil {
return nil, fmt.Errorf("failed to parse program arguments: %w", err)
}
if err := kloader.Load(env.Provider("OC_", ".", func(s string) string {
return strings.ReplaceAll(strings.ToLower(
strings.TrimPrefix(s, "OC_")), "_", ".")
}), nil); err != nil {
return nil, fmt.Errorf("error loading environment: %w", err)
}
if err := kloader.Load(posflag.Provider(flagset, ".", kloader), nil); err != nil {
return nil, fmt.Errorf("error loading flags: %w", err)
}
conf := &Config{}
if err := kloader.Unmarshal("", &conf); err != nil {
return nil, fmt.Errorf("error unmarshalling: %w", err)
}
switch conf.Loglevel {
case "debug":
conf.Debug = true
}
// are there any args left on commandline? if so threat them as adlinks
if len(flagset.Args()) > 0 {
level, err := strconv.Atoi(flagset.Args()[0])
if err != nil {
return nil, fmt.Errorf("failed to parse start level: %w", err)
}
conf.Startlevel = level
}
return conf, nil
}

View File

@@ -4,6 +4,7 @@ import (
"fmt" "fmt"
"image" "image"
"log/slog" "log/slog"
"openquell/config"
"openquell/observers" "openquell/observers"
"github.com/hajimehoshi/ebiten/v2" "github.com/hajimehoshi/ebiten/v2"
@@ -18,9 +19,10 @@ type Game struct {
CurrentScene SceneName CurrentScene SceneName
Observer *observers.GameObserver Observer *observers.GameObserver
Levels []*Level // needed to feed select_scene Levels []*Level // needed to feed select_scene
Config *config.Config
} }
func NewGame(width, height, cellsize, startlevel int, startscene SceneName) *Game { func NewGame(width, height, cellsize int, cfg *config.Config, startscene SceneName) *Game {
world := ecs.NewWorld() world := ecs.NewWorld()
game := &Game{ game := &Game{
@@ -30,18 +32,20 @@ func NewGame(width, height, cellsize, startlevel int, startscene SceneName) *Gam
ScreenHeight: height, ScreenHeight: height,
Scenes: map[SceneName]Scene{}, Scenes: map[SceneName]Scene{},
Cellsize: cellsize, Cellsize: cellsize,
Config: cfg,
} }
observers.NewPlayerObserver(&world) observers.NewPlayerObserver(&world)
observers.NewParticleObserver(&world) observers.NewParticleObserver(&world)
observers.NewObstacleObserver(&world) observers.NewObstacleObserver(&world)
game.Observer = observers.NewGameObserver(&world, startlevel, width, height, cellsize) observers.NewEntityObserver(&world)
game.Observer = observers.NewGameObserver(&world, cfg.Startlevel, width, height, cellsize)
game.Scenes[Welcome] = NewWelcomeScene(game) game.Scenes[Welcome] = NewWelcomeScene(game)
game.Scenes[Menu] = NewMenuScene(game) game.Scenes[Menu] = NewMenuScene(game)
game.Scenes[About] = NewAboutScene(game) game.Scenes[About] = NewAboutScene(game)
game.Scenes[Popup] = NewPopupScene(game) game.Scenes[Popup] = NewPopupScene(game)
game.Scenes[Play] = NewLevelScene(game, startlevel) game.Scenes[Play] = NewLevelScene(game, cfg.Startlevel)
game.Scenes[Select] = NewSelectScene(game) game.Scenes[Select] = NewSelectScene(game)
game.CurrentScene = startscene game.CurrentScene = startscene
@@ -96,7 +100,6 @@ func (game *Game) Update() error {
if next == Play { if next == Play {
// fresh setup of actual level every time we enter the play scene // fresh setup of actual level every time we enter the play scene
//game.Scenes[Play] = NewLevelScene(game, gameobserver.CurrentLevel)
game.Scenes[Play].SetLevel(gameobserver.CurrentLevel) game.Scenes[Play].SetLevel(gameobserver.CurrentLevel)
} }

View File

@@ -1,10 +1,12 @@
package game package game
import ( import (
"fmt"
"log/slog" "log/slog"
"openquell/assets" "openquell/assets"
"github.com/hajimehoshi/ebiten/v2" "github.com/hajimehoshi/ebiten/v2"
"github.com/hajimehoshi/ebiten/v2/ebitenutil"
) )
type LevelScene struct { type LevelScene struct {
@@ -69,12 +71,23 @@ func (scene *LevelScene) Update() error {
} }
func (scene *LevelScene) Draw(screen *ebiten.Image) { func (scene *LevelScene) Draw(screen *ebiten.Image) {
// FIXME: why not in Update() ?!?!?!
if scene.CurrentLevel != scene.Game.Observer.CurrentLevel { if scene.CurrentLevel != scene.Game.Observer.CurrentLevel {
slog.Debug("level", "current", scene.CurrentLevel, slog.Debug("level", "current", scene.CurrentLevel,
"next", scene.Game.Observer.CurrentLevel) "next", scene.Game.Observer.CurrentLevel)
scene.CurrentLevel = scene.Game.Observer.CurrentLevel scene.CurrentLevel = scene.Game.Observer.CurrentLevel
scene.Levels[scene.CurrentLevel].SetupGrid(scene.Game) scene.Levels[scene.CurrentLevel].SetupGrid(scene.Game)
} }
screen.Clear() screen.Clear()
scene.Levels[scene.CurrentLevel].Draw(screen) scene.Levels[scene.CurrentLevel].Draw(screen)
// FIXME: put into hud_system
op := &ebiten.DrawImageOptions{}
screen.DrawImage(assets.Assets["hud"], op)
ebitenutil.DebugPrintAt(screen, fmt.Sprintf(
"FPS: %02.f TPS: %02.f",
ebiten.ActualFPS(),
ebiten.ActualTPS(),
), 10, 10)
} }

View File

@@ -3,6 +3,7 @@ package game
import ( import (
"image" "image"
"log" "log"
"log/slog"
"openquell/assets" "openquell/assets"
"openquell/components" "openquell/components"
"openquell/grid" "openquell/grid"
@@ -15,12 +16,16 @@ import (
"github.com/mlange-42/arche/ecs" "github.com/mlange-42/arche/ecs"
) )
type Map map[image.Point]*assets.Tile
type BackupMap map[image.Point]assets.Tile
type Level struct { type Level struct {
Cellsize, Width, Height int Cellsize, Width, Height int
World *ecs.World World *ecs.World
Name string Name string
Description string Description string
Mapslice map[image.Point]*assets.Tile Mapslice Map
BackupMapslice Map
GridContainer *grid.GridContainer GridContainer *grid.GridContainer
Systems []systems.System Systems []systems.System
Grid *grid.Grid Grid *grid.Grid
@@ -36,6 +41,9 @@ func NewLevel(game *Game, cellsize int, plan *assets.RawLevel) *Level {
systemlist = append(systemlist, systems.NewCollectibleSystem(game.World)) systemlist = append(systemlist, systems.NewCollectibleSystem(game.World))
systemlist = append(systemlist,
systems.NewCollisionSystem(game.World, gridcontainer))
systemlist = append(systemlist, systemlist = append(systemlist,
systems.NewPlayerSystem(game.World, gridcontainer)) systems.NewPlayerSystem(game.World, gridcontainer))
@@ -45,16 +53,21 @@ func NewLevel(game *Game, cellsize int, plan *assets.RawLevel) *Level {
systemlist = append(systemlist, systems.NewTransientSystem(game.World, gridcontainer)) systemlist = append(systemlist, systems.NewTransientSystem(game.World, gridcontainer))
systemlist = append(systemlist, systems.NewDestroyableSystem(game.World, gridcontainer))
mapslice, backupmap := LevelToSlice(game, plan, cellsize)
return &Level{ return &Level{
Mapslice: LevelToSlice(game, plan, cellsize), Mapslice: mapslice,
Cellsize: cellsize, BackupMapslice: backupmap,
World: game.World, Cellsize: cellsize,
Width: game.ScreenWidth, World: game.World,
Height: game.ScreenHeight, Width: game.ScreenWidth,
Description: plan.Description, Height: game.ScreenHeight,
Name: plan.Name, Description: plan.Description,
GridContainer: gridcontainer, Name: plan.Name,
Systems: systemlist, GridContainer: gridcontainer,
Systems: systemlist,
} }
} }
@@ -77,6 +90,12 @@ func (level *Level) Position2Point(position *components.Position) image.Point {
} }
} }
func (level *Level) RestoreMap() {
for point, tile := range level.BackupMapslice {
level.Mapslice[point] = tile.Clone()
}
}
func (level *Level) SetupGrid(game *Game) { func (level *Level) SetupGrid(game *Game) {
// generic variant does not work here: // generic variant does not work here:
// selector := generic.NewFilter1[components.Position]() // selector := generic.NewFilter1[components.Position]()
@@ -92,15 +111,20 @@ func (level *Level) SetupGrid(game *Game) {
playerobserver := observers.GetPlayerObserver(level.World) playerobserver := observers.GetPlayerObserver(level.World)
playerobserver.RemoveEntities() playerobserver.RemoveEntities()
// get rid of possibly manipulated map
level.RestoreMap()
// setup world // setup world
slog.Debug("new grid?")
level.GridContainer.SetGrid( level.GridContainer.SetGrid(
grid.NewGrid(game.World, level.Cellsize, level.Width, level.Height, level.Mapslice)) grid.NewGrid(game.World, level.Cellsize, level.Width, level.Height, level.Mapslice))
} }
// parses a RawLevel and generates a mapslice from it, which is being used as grid // parses a RawLevel and generates a mapslice from it, which is being used as grid
func LevelToSlice(game *Game, level *assets.RawLevel, tilesize int) map[image.Point]*assets.Tile { func LevelToSlice(game *Game, level *assets.RawLevel, tilesize int) (Map, Map) {
size := game.ScreenWidth * game.ScreenHeight size := game.ScreenWidth * game.ScreenHeight
mapslice := make(map[image.Point]*assets.Tile, size) mapslice := make(Map, size)
backupmap := make(Map, size)
for y, line := range strings.Split(string(level.Data), "\n") { for y, line := range strings.Split(string(level.Data), "\n") {
if len(line) != game.ScreenWidth/tilesize && y < game.ScreenHeight/tilesize { if len(line) != game.ScreenWidth/tilesize && y < game.ScreenHeight/tilesize {
@@ -113,9 +137,11 @@ func LevelToSlice(game *Game, level *assets.RawLevel, tilesize int) map[image.Po
log.Fatalf("unregistered tile type %c encountered", char) log.Fatalf("unregistered tile type %c encountered", char)
} }
mapslice[image.Point{x, y}] = assets.Tiles[byte(char)] tile := assets.Tiles[byte(char)]
mapslice[image.Point{x, y}] = tile
backupmap[image.Point{x, y}] = tile.Clone()
} }
} }
return mapslice return mapslice, backupmap
} }

5
go.mod
View File

@@ -16,8 +16,13 @@ require (
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 // indirect github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 // indirect
github.com/hajimehoshi/ebiten v1.12.12 // indirect github.com/hajimehoshi/ebiten v1.12.12 // indirect
github.com/jezek/xgb v1.1.0 // indirect github.com/jezek/xgb v1.1.0 // indirect
github.com/knadh/koanf v1.5.0 // indirect
github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-colorable v0.1.13 // indirect
github.com/mattn/go-isatty v0.0.20 // indirect github.com/mattn/go-isatty v0.0.20 // indirect
github.com/mitchellh/copystructure v1.2.0 // indirect
github.com/mitchellh/mapstructure v1.5.0 // indirect
github.com/mitchellh/reflectwalk v1.0.2 // indirect
github.com/spf13/pflag v1.0.5 // indirect
github.com/tinne26/etxt v0.0.8 // indirect github.com/tinne26/etxt v0.0.8 // indirect
github.com/tlinden/yadu v0.1.3 // indirect github.com/tlinden/yadu v0.1.3 // indirect
golang.org/x/exp v0.0.0-20230817173708-d852ddb80c63 // indirect golang.org/x/exp v0.0.0-20230817173708-d852ddb80c63 // indirect

345
go.sum
View File

@@ -1,20 +1,110 @@
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=
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/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
github.com/alecthomas/repr v0.3.0 h1:NeYzUPfjjlqHY4KtzgKJiWd6sVq2eNUPTi34PiFGjY8= github.com/alecthomas/repr v0.3.0 h1:NeYzUPfjjlqHY4KtzgKJiWd6sVq2eNUPTi34PiFGjY8=
github.com/alecthomas/repr v0.3.0/go.mod h1:Fr0507jx4eOXV7AlPV6AVZLYrLIuIeSOWtW57eE/O/4= github.com/alecthomas/repr v0.3.0/go.mod h1:Fr0507jx4eOXV7AlPV6AVZLYrLIuIeSOWtW57eE/O/4=
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho=
github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY=
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/armon/go-radix v1.0.0/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8=
github.com/aws/aws-sdk-go-v2 v1.9.2/go.mod h1:cK/D0BBs0b/oWPIcX/Z/obahJK1TT7IPVjy53i/mX/4=
github.com/aws/aws-sdk-go-v2/config v1.8.3/go.mod h1:4AEiLtAb8kLs7vgw2ZV3p2VZ1+hBavOc84hqxVNpCyw=
github.com/aws/aws-sdk-go-v2/credentials v1.4.3/go.mod h1:FNNC6nQZQUuyhq5aE5c7ata8o9e4ECGmS4lAXC7o1mQ=
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.6.0/go.mod h1:gqlclDEZp4aqJOancXK6TN24aKhT0W0Ae9MHk3wzTMM=
github.com/aws/aws-sdk-go-v2/internal/ini v1.2.4/go.mod h1:ZcBrrI3zBKlhGFNYWvju0I3TR93I7YIgAfy82Fh4lcQ=
github.com/aws/aws-sdk-go-v2/service/appconfig v1.4.2/go.mod h1:FZ3HkCe+b10uFZZkFdvf98LHW21k49W8o8J366lqVKY=
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.3.2/go.mod h1:72HRZDLMtmVQiLG2tLfQcaWLCssELvGl+Zf2WVxMmR8=
github.com/aws/aws-sdk-go-v2/service/sso v1.4.2/go.mod h1:NBvT9R1MEF+Ud6ApJKM0G+IkPchKS7p7c2YPKwHmBOk=
github.com/aws/aws-sdk-go-v2/service/sts v1.7.2/go.mod h1:8EzeIqfWt2wWT4rJVu3f21TfrhJ8AEMzVybRNSb/b4g=
github.com/aws/smithy-go v1.8.0/go.mod h1:SObp3lf9smib00L/v3U2eAKG8FyQ7iLrJnQiAmR5n+E=
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/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs=
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
github.com/ebitengine/purego v0.5.0 h1:JrMGKfRIAM4/QVKaesIIT7m/UVjTj5GYhRSQYwfVdpo= github.com/ebitengine/purego v0.5.0 h1:JrMGKfRIAM4/QVKaesIIT7m/UVjTj5GYhRSQYwfVdpo=
github.com/ebitengine/purego v0.5.0/go.mod h1:ah1In8AOtksoNK6yk5z1HTJeUkC1Ez4Wk2idgGslMwQ= github.com/ebitengine/purego v0.5.0/go.mod h1:ah1In8AOtksoNK6yk5z1HTJeUkC1Ez4Wk2idgGslMwQ=
github.com/ebitengine/purego v0.6.0 h1:Yo9uBc1x+ETQbfEaf6wcBsjrQfCEnh/gaGUg7lguEJY= github.com/ebitengine/purego v0.6.0 h1:Yo9uBc1x+ETQbfEaf6wcBsjrQfCEnh/gaGUg7lguEJY=
github.com/ebitengine/purego v0.6.0/go.mod h1:ah1In8AOtksoNK6yk5z1HTJeUkC1Ez4Wk2idgGslMwQ= github.com/ebitengine/purego v0.6.0/go.mod h1:ah1In8AOtksoNK6yk5z1HTJeUkC1Ez4Wk2idgGslMwQ=
github.com/ebitenui/ebitenui v0.5.5 h1:L9UCWmiMlo4sG5TavQKmjfsnwMmYqkld2tXWZMmKkSA= github.com/ebitenui/ebitenui v0.5.5 h1:L9UCWmiMlo4sG5TavQKmjfsnwMmYqkld2tXWZMmKkSA=
github.com/ebitenui/ebitenui v0.5.5/go.mod h1:CkzAwu9Ks32P+NC/7+iypdLA85Wqnn93UztPFE+kAH4= github.com/ebitenui/ebitenui v0.5.5/go.mod h1:CkzAwu9Ks32P+NC/7+iypdLA85Wqnn93UztPFE+kAH4=
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU=
github.com/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM= github.com/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM=
github.com/fatih/color v1.16.0/go.mod h1:fL2Sau1YI5c0pdGEVCbKQbLXB6edEj1ZgiY4NijnWvE= github.com/fatih/color v1.16.0/go.mod h1:fL2Sau1YI5c0pdGEVCbKQbLXB6edEj1ZgiY4NijnWvE=
github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M=
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/v3.3/glfw v0.0.0-20200707082815-5321531c36a2/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200707082815-5321531c36a2/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20221017161538-93cebf72946b h1:GgabKamyOYguHqHjSkDACcgoPIz3w0Dis/zJ1wyHHHU= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20221017161538-93cebf72946b h1:GgabKamyOYguHqHjSkDACcgoPIz3w0Dis/zJ1wyHHHU=
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20221017161538-93cebf72946b/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20221017161538-93cebf72946b/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY=
github.com/go-ldap/ldap v3.0.2+incompatible/go.mod h1:qfd9rJvER9Q0/D/Sqn1DfHRoBp40uXYvFoEVrNEPqRc=
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-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A=
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
github.com/go-test/deep v1.0.2-0.20181118220953-042da051cf31/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA=
github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
github.com/gofrs/flock v0.8.0/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14jxHU= github.com/gofrs/flock v0.8.0/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14jxHU=
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 h1:DACJavvAHhabrF08vX0COfcOBJRhZ8lUbR+ZWIs0Y5g= github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 h1:DACJavvAHhabrF08vX0COfcOBJRhZ8lUbR+ZWIs0Y5g=
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGwJL78qG/PmXZO1EjYhfJinVAhrmmHX6Z8B9k= github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGwJL78qG/PmXZO1EjYhfJinVAhrmmHX6Z8B9k=
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
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.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
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.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8=
github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/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.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk=
github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw=
github.com/hajimehoshi/bitmapfont v1.3.0/go.mod h1:/Qb7yVjHYNUV4JdqNkPs6BSZwLjKqkZOMIp6jZD0KgE= github.com/hajimehoshi/bitmapfont v1.3.0/go.mod h1:/Qb7yVjHYNUV4JdqNkPs6BSZwLjKqkZOMIp6jZD0KgE=
github.com/hajimehoshi/ebiten v1.12.12 h1:JvmF1bXRa+t+/CcLWxrJCRsdjs2GyBYBSiFAfIqDFlI= github.com/hajimehoshi/ebiten v1.12.12 h1:JvmF1bXRa+t+/CcLWxrJCRsdjs2GyBYBSiFAfIqDFlI=
github.com/hajimehoshi/ebiten v1.12.12/go.mod h1:1XI25ImVCDPJiXox4h9yK/CvN5sjDYnbF4oZcFzPXHw= github.com/hajimehoshi/ebiten v1.12.12/go.mod h1:1XI25ImVCDPJiXox4h9yK/CvN5sjDYnbF4oZcFzPXHw=
@@ -26,35 +116,176 @@ github.com/hajimehoshi/file2byteslice v0.0.0-20200812174855-0e5e8a80490e/go.mod
github.com/hajimehoshi/go-mp3 v0.3.1/go.mod h1:qMJj/CSDxx6CGHiZeCgbiq2DSUkbK0UbtXShQcnfyMM= github.com/hajimehoshi/go-mp3 v0.3.1/go.mod h1:qMJj/CSDxx6CGHiZeCgbiq2DSUkbK0UbtXShQcnfyMM=
github.com/hajimehoshi/oto v0.6.1/go.mod h1:0QXGEkbuJRohbJaxr7ZQSxnju7hEhseiPx2hrh6raOI= github.com/hajimehoshi/oto v0.6.1/go.mod h1:0QXGEkbuJRohbJaxr7ZQSxnju7hEhseiPx2hrh6raOI=
github.com/hajimehoshi/oto v0.6.8/go.mod h1:0QXGEkbuJRohbJaxr7ZQSxnju7hEhseiPx2hrh6raOI= github.com/hajimehoshi/oto v0.6.8/go.mod h1:0QXGEkbuJRohbJaxr7ZQSxnju7hEhseiPx2hrh6raOI=
github.com/hashicorp/consul/api v1.13.0/go.mod h1:ZlVrynguJKcYr54zGaDbaL3fOvKC9m72FhPvA8T35KQ=
github.com/hashicorp/consul/sdk v0.8.0/go.mod h1:GBvyrGALthsZObzUGsfgHZQDXjg4lOjagTIwIR1vPms=
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
github.com/hashicorp/go-cleanhttp v0.5.0/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80=
github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80=
github.com/hashicorp/go-hclog v0.0.0-20180709165350-ff2cf002a8dd/go.mod h1:9bjs9uLqI8l75knNv3lV1kA55veR+WUPSiKIWcQHudI=
github.com/hashicorp/go-hclog v0.8.0/go.mod h1:5CU+agLiy3J7N7QjHK5d05KxGsuXiQLrjA0H7acj2lQ=
github.com/hashicorp/go-hclog v0.12.0/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ=
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-multierror v1.1.0/go.mod h1:spPvp8C1qA32ftKqdAHm4hHTbPw+vmowP0z+KUhOZdA=
github.com/hashicorp/go-plugin v1.0.1/go.mod h1:++UyYGoz3o5w9ZzAdZxtQKrWWP+iqPBn3cQptSMzBuY=
github.com/hashicorp/go-retryablehttp v0.5.4/go.mod h1:9B5zBasrRhHXnJnui7y6sL7es7NDiJgTc6Er0maI1Xs=
github.com/hashicorp/go-rootcerts v1.0.1/go.mod h1:pqUvnprVnM5bf7AOirdbb01K4ccR319Vf4pU3K5EGc8=
github.com/hashicorp/go-rootcerts v1.0.2/go.mod h1:pqUvnprVnM5bf7AOirdbb01K4ccR319Vf4pU3K5EGc8=
github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU=
github.com/hashicorp/go-sockaddr v1.0.2/go.mod h1:rB4wwRAUzs07qva3c5SdrY/NEtAUjGlgmH/UkBUC97A=
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-version v1.1.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
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.4/go.mod h1:mtBihi+LeNXGtG8L9dX59gAEa12BDtBQSp4v/YAJqrc=
github.com/hashicorp/memberlist v0.3.0/go.mod h1:MS2lj3INKhZjWNqd3N0m3J+Jxf3DAOnAH9VT3Sh9MUE=
github.com/hashicorp/serf v0.9.6/go.mod h1:TXZNMjZQijwlDvp+r0b63xZ45H7JmCmgg4gpTwn9UV4=
github.com/hashicorp/vault/api v1.0.4/go.mod h1:gDcqh3WGcR1cpF5AJz/B1UFheUEneMoIospckxBxk6Q=
github.com/hashicorp/vault/sdk v0.1.13/go.mod h1:B+hVj7TpuQY1Y/GPbCpffmgd+tSEwvhkWnjtSYCaS2M=
github.com/hashicorp/yamux v0.0.0-20180604194846-3520598351bb/go.mod h1:+NfK9FKeTrX5uv1uIXGdwYDTeHna2qgaIlx54MXqjAM=
github.com/hashicorp/yamux v0.0.0-20181012175058-2f1d1f20f75d/go.mod h1:+NfK9FKeTrX5uv1uIXGdwYDTeHna2qgaIlx54MXqjAM=
github.com/hjson/hjson-go/v4 v4.0.0/go.mod h1:KaYt3bTw3zhBjYqnXkYywcYctk0A2nxeEFTse3rH13E=
github.com/jakecoffman/cp v1.0.0/go.mod h1:JjY/Fp6d8E1CHnu74gWNnU0+b9VzEdUVPoJxg2PsTQg= github.com/jakecoffman/cp v1.0.0/go.mod h1:JjY/Fp6d8E1CHnu74gWNnU0+b9VzEdUVPoJxg2PsTQg=
github.com/jezek/xgb v1.1.0 h1:wnpxJzP1+rkbGclEkmwpVFQWpuE2PUGNUzP8SbfFobk= github.com/jezek/xgb v1.1.0 h1:wnpxJzP1+rkbGclEkmwpVFQWpuE2PUGNUzP8SbfFobk=
github.com/jezek/xgb v1.1.0/go.mod h1:nrhwO0FX/enq75I7Y7G8iN1ubpSGZEiA3v9e9GyRFlk= github.com/jezek/xgb v1.1.0/go.mod h1:nrhwO0FX/enq75I7Y7G8iN1ubpSGZEiA3v9e9GyRFlk=
github.com/jfreymuth/oggvorbis v1.0.1/go.mod h1:NqS+K+UXKje0FUYUPosyQ+XTVvjmVjps1aEZH1sumIk= github.com/jfreymuth/oggvorbis v1.0.1/go.mod h1:NqS+K+UXKje0FUYUPosyQ+XTVvjmVjps1aEZH1sumIk=
github.com/jfreymuth/vorbis v1.0.0/go.mod h1:8zy3lUAm9K/rJJk223RKy6vjCZTWC61NA2QD06bfOE0= github.com/jfreymuth/vorbis v1.0.0/go.mod h1:8zy3lUAm9K/rJJk223RKy6vjCZTWC61NA2QD06bfOE0=
github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo=
github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U=
github.com/joho/godotenv v1.3.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqxOKXbg=
github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4=
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM=
github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
github.com/knadh/koanf v1.5.0 h1:q2TSd/3Pyc/5yP9ldIrSdIz26MCcyNQzW0pEAugLPNs=
github.com/knadh/koanf v1.5.0/go.mod h1:Hgyjp4y8v44hpZtPzs7JZfRAW5AhN7KfZcwv1RYggDs=
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/konsorten/go-windows-terminal-sequences v1.0.3/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/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= 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.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
github.com/mattn/go-colorable v0.1.6/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
github.com/mattn/go-isatty v0.0.10/go.mod h1:qgIWMr58cqv1PHHyhnkY9lrL7etaEgOFcMEpPG5Rm84=
github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOAqxQCu2WE=
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= 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 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
github.com/miekg/dns v1.1.26/go.mod h1:bPDLeHnStXmXAq1m/Ch/hvfNHr14JKNPMBo3VZKjuso=
github.com/miekg/dns v1.1.41/go.mod h1:p6aan82bvRIyn+zDIv9xYNUpwa73JcSh9BKwknJysuI=
github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc=
github.com/mitchellh/cli v1.1.0/go.mod h1:xcISNoH86gajksDmfB23e/pu+B+GeFRMYmoHXxx3xhI=
github.com/mitchellh/copystructure v1.0.0/go.mod h1:SNtv71yrdKgLRyLFxmLdkAbkKEFWgYaq1OVrnRcwhnw=
github.com/mitchellh/copystructure v1.2.0 h1:vpKXTN4ewci03Vljg/q9QvCGUDttBOGBIa15WveJJGw=
github.com/mitchellh/copystructure v1.2.0/go.mod h1:qLl+cE2AmVv+CoeAwDPye/v+N2HKCj9FbZEVFJRxO9s=
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
github.com/mitchellh/go-testing-interface v0.0.0-20171004221916-a61a99592b77/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI=
github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI=
github.com/mitchellh/go-wordwrap v1.0.0/go.mod h1:ZXFpozHsX6DPmq2I0TCekCxypsnAUbP2oI0UX1GXzOo=
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/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY=
github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
github.com/mitchellh/reflectwalk v1.0.0/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw=
github.com/mitchellh/reflectwalk v1.0.2 h1:G2LzWKi524PWgd3mLHV8Y5k7s6XUvT0Gef6zxSIeXaQ=
github.com/mitchellh/reflectwalk v1.0.2/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw=
github.com/mlange-42/arche v0.10.0 h1:fEFDAYMAnWa+xHc1oq4gVcA4PuEQOCGSRXSKITXawMw= github.com/mlange-42/arche v0.10.0 h1:fEFDAYMAnWa+xHc1oq4gVcA4PuEQOCGSRXSKITXawMw=
github.com/mlange-42/arche v0.10.0/go.mod h1:gJ5J8vBreqrf4TcBomBFPGnWdE5P3qa4LtxYHn1gDcg= github.com/mlange-42/arche v0.10.0/go.mod h1:gJ5J8vBreqrf4TcBomBFPGnWdE5P3qa4LtxYHn1gDcg=
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
github.com/npillmayer/nestext v0.1.3/go.mod h1:h2lrijH8jpicr25dFY+oAJLyzlya6jhnuG+zWp9L0Uk=
github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA=
github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
github.com/pelletier/go-toml v1.7.0/go.mod h1:vwGMzjaWMwyfHwgIBhI2YUM4fB6nL6lVAvS1LBMMhTE=
github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY=
github.com/pkg/browser v0.0.0-20180916011732-0a3d74bf9ce4/go.mod h1:4OwLy04Bl9Ef3GJJCoec+30X3LQs/0/m4HFRt/2LUSA= github.com/pkg/browser v0.0.0-20180916011732-0a3d74bf9ce4/go.mod h1:4OwLy04Bl9Ef3GJJCoec+30X3LQs/0/m4HFRt/2LUSA=
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/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
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/posener/complete v1.2.3/go.mod h1:WZIdtGGp+qx0sLrYKtIRAruyNpv6hFCicSgv7Sy7s/s=
github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo=
github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M=
github.com/prometheus/client_golang v1.11.1/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0=
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/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo=
github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc=
github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU=
github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA=
github.com/rhnvrm/simples3 v0.6.1/go.mod h1:Y+3vYm2V7Y4VijFoJHHTrja6OgPrJ2cBti8dPGkC3sA=
github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ=
github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts=
github.com/ryanuber/columnize v2.1.0+incompatible/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts=
github.com/ryanuber/go-glob v1.0.0/go.mod h1:807d1WSdnB0XRJzKNil9Om6lcp/3a0v4qIHxIXzX/Yc=
github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc=
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88=
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
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.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/tinne26/etxt v0.0.8 h1:rjb58jkMkapRGLmhBMWnT76E/nMTXC5P1Q956BRZkoc= github.com/tinne26/etxt v0.0.8 h1:rjb58jkMkapRGLmhBMWnT76E/nMTXC5P1Q956BRZkoc=
github.com/tinne26/etxt v0.0.8/go.mod h1:QM/hlNkstsKC39elTFNKAR34xsMb9QoVosf+g9wlYxM= github.com/tinne26/etxt v0.0.8/go.mod h1:QM/hlNkstsKC39elTFNKAR34xsMb9QoVosf+g9wlYxM=
github.com/tlinden/yadu v0.1.2 h1:TYYVnUJwziRJ9YPbIbRf9ikmDw0Q8Ifixm+J/kBQFh8= github.com/tlinden/yadu v0.1.2 h1:TYYVnUJwziRJ9YPbIbRf9ikmDw0Q8Ifixm+J/kBQFh8=
github.com/tlinden/yadu v0.1.2/go.mod h1:l3bRmHKL9zGAR6pnBHY2HRPxBecf7L74BoBgOOpTcUA= github.com/tlinden/yadu v0.1.2/go.mod h1:l3bRmHKL9zGAR6pnBHY2HRPxBecf7L74BoBgOOpTcUA=
github.com/tlinden/yadu v0.1.3 h1:5cRCUmj+l5yvlM2irtpFBIJwVV2DPEgYSaWvF19FtcY= github.com/tlinden/yadu v0.1.3 h1:5cRCUmj+l5yvlM2irtpFBIJwVV2DPEgYSaWvF19FtcY=
github.com/tlinden/yadu v0.1.3/go.mod h1:l3bRmHKL9zGAR6pnBHY2HRPxBecf7L74BoBgOOpTcUA= github.com/tlinden/yadu v0.1.3/go.mod h1:l3bRmHKL9zGAR6pnBHY2HRPxBecf7L74BoBgOOpTcUA=
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
go.etcd.io/etcd/api/v3 v3.5.4/go.mod h1:5GB2vv4A4AOn3yk7MftYGHkUfGtDHnEraIjym4dYz5A=
go.etcd.io/etcd/client/pkg/v3 v3.5.4/go.mod h1:IJHfcCEKxYu1Os13ZdwCwIUTUVGYTSAM3YSwc9/Ac1g=
go.etcd.io/etcd/client/v3 v3.5.4/go.mod h1:ZaRkVgBZC+L+dLCjTcF1hRXpgZXQPOvnA/Ak/gq3kiY=
go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU=
go.uber.org/zap v1.17.0/go.mod h1:MXVU+bhUf/A7Xi2HNOnopQOrmycQ5Ih87HtOu4q5SSo=
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/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-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-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20190923035154-9ee001bba392/go.mod h1:/lpIB1dKB+9EgE3H3cr1v9wB50oz8l4C4h62xy7jSTY=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/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-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
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-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190731235908-ec7cb31e5a56/go.mod h1:JhuoJpWY28nO4Vef9tZUw9qufEGTyX1+7lmHxV5q5G4= golang.org/x/exp v0.0.0-20190731235908-ec7cb31e5a56/go.mod h1:JhuoJpWY28nO4Vef9tZUw9qufEGTyX1+7lmHxV5q5G4=
golang.org/x/exp v0.0.0-20230817173708-d852ddb80c63 h1:m64FZMko/V45gv0bNmrNYoDEq8U5YUhetc9cBWKS1TQ= golang.org/x/exp v0.0.0-20230817173708-d852ddb80c63 h1:m64FZMko/V45gv0bNmrNYoDEq8U5YUhetc9cBWKS1TQ=
@@ -67,6 +298,10 @@ golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+o
golang.org/x/image v0.0.0-20200801110659-972c09e46d76/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/image v0.0.0-20200801110659-972c09e46d76/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
golang.org/x/image v0.12.0 h1:w13vZbU4o5rKOFFR8y7M+c4A5jXDC0uXTdHYRP8X2DQ= golang.org/x/image v0.12.0 h1:w13vZbU4o5rKOFFR8y7M+c4A5jXDC0uXTdHYRP8X2DQ=
golang.org/x/image v0.12.0/go.mod h1:Lu90jvHG7GfemOIcldsh9A2hS01ocl6oNO7ype5mEnk= golang.org/x/image v0.12.0/go.mod h1:Lu90jvHG7GfemOIcldsh9A2hS01ocl6oNO7ype5mEnk=
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-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE=
golang.org/x/mobile v0.0.0-20190415191353-3e0bab5405d6/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= golang.org/x/mobile v0.0.0-20190415191353-3e0bab5405d6/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o=
golang.org/x/mobile v0.0.0-20210208171126-f462b3930c8f/go.mod h1:skQtrUTUwhdJvXM/2KKJzY8pDgNr9I/FOMqDVRPBUS4= golang.org/x/mobile v0.0.0-20210208171126-f462b3930c8f/go.mod h1:skQtrUTUwhdJvXM/2KKJzY8pDgNr9I/FOMqDVRPBUS4=
@@ -75,29 +310,80 @@ golang.org/x/mobile v0.0.0-20230922142353-e2f452493d57/go.mod h1:wEyOn6VvNW7tcf+
golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY=
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
golang.org/x/mod v0.1.1-0.20191209134235-331c550502dd/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.1.1-0.20191209134235-331c550502dd/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
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-20181114220301-adae6a3d119a/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-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-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
golang.org/x/net v0.0.0-20210410081132-afb366fc7cd1/go.mod h1:9tjilg8BloeKEkVJvy7fQ90B1CfIiPueXVOjqfkSzI8=
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
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-20200107190931-bf48bf16ab8d/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-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/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.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.3.0 h1:ftCYgMx6zT/asHUrPw8BLLscYtGznsLAnjq5RH9P66E= golang.org/x/sync v0.3.0 h1:ftCYgMx6zT/asHUrPw8BLLscYtGznsLAnjq5RH9P66E=
golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y=
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-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190129075346-302c3dd5f1cc/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-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/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-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190403152447-81d4e9dc473e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190429190828-d89cdac9e872/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190429190828-d89cdac9e872/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190922100055-0a153f010e69/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190924154521-2837fb4f24fe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191008105621-543471e840be/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200124204421-9fbb57f87de9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200918174421-af09f7315aff/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200918174421-af09f7315aff/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210303074136-134d130e1a04/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
@@ -112,22 +398,81 @@ golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9sn
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.1-0.20181227161524-e6919f6577db/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k= golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k=
golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/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-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
golang.org/x/tools v0.0.0-20190907020128-2ca718005c18/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-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20200117012304-6edc0a871e69/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200117012304-6edc0a871e69/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20200918232735-d647fc253266/go.mod h1:z6u4i615ZeAfBE4XtMziQW1fSVJXACjjbWkB/mvPzlU= golang.org/x/tools v0.0.0-20200918232735-d647fc253266/go.mod h1:z6u4i615ZeAfBE4XtMziQW1fSVJXACjjbWkB/mvPzlU=
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= 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-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/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
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/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
google.golang.org/genproto v0.0.0-20190404172233-64821d5d2107/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0=
google.golang.org/grpc v1.14.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw=
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
google.golang.org/grpc v1.22.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0=
google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM=
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.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
gopkg.in/asn1-ber.v1 v1.0.0-20181015200546-f715ec2f112d/go.mod h1:cuepJuh7vyXfUyUwEgHQXw849cJrilpS5NeIjOWESAw=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20200902074654-038fdea0a05b/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20200902074654-038fdea0a05b/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/square/go-jose.v2 v2.3.1/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI=
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.3/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.5/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/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1/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-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
sigs.k8s.io/yaml v1.2.0/go.mod h1:yfXDCHCao9+ENCvLSE62v9VSji2MKu5jeNfTrofGhJc=

View File

@@ -14,7 +14,7 @@ func (grid *Grid) GetSolidNeighborPosition(
return false, nil return false, nil
} }
// set to true, if we are already on the last tile in the current // set to true if we are already on the last tile in the current
// direction, i.e. on the edge of the grid // direction, i.e. on the edge of the grid
edge := true edge := true
neighborpos := position.Point() neighborpos := position.Point()
@@ -44,6 +44,9 @@ func (grid *Grid) GetSolidNeighborPosition(
newpos := components.NewPosition(neighborpos, grid.Tilesize) newpos := components.NewPosition(neighborpos, grid.Tilesize)
// slog.Debug("SolidNeighbor?", "player", position.Point(),
// "neighbor", neighborpos, "edge", edge, "neighbor-solid",
// grid.Map[neighborpos].Solid, "newpos", newpos.Point())
if !edge && grid.Map[neighborpos].Solid { if !edge && grid.Map[neighborpos].Solid {
return true, newpos return true, newpos
} }

View File

@@ -6,6 +6,7 @@ import (
"openquell/assets" "openquell/assets"
"openquell/components" "openquell/components"
"openquell/config" "openquell/config"
"openquell/handlers"
"openquell/observers" "openquell/observers"
"github.com/mlange-42/arche/ecs" "github.com/mlange-42/arche/ecs"
@@ -33,8 +34,8 @@ func NewGrid(world *ecs.World,
components.Position, components.Position,
components.Velocity, components.Velocity,
components.Renderable, components.Renderable,
components.Speed, components.Player,
components.Player](world) components.Collider](world)
solidmapper := generic.NewMap4[ solidmapper := generic.NewMap4[
components.Position, components.Position,
@@ -49,11 +50,10 @@ func NewGrid(world *ecs.World,
components.Renderable, components.Renderable,
components.Collectible](world) components.Collectible](world)
obsmapper := generic.NewMap5[ obsmapper := generic.NewMap4[
components.Position, components.Position,
components.Velocity, components.Velocity,
components.Renderable, components.Renderable,
components.Speed,
components.Obstacle](world) components.Obstacle](world)
transmapper := generic.NewMap3[ transmapper := generic.NewMap3[
@@ -61,15 +61,22 @@ func NewGrid(world *ecs.World,
components.Renderable, components.Renderable,
components.Transient](world) components.Transient](world)
doormapper := generic.NewMap3[
components.Position,
components.Renderable,
components.Destroyable](world)
var pos *components.Position var pos *components.Position
var vel *components.Velocity var vel *components.Velocity
var render *components.Renderable var render *components.Renderable
var speed *components.Speed
var transient *components.Transient var transient *components.Transient
var player *components.Player var player *components.Player
var destroyable *components.Destroyable
var collider *components.Collider
playerobserver := observers.GetPlayerObserver(world) playerobserver := observers.GetPlayerObserver(world)
obstacleobserver := observers.GetObstacleObserver(world) obstacleobserver := observers.GetObstacleObserver(world)
entityobserver := observers.GetEntityObserver(world)
for point, tile := range mapslice { for point, tile := range mapslice {
switch tile.Renderable { switch tile.Renderable {
@@ -80,25 +87,35 @@ func NewGrid(world *ecs.World,
pos, render, _, _ = solidmapper.Get(entity) pos, render, _, _ = solidmapper.Get(entity)
case tile.Player: case tile.Player:
entity := playermapper.New() entity := playermapper.New()
pos, _, render, speed, player = playermapper.Get(entity) pos, vel, render, player, collider = playermapper.Get(entity)
playerobserver.AddEntity(entity) playerobserver.AddEntity(entity)
speed.Value = config.PLAYERSPEED vel.Speed = config.PLAYERSPEED
player.IsPrimary = tile.IsPrimary player.IsPrimary = tile.IsPrimary
player.Sprites = tile.Tiles player.Sprites = tile.Tiles
collider.CollisionHandler = handlers.HandlePlayerCollision
collider.EdgeHandler = handlers.HandlePlayerEdgeBump
case tile.Collectible: case tile.Collectible:
entity := colmapper.New() entity := colmapper.New()
pos, render, _ = colmapper.Get(entity) pos, render, _ = colmapper.Get(entity)
entityobserver.AddEntity(entity)
case tile.Obstacle: case tile.Obstacle:
entity := obsmapper.New() entity := obsmapper.New()
pos, vel, render, speed, _ = obsmapper.Get(entity) pos, vel, render, _ = obsmapper.Get(entity)
vel.Direction = tile.Direction vel.Direction = tile.Direction
vel.PointingAt = tile.Direction vel.PointingAt = tile.Direction
speed.Value = config.PLAYERSPEED vel.Speed = config.PLAYERSPEED
obstacleobserver.AddEntity(entity) obstacleobserver.AddEntity(entity)
entityobserver.AddEntity(entity)
case tile.Transient: case tile.Transient:
entity := transmapper.New() entity := transmapper.New()
pos, render, transient = transmapper.Get(entity) pos, render, transient = transmapper.Get(entity)
transient.Sprites = tile.TileNames transient.Sprites = tile.TileNames
entityobserver.AddEntity(entity)
case tile.Destroyable:
entity := doormapper.New()
pos, render, destroyable = doormapper.Get(entity)
destroyable.Sprites = tile.Tiles
entityobserver.AddEntity(entity)
default: default:
log.Fatalln("unsupported tile type encountered") log.Fatalln("unsupported tile type encountered")
} }
@@ -143,7 +160,15 @@ func (grid *Grid) GetTile(
return tile return tile
} }
func (grid *Grid) SetTile(tile *assets.Tile, point image.Point) { func (grid *Grid) RemoveTile(point image.Point) {
delete(grid.Map, point)
}
func (grid *Grid) SetFloorTile(point image.Point) {
grid.Map[point] = assets.Tiles[' ']
}
func (grid *Grid) SetSolidTile(tile *assets.Tile, point image.Point) {
solidmapper := generic.NewMap4[ solidmapper := generic.NewMap4[
components.Position, components.Position,
components.Renderable, components.Renderable,

View File

@@ -0,0 +1,25 @@
package handlers
import (
"openquell/components"
. "openquell/config"
)
// type Collider struct {
// CollisionHandler func(*Position, *Position, *Velocity) bool
// EdgeHandler func(*Position, *Position, *Velocity) bool
// PassoverHandler func(*Position, *Velocity) bool
// PassoverFinishedHandler func(*Position, *Velocity) bool
// }
func HandleCollectibleCollision(pos, newpos *components.Position, velocity *components.Velocity) bool {
pos.Set(newpos)
velocity.Change(Stop)
return true
}
func HandleCollectibleEdgeBump(pos, newpos *components.Position, velocity *components.Velocity) bool {
pos.Set(newpos)
return true
}

View File

@@ -0,0 +1,72 @@
package handlers
import (
"openquell/components"
. "openquell/config"
"openquell/util"
"log/slog"
"github.com/mlange-42/arche/ecs"
"github.com/mlange-42/arche/generic"
)
// type Collider struct {
// CollisionHandler func(*Position, *Position, *Velocity) bool
// EdgeHandler func(*Position, *Position, *Velocity) bool
// PassoverHandler func(*Position, *Velocity) bool
// PassoverFinishedHandler func(*Position, *Velocity) bool
// }
func HandlePlayerCollision(world *ecs.World, pos, newpos *components.Position,
velocity *components.Velocity, target ecs.Entity) bool {
velmapper := generic.NewMap[components.Velocity](world)
wallmapper := generic.NewMap[components.Solid](world)
obsmapper := generic.NewMap[components.Obstacle](world)
if wallmapper.Has(target) {
pos.Set(newpos)
velocity.Change(Stop)
return true
}
if obsmapper.Has(target) {
obsvelocity := velmapper.Get(target)
if CheckObstacleSide(velocity, obsvelocity.Direction) {
// player died
return false
} else {
// bumped into nonlethal obstacle side, stop the
// player, set the obstacle in motion, if possible
obsvelocity.Set(velocity)
velocity.Change(Stop)
pos.Set(newpos)
}
}
return true
}
func HandlePlayerEdgeBump(world *ecs.World, playerpos,
newpos *components.Position, velocity *components.Velocity, target ecs.Entity) bool {
playerpos.Set(newpos)
return true
}
func CheckObstacleSide(playervelocity *components.Velocity, obsdirection int) bool {
movingdirection := playervelocity.InvertDirection()
if movingdirection == Stop || movingdirection == obsdirection {
slog.Debug("Damaging obstacle collision",
"playerdirection", util.DirectionStr(playervelocity.Direction),
"obsdirection", util.DirectionStr(obsdirection),
"movingdirection", util.DirectionStr(movingdirection),
)
return true
}
return false
}

22
main.go
View File

@@ -1,11 +1,14 @@
package main package main
import ( import (
"fmt"
"log" "log"
"log/slog" "log/slog"
"openquell/config"
"openquell/game" "openquell/game"
"os" "os"
"github.com/alecthomas/repr"
"github.com/hajimehoshi/ebiten/v2" "github.com/hajimehoshi/ebiten/v2"
"github.com/tlinden/yadu" "github.com/tlinden/yadu"
) )
@@ -20,22 +23,35 @@ func main() {
ebiten.SetWindowSize(width, height) ebiten.SetWindowSize(width, height)
ebiten.SetWindowTitle("openquell") ebiten.SetWindowTitle("openquell")
config, err := config.InitConfig()
if err != nil {
log.Fatal(err)
}
repr.Print(config)
if config.TPS > 0 {
fmt.Printf("Setting TPS to %d\n", config.TPS)
ebiten.SetMaxTPS(config.TPS)
}
logLevel := &slog.LevelVar{} logLevel := &slog.LevelVar{}
opts := &yadu.Options{ opts := &yadu.Options{
Level: logLevel, Level: logLevel,
AddSource: true, AddSource: true,
} }
logLevel.Set(slog.LevelDebug) if config.Debug {
logLevel.Set(slog.LevelDebug)
}
handler := yadu.NewHandler(os.Stdout, opts) handler := yadu.NewHandler(os.Stdout, opts)
debuglogger := slog.New(handler) debuglogger := slog.New(handler)
slog.SetDefault(debuglogger) slog.SetDefault(debuglogger)
g := game.NewGame(width, height, cellsize, 0, game.Welcome) g := game.NewGame(width, height, cellsize, config, game.Welcome)
err := ebiten.RunGame(g) err = ebiten.RunGame(g)
if err != nil { if err != nil {
log.Fatalf("unable to run game: %s", err) log.Fatalf("unable to run game: %s", err)
} }

View File

@@ -0,0 +1,50 @@
package observers
import (
"github.com/mlange-42/arche/ecs"
"github.com/mlange-42/arche/ecs/event"
"github.com/mlange-42/arche/generic"
"github.com/mlange-42/arche/listener"
)
// will be added as an ecs.Resource to the world so we can use it in
// CollisionSystem to dynamically make it appear or disappear
type EntityObserver struct {
// we only have one obstacle so far, if we use multiple ones, turn
// this in to a map, see player_observer.go for an example
Entities map[ecs.Entity]int
}
func NewEntityObserver(world *ecs.World) {
observer := &EntityObserver{}
observer.Entities = make(map[ecs.Entity]int)
resmanger := generic.NewResource[EntityObserver](world)
resmanger.Add(observer)
listen := listener.NewCallback(
func(world *ecs.World, event ecs.EntityEvent) {
observerID := ecs.ResourceID[EntityObserver](world)
observer := world.Resources().Get(observerID).(*EntityObserver)
observer.RemoveEntity(event.Entity)
},
event.EntityRemoved,
)
world.SetListener(&listen)
}
func GetEntityObserver(world *ecs.World) *EntityObserver {
observerID := ecs.ResourceID[EntityObserver](world)
observer := world.Resources().Get(observerID).(*EntityObserver)
return observer
}
func (observer *EntityObserver) AddEntity(entity ecs.Entity) {
observer.Entities[entity] = 1
}
func (observer *EntityObserver) RemoveEntity(entity ecs.Entity) {
observer.Entities = make(map[ecs.Entity]int)
}

BIN
src/block-grey-damage.xcf Normal file

Binary file not shown.

Binary file not shown.

View File

@@ -53,7 +53,7 @@ func (system *CollectibleSystem) Update() error {
playerposition := (*Position)(system.World.Get(player, posID)) playerposition := (*Position)(system.World.Get(player, posID))
playervelocity := (*Velocity)(system.World.Get(player, veloID)) playervelocity := (*Velocity)(system.World.Get(player, veloID))
ok, _ := playerposition.Intersects(colposition, playervelocity) ok, _ := colposition.Intersects(playerposition, playervelocity)
if ok { if ok {
slog.Debug("bumped into collectible", "collectible", collectible) slog.Debug("bumped into collectible", "collectible", collectible)
particlepositions = append(particlepositions, colposition) particlepositions = append(particlepositions, colposition)

View File

@@ -0,0 +1,92 @@
package systems
import (
"openquell/components"
. "openquell/components"
"openquell/grid"
"openquell/observers"
"github.com/hajimehoshi/ebiten/v2"
"github.com/mlange-42/arche/ecs"
"github.com/mlange-42/arche/generic"
)
type CollisionSystem struct {
World *ecs.World
Selector *generic.Filter4[Position, Velocity, Renderable, Collider]
GridContainer *grid.GridContainer
}
func NewCollisionSystem(world *ecs.World, gridcontainer *grid.GridContainer) System {
system := &CollisionSystem{
Selector: generic.NewFilter4[Position, Velocity, Renderable, Collider](),
GridContainer: gridcontainer,
World: world,
}
return system
}
func (system CollisionSystem) Update() error {
entityobserver := observers.GetEntityObserver(system.World)
posID := ecs.ComponentID[components.Position](system.World)
EntitiesToRemove := []ecs.Entity{}
query := system.Selector.Query(system.World)
for query.Next() {
position, velocity, _, handler := query.Get()
if velocity.Moving() {
// check if we bump agains the screen edge
ok, newpos := system.GridContainer.Grid.BumpEdge(position, velocity)
if ok {
if handler.EdgeHandler != nil {
if !handler.EdgeHandler(system.World, position, newpos, velocity, query.Entity()) {
EntitiesToRemove = append(EntitiesToRemove, query.Entity())
}
}
} else {
// check if we collide with some solid entity
ok, tilepos := system.GridContainer.Grid.GetSolidNeighborPosition(position, velocity, true)
if ok {
intersects, newpos := tilepos.Intersects(position, velocity)
if intersects {
if handler.CollisionHandler != nil {
if !handler.CollisionHandler(system.World, position, newpos, velocity, query.Entity()) {
EntitiesToRemove = append(EntitiesToRemove, query.Entity())
}
}
}
}
}
// check if current entity bumps into another entity
for foreign_entity := range entityobserver.Entities {
if foreign_entity == query.Entity() {
// don't check entity against itself
continue
}
foreign_position := (*Position)(system.World.Get(foreign_entity, posID))
ok, newpos := foreign_position.Intersects(position, velocity)
if ok {
if handler.CollisionHandler != nil {
if !handler.CollisionHandler(system.World, position, newpos, velocity, foreign_entity) {
EntitiesToRemove = append(EntitiesToRemove, query.Entity())
}
}
}
}
}
}
for _, entity := range EntitiesToRemove {
system.World.RemoveEntity(entity)
}
return nil
}
func (system *CollisionSystem) Draw(screen *ebiten.Image) {}

View File

@@ -0,0 +1,112 @@
package systems
import (
"log/slog"
"openquell/components"
. "openquell/components"
. "openquell/config"
"openquell/grid"
"openquell/observers"
"github.com/hajimehoshi/ebiten/v2"
"github.com/mlange-42/arche/ecs"
"github.com/mlange-42/arche/generic"
)
type DestroyableSystem struct {
World *ecs.World
Selector *generic.Filter3[Position, Renderable, Destroyable]
GridContainer *grid.GridContainer
SolidMapper generic.Map4[ // needed for replacement
components.Position,
components.Renderable,
components.Tilish,
components.Solid]
}
type DoorToRemove struct {
Entity ecs.Entity
Position *components.Position
}
func NewDestroyableSystem(world *ecs.World, gridcontainer *grid.GridContainer) System {
solidmapper := generic.NewMap4[
components.Position,
components.Renderable,
components.Tilish,
components.Solid](world)
system := &DestroyableSystem{
Selector: generic.NewFilter3[Position, Renderable, Destroyable](),
World: world,
GridContainer: gridcontainer,
SolidMapper: solidmapper,
}
return system
}
func (system *DestroyableSystem) Update() error {
playerobserver := observers.GetPlayerObserver(system.World)
posID := ecs.ComponentID[components.Position](system.World)
veloID := ecs.ComponentID[components.Velocity](system.World)
query := system.Selector.Query(system.World)
EntitiestoRemove := []*DoorToRemove{}
for query.Next() {
doorposition, renderable, door := query.Get()
for player := range playerobserver.Entities {
if !system.World.Alive(player) {
continue
}
playerposition := (*Position)(system.World.Get(player, posID))
playervelocity := (*Velocity)(system.World.Get(player, veloID))
ok, newpos := doorposition.Intersects(playerposition, playervelocity)
if ok {
// player bumped into hidden wall, activate it, snap in player
slog.Debug("bump not die", "originalpos", playerposition)
playervelocity.Change(Stop)
playerposition.Set(newpos)
if door.Activated {
// player bumps into the door a second time, now hide it
EntitiestoRemove = append(EntitiestoRemove,
&DoorToRemove{Entity: query.Entity(), Position: doorposition})
} else {
slog.Debug("activating destroyable", "doorpos", doorposition)
door.Activated = true
renderable.Image = door.GetNext()
}
}
}
}
for _, door := range EntitiestoRemove {
slog.Debug("hiding destroyable", "doorpos", door.Position.Point())
// remove door entity
system.World.RemoveEntity(door.Entity)
}
return nil
}
func (system *DestroyableSystem) Draw(screen *ebiten.Image) {
// write transients (these are no tiles!)
op := &ebiten.DrawImageOptions{}
query := system.Selector.Query(system.World)
for query.Next() {
pos, render, _ := query.Get()
op.GeoM.Reset()
op.GeoM.Translate(float64(pos.X), float64(pos.Y))
screen.DrawImage(render.Image, op)
}
}

View File

@@ -3,6 +3,7 @@ package systems
import ( import (
"image" "image"
"image/draw" "image/draw"
"log/slog"
. "openquell/components" . "openquell/components"
"github.com/hajimehoshi/ebiten/v2" "github.com/hajimehoshi/ebiten/v2"
@@ -44,8 +45,8 @@ func (system *GridSystem) Update() error { return nil }
func (system *GridSystem) Draw(screen *ebiten.Image) { func (system *GridSystem) Draw(screen *ebiten.Image) {
op := &ebiten.DrawImageOptions{} op := &ebiten.DrawImageOptions{}
query := system.Selector.Query(system.World) query := system.Selector.Query(system.World)
if !system.UseCache || query.Count() != system.Count { if !system.UseCache || query.Count() != system.Count {
slog.Debug("entity number changes", "old", system.Count, "current", query.Count())
// map not cached or cacheable, write it to the cache // map not cached or cacheable, write it to the cache
draw.Draw(system.Cache, system.Background.Bounds(), system.Background, image.ZP, draw.Src) draw.Draw(system.Cache, system.Background.Bounds(), system.Background, image.ZP, draw.Src)
@@ -54,6 +55,7 @@ func (system *GridSystem) Draw(screen *ebiten.Image) {
for query.Next() { for query.Next() {
sprite, pos, _ := query.Get() sprite, pos, _ := query.Get()
//slog.Debug("drawing sprite", "sprite", sprite, "point", pos.Point())
draw.Draw( draw.Draw(
system.Cache, system.Cache,
image.Rect(pos.X, pos.Y, pos.X+pos.Cellsize, pos.Y+pos.Cellsize), image.Rect(pos.X, pos.Y, pos.X+pos.Cellsize, pos.Y+pos.Cellsize),

View File

@@ -17,13 +17,13 @@ import (
type ObstacleSystem struct { type ObstacleSystem struct {
World *ecs.World World *ecs.World
Selector *generic.Filter5[Position, Velocity, Obstacle, Renderable, Speed] Selector *generic.Filter4[Position, Velocity, Obstacle, Renderable]
GridContainer *grid.GridContainer GridContainer *grid.GridContainer
} }
func NewObstacleSystem(world *ecs.World, gridcontainer *grid.GridContainer) System { func NewObstacleSystem(world *ecs.World, gridcontainer *grid.GridContainer) System {
system := &ObstacleSystem{ system := &ObstacleSystem{
Selector: generic.NewFilter5[Position, Velocity, Obstacle, Renderable, Speed](), Selector: generic.NewFilter4[Position, Velocity, Obstacle, Renderable](),
World: world, World: world,
GridContainer: gridcontainer, GridContainer: gridcontainer,
} }
@@ -34,86 +34,16 @@ func NewObstacleSystem(world *ecs.World, gridcontainer *grid.GridContainer) Syst
func (system *ObstacleSystem) Update() error { func (system *ObstacleSystem) Update() error {
playerobserver := observers.GetPlayerObserver(system.World) playerobserver := observers.GetPlayerObserver(system.World)
gameobserver := observers.GetGameObserver(system.World) gameobserver := observers.GetGameObserver(system.World)
obstacleobserver := observers.GetObstacleObserver(system.World)
if gameobserver.Lost { if gameobserver.Lost {
return nil return nil
} }
posID := ecs.ComponentID[components.Position](system.World) var gameover bool
veloID := ecs.ComponentID[components.Velocity](system.World)
EntitiesToRemove := []ecs.Entity{} if len(playerobserver.Entities) == 0 {
// FIXME: check this in game or elsewhere
query := system.Selector.Query(system.World) gameover = true
gameover := false
for query.Next() {
obsposition, obsvelocity, _, _, speed := query.Get()
// check if one player has bumped into current obstacle
for player := range playerobserver.Entities {
playerposition := (*Position)(system.World.Get(player, posID))
playervelocity := (*Velocity)(system.World.Get(player, veloID))
ok, newpos := obsposition.Intersects(playerposition, playervelocity)
if ok {
// slog.Debug("bumped into obstacle", "obstacle", obstacle)
if CheckObstacleSide(playervelocity, obsvelocity.Direction) {
// player died
EntitiesToRemove = append(EntitiesToRemove, player)
gameover = true
} else {
// bumped into nonlethal obstacle side, stop the
// player, set the obstacle in motion, if possible
slog.Debug("bump not die", "originalpos", playerposition)
obsvelocity.Set(playervelocity)
playervelocity.Change(Stop)
playerposition.Set(newpos)
}
}
}
// check if current obstacle bumped into another obstacle
for foreign_obstacle := range obstacleobserver.Entities {
if foreign_obstacle == query.Entity() {
// don't check obstacle against itself
continue
}
foreign_obstacle_position := (*Position)(system.World.Get(foreign_obstacle, posID))
ok, newpos := foreign_obstacle_position.Intersects(obsposition, obsvelocity)
if ok {
//slog.Debug("bumped into foreign obstacle", "obstacle", foreign_obstacle)
obsposition.Set(newpos)
obsvelocity.ResetDirectionAndStop()
}
}
// FIXME: this is the same loop as in player_system, unite the
// two, just iterate over all entities with pos,vel,render, dammit
if obsvelocity.Moving() {
ok, tilepos := system.GridContainer.Grid.GetSolidNeighborPosition(obsposition, obsvelocity, true)
if ok {
intersects, newpos := tilepos.Intersects(obsposition, obsvelocity)
if intersects {
// slog.Debug("collision with foreign obstacle detected", "tile",
// tilepos, "obs", obsposition, "new", newpos)
obsposition.Set(newpos)
obsvelocity.ResetDirectionAndStop()
}
}
obsposition.Move(obsvelocity, speed)
}
}
for _, entity := range EntitiesToRemove {
system.World.RemoveEntity(entity)
} }
if gameover { if gameover {
@@ -136,7 +66,7 @@ func (system *ObstacleSystem) Draw(screen *ebiten.Image) {
query := system.Selector.Query(system.World) query := system.Selector.Query(system.World)
for query.Next() { for query.Next() {
pos, _, _, sprite, _ := query.Get() pos, _, _, sprite := query.Get()
op.GeoM.Reset() op.GeoM.Reset()
op.GeoM.Translate(float64(pos.X), float64(pos.Y)) op.GeoM.Translate(float64(pos.X), float64(pos.Y))

View File

@@ -14,13 +14,13 @@ import (
type PlayerSystem struct { type PlayerSystem struct {
World *ecs.World World *ecs.World
Selector *generic.Filter5[Position, Velocity, Player, Renderable, Speed] Selector *generic.Filter4[Position, Velocity, Player, Renderable]
GridContainer *grid.GridContainer GridContainer *grid.GridContainer
} }
func NewPlayerSystem(world *ecs.World, gridcontainer *grid.GridContainer) System { func NewPlayerSystem(world *ecs.World, gridcontainer *grid.GridContainer) System {
system := &PlayerSystem{ system := &PlayerSystem{
Selector: generic.NewFilter5[Position, Velocity, Player, Renderable, Speed](), Selector: generic.NewFilter4[Position, Velocity, Player, Renderable](),
GridContainer: gridcontainer, GridContainer: gridcontainer,
World: world, World: world,
} }
@@ -33,7 +33,7 @@ func (system PlayerSystem) Update() error {
switchable := false switchable := false
query := system.Selector.Query(system.World) query := system.Selector.Query(system.World)
for query.Next() { for query.Next() {
_, _, player, _, _ := query.Get() _, _, player, _ := query.Get()
if !player.IsPrimary { if !player.IsPrimary {
switchable = true switchable = true
} }
@@ -42,7 +42,7 @@ func (system PlayerSystem) Update() error {
if switchable { if switchable {
query := system.Selector.Query(system.World) query := system.Selector.Query(system.World)
for query.Next() { for query.Next() {
_, _, player, render, _ := query.Get() _, _, player, render := query.Get()
if inpututil.IsKeyJustPressed(ebiten.KeyTab) { if inpututil.IsKeyJustPressed(ebiten.KeyTab) {
slog.Debug("switch players") slog.Debug("switch players")
if player.IsPrimary { if player.IsPrimary {
@@ -59,7 +59,7 @@ func (system PlayerSystem) Update() error {
// check player movements etc // check player movements etc
query = system.Selector.Query(system.World) query = system.Selector.Query(system.World)
for query.Next() { for query.Next() {
playerposition, velocity, player, _, _ := query.Get() _, velocity, player, _ := query.Get()
if !player.IsPrimary { if !player.IsPrimary {
continue continue
@@ -75,36 +75,34 @@ func (system PlayerSystem) Update() error {
velocity.Change(South) velocity.Change(South)
case ebiten.IsKeyPressed(ebiten.KeyUp): case ebiten.IsKeyPressed(ebiten.KeyUp):
velocity.Change(North) velocity.Change(North)
case ebiten.IsKeyPressed(ebiten.Key1):
velocity.Speed = 1
case ebiten.IsKeyPressed(ebiten.Key2):
velocity.Speed = 2
case ebiten.IsKeyPressed(ebiten.Key3):
velocity.Speed = 3
case ebiten.IsKeyPressed(ebiten.Key4):
velocity.Speed = 4
case ebiten.IsKeyPressed(ebiten.Key5):
velocity.Speed = 5
case ebiten.IsKeyPressed(ebiten.Key6):
velocity.Speed = 6
case ebiten.IsKeyPressed(ebiten.Key7):
velocity.Speed = 7
case ebiten.IsKeyPressed(ebiten.Key8):
velocity.Speed = 8
case ebiten.IsKeyPressed(ebiten.Key9):
velocity.Speed = 9
// other keys: <tab>: switch player, etc // other keys: <tab>: switch player, etc
} }
} }
if velocity.Moving() {
ok, newpos := system.GridContainer.Grid.BumpEdge(playerposition, velocity)
if ok {
//slog.Debug("falling off the edge", "newpos", newpos)
playerposition.Set(newpos)
} else {
ok, tilepos := system.GridContainer.Grid.GetSolidNeighborPosition(playerposition, velocity, true)
if ok {
intersects, newpos := tilepos.Intersects(playerposition, velocity)
if intersects {
// slog.Debug("collision detected", "tile",
// tilepos, "player", playerposition, "new", newpos)
playerposition.Set(newpos)
velocity.Change(Stop)
}
}
}
}
} }
query = system.Selector.Query(system.World) query = system.Selector.Query(system.World)
for query.Next() { for query.Next() {
// move player after obstacle or collectible updates // move player after obstacle or collectible updates
playerposition, velocity, _, _, speed := query.Get() playerposition, velocity, _, _ := query.Get()
playerposition.Move(velocity, speed) playerposition.Move(velocity)
} }
return nil return nil
@@ -116,7 +114,7 @@ func (system *PlayerSystem) Draw(screen *ebiten.Image) {
query := system.Selector.Query(system.World) query := system.Selector.Query(system.World)
for query.Next() { for query.Next() {
pos, _, _, sprite, _ := query.Get() pos, _, _, sprite := query.Get()
op.GeoM.Reset() op.GeoM.Reset()
op.GeoM.Translate(float64(pos.X), float64(pos.Y)) op.GeoM.Translate(float64(pos.X), float64(pos.Y))

View File

@@ -60,6 +60,10 @@ func (system *TransientSystem) Update() error {
transientposition, _, transient := query.Get() transientposition, _, transient := query.Get()
for player := range playerobserver.Entities { for player := range playerobserver.Entities {
if !system.World.Alive(player) {
continue
}
playerposition := (*Position)(system.World.Get(player, posID)) playerposition := (*Position)(system.World.Get(player, posID))
playervelocity := (*Velocity)(system.World.Get(player, veloID)) playervelocity := (*Velocity)(system.World.Get(player, veloID))
@@ -95,7 +99,7 @@ func (system *TransientSystem) Update() error {
// also setup the grid tile with a new solid, so that // also setup the grid tile with a new solid, so that
// collision detection works // collision detection works
system.GridContainer.Grid.SetTile( system.GridContainer.Grid.SetSolidTile(
assets.NewTileBlock(convertible.NewSprite), assets.NewTileBlock(convertible.NewSprite),
convertible.Position.Point(), convertible.Position.Point(),
) )