Wrap text buffers

This commit is contained in:
Trevor Slocum 2021-11-03 17:34:02 -07:00
parent bcd81219e4
commit 8e5d87bbcc
6 changed files with 168 additions and 77 deletions

View File

@ -5,6 +5,7 @@ import (
"image"
"image/color"
"log"
"os"
"time"
"code.rocketnine.space/tslocum/fibs"
@ -504,12 +505,18 @@ func (b *board) draw(screen *ebiten.Image) {
}
if b.debug == 2 {
homeStart, homeEnd := b.Client.Board.PlayerHomeSpaces()
b.iterateSpaces(func(space int) {
x, y, w, h := b.spaceRect(space)
spaceImage := ebiten.NewImage(w, h)
br := ""
if b.bottomRow(space) {
br = "B"
if space >= homeStart && space <= homeEnd {
br += "H"
}
if space == b.Client.Board.PlayerBarSpace() {
br += "(PB)"
} else if space == 25-b.Client.Board.PlayerBarSpace() {
br += "(OB)"
}
ebitenutil.DebugPrint(spaceImage, fmt.Sprintf(" %d %s", space, br))
x, y = b.offsetPosition(x, y)
@ -736,6 +743,16 @@ func (b *board) stackSpaceRect(space int, stack int) (x, y, w, h int) {
}
func (b *board) SetState(s []string, v []int) {
log.Printf("OLD %+v", b.v)
log.Printf("NEW %+v", v)
for i := 0; i < 26; i++ {
var str string
if b.v[fibs.StateBoardSpace0+i] != v[fibs.StateBoardSpace0+i] {
str = "^^^"
}
log.Printf("SPACE %d WAS %d, NOW %d %s", i, b.v[fibs.StateBoardSpace0+i], v[fibs.StateBoardSpace0+i], str)
}
copy(b.s, s)
copy(b.v, v)
b.ProcessState()
@ -782,9 +799,15 @@ func (b *board) ProcessState() {
b.positionCheckers()
}
// _movePiece returns after moving the piece.
func (b *board) _movePiece(sprite *Sprite, from int, to int, speed int, pause bool) {
moveTime := time.Second / time.Duration(speed)
pauseTime := 750 * time.Millisecond
t := time.Now()
defer func() {
log.Printf("MOVE PIECE TOOK %s", time.Since(t))
}()
moveTime := (750 * time.Millisecond) / time.Duration(speed)
pauseTime := 500 * time.Millisecond
b.moving = sprite
@ -805,21 +828,12 @@ func (b *board) _movePiece(sprite *Sprite, from int, to int, speed int, pause bo
sprite.toTime = moveTime
sprite.toStart = time.Now()
ebiten.ScheduleFrame()
log.Println("SCHEDULED FRAME, SLEEP")
time.Sleep(sprite.toTime)
time.Sleep(moveTime)
sprite.x = x
sprite.y = y
sprite.toStart = time.Time{}
ebiten.ScheduleFrame()
log.Println("SCHEDULED FRAME, UNSLEEP")
if pause {
log.Println("PAUSE ", pauseTime)
time.Sleep(pauseTime)
log.Println("UNPAUSE")
} else {
time.Sleep(50 * time.Millisecond)
}
/*homeSpace := b.Client.Board.PlayerHomeSpace()
if b.v[fibs.StateTurn] != b.v[fibs.StatePlayerColor] {
@ -837,14 +851,19 @@ func (b *board) _movePiece(sprite *Sprite, from int, to int, speed int, pause bo
}
b.moving = nil
b.ScheduleFrame()
if pause {
time.Sleep(pauseTime)
} else {
time.Sleep(50 * time.Millisecond)
}
}
// Do not call directly
// movePiece returns when finished moving the piece.
func (b *board) movePiece(from int, to int) {
pieces := b.spaces[from]
if len(pieces) == 0 {
log.Printf("%d-%d: NO PIECES AT SPACE %d", from, to, from)
os.Exit(1)
return
}
@ -859,7 +878,11 @@ func (b *board) movePiece(from int, to int) {
b._movePiece(sprite, from, to, 1, moveAfter == nil)
if moveAfter != nil {
b._movePiece(moveAfter, to, b.Client.Board.PlayerBarSpace(), 1, true)
bar := b.Client.Board.PlayerBarSpace()
if b.v[fibs.StateTurn] == b.v[fibs.StatePlayerColor] {
bar = 25 - bar
}
b._movePiece(moveAfter, to, bar, 1, true)
}
log.Println("FINISH MOVE PIECE", from, to)
}

View File

@ -162,6 +162,8 @@ type Game struct {
Debug int
debugImg *ebiten.Image
keyboard *kibodo.Keyboard
keyboardInput []*kibodo.Input
shownKeyboard bool
@ -187,6 +189,8 @@ func NewGame() *Game {
keyboard: kibodo.NewKeyboard(),
buffers: newTabbedBuffers(),
debugImg: ebiten.NewImage(200, 200),
}
g.keyboard.SetKeys(kibodo.KeysQWERTY)
@ -208,7 +212,6 @@ func NewGame() *Game {
t := time.NewTicker(time.Second / 4)
for range t.C {
_ = g.update()
}
}()
@ -232,10 +235,15 @@ func (g *Game) handleEvents() {
g.pendingWho = event.Who
}
case *fibs.EventBoardState:
log.Println("EVENTBOARDSTATE START")
g.Board.SetState(event.S, event.V)
log.Println("EVENTBOARDSTATE FINISH")
case *fibs.EventMove:
log.Printf("EVENTMOVE START %d %d", event.From, event.To)
g.Board.movePiece(event.From, event.To)
log.Println("EVENTMOVE FINISH")
case *fibs.EventDraw:
log.Println("EVENTDRAW START")
g.Board.ProcessState()
}
}
@ -439,9 +447,6 @@ http://www.fibs.com/help.html#register`
}
if g.Debug > 0 {
debugBox := image.NewRGBA(image.Rect(10, 20, 200, 200))
debugImg := ebiten.NewImageFromImage(debugBox)
g.drawBuffer.Reset()
g.drawBuffer.Write([]byte(fmt.Sprintf("FPS %0.0f %c\nTPS %0.0f", ebiten.CurrentFPS(), spinner[g.spinnerIndex], ebiten.CurrentTPS())))
@ -462,12 +467,14 @@ http://www.fibs.com/help.html#register`
g.drawBuffer.Write(debugExtra)
}
ebitenutil.DebugPrint(debugImg, g.drawBuffer.String())
g.debugImg.Clear()
ebitenutil.DebugPrint(g.debugImg, g.drawBuffer.String())
g.resetImageOptions()
g.op.GeoM.Translate(3, 0)
g.op.GeoM.Scale(2, 2)
screen.DrawImage(debugImg, g.op)
screen.DrawImage(g.debugImg, g.op)
}
}
@ -480,38 +487,46 @@ func (g *Game) Layout(outsideWidth, outsideHeight int) (int, int) {
g.screenW, g.screenH = outsideWidth, outsideHeight
g.lobby.setRect(0, 0, g.screenW, g.screenH)
g.Board.setRect(0, 0, g.screenW, g.screenH)
g.lobby.setRect(0, 0, g.screenW, g.screenH)
// Clamp buffer position.
bx, by := g.buffers.x, g.buffers.y
var bw, bh int
if g.buffers.w == 0 && g.buffers.h == 0 {
// Set initial buffer position.
bx = 0
by = g.screenH / 2
// Set initial buffer size.
bw = g.screenW
bh = g.screenH / 2
availableWidth := g.Board.w - (g.Board.spaceWidth * 14)
if availableWidth >= 150 {
g.Board.setRect(0, 0, g.screenW-availableWidth, g.screenH)
g.buffers.setRect(g.screenW-availableWidth, 0, availableWidth, g.screenH)
// TODO set flag to restore user position (could use extra state for this? docked state?)
} else {
// Scale existing buffer size
bx, by = bx*(outsideWidth/g.screenW), by*(outsideHeight/g.screenH)
bw, bh = g.buffers.w*(outsideWidth/g.screenW), g.buffers.h*(outsideHeight/g.screenH)
if bw < 200 {
bw = 200
// Clamp buffer position.
bx, by := g.buffers.x, g.buffers.y
var bw, bh int
if g.buffers.w == 0 && g.buffers.h == 0 {
// Set initial buffer position.
bx = 0
by = g.screenH / 2
// Set initial buffer size.
bw = g.screenW
bh = g.screenH / 2
} else {
// Scale existing buffer size
bx, by = bx*(outsideWidth/g.screenW), by*(outsideHeight/g.screenH)
bw, bh = g.buffers.w*(outsideWidth/g.screenW), g.buffers.h*(outsideHeight/g.screenH)
if bw < 200 {
bw = 200
}
if bh < 100 {
bh = 100
}
}
if bh < 100 {
bh = 100
padding := 7
if bx > g.screenW-padding {
bx = g.screenW - padding
}
if by > g.screenH-padding {
by = g.screenH - padding
}
g.buffers.setRect(bx, by, bw, bh)
}
padding := 7
if bx > g.screenW-padding {
bx = g.screenW - padding
}
if by > g.screenH-padding {
by = g.screenH - padding
}
g.buffers.setRect(bx, by, bw, bh)
displayArea := 200
g.keyboard.SetRect(0, displayArea, g.screenW, g.screenH-displayArea)

View File

@ -17,6 +17,8 @@ const (
const windowStartingAlpha = 0.9
const bufferCharacterWidth = 12
type tabbedBuffers struct {
buffers []*textBuffer
labels [][]byte
@ -29,6 +31,8 @@ type tabbedBuffers struct {
buffer *ebiten.Image
bufferDirty bool
wrapWidth int
op *ebiten.DrawImageOptions
state int
@ -64,6 +68,13 @@ func (t *tabbedBuffers) setRect(x, y, w, h int) {
t.bufferDirty = true
}
if t.w != w {
t.wrapWidth = w / bufferCharacterWidth
for _, b := range t.buffers {
b.wrapDirty = true
}
}
t.x, t.y, t.w, t.h = x, y, w, h
}
@ -75,7 +86,7 @@ func (t *tabbedBuffers) drawBuffer() {
b := t.buffers[0]
l := len(b.content)
l := len(b.contentWrapped)
lineHeight := 16
showLines := t.h / lineHeight
@ -90,7 +101,7 @@ func (t *tabbedBuffers) drawBuffer() {
showLines = l
}
for i := 0; i < showLines; i++ {
line := string(b.content[l-showLines+i])
line := b.contentWrapped[l-showLines+i]
bounds := text.BoundString(monoFont, line)
_ = bounds
@ -110,7 +121,16 @@ func (t *tabbedBuffers) draw(target *ebiten.Image) {
}
if t.bufferDirty {
for _, b := range t.buffers {
if b.wrapDirty {
b.wrapContent()
b.wrapDirty = false
}
}
t.drawBuffer()
t.bufferDirty = false
}

View File

@ -1,13 +1,17 @@
package game
import "github.com/hajimehoshi/ebiten/v2"
import (
"github.com/hajimehoshi/ebiten/v2"
)
type textBuffer struct {
// Content of buffer separated by newlines.
content [][]byte
wrapDirty bool
// Content as it appears on the screen.
contentWrapped []byte
contentWrapped []string
offset int
@ -17,12 +21,27 @@ type textBuffer struct {
func (b *textBuffer) Write(p []byte) {
b.content = append(b.content, p)
b.wrapContent()
b.wrapDirty = true
b.tab.bufferDirty = true
ebiten.ScheduleFrame()
}
func (b *textBuffer) wrapContent() {
// TODO
b.contentWrapped = nil
for _, line := range b.content {
if b.tab.wrapWidth == 0 {
b.contentWrapped = append(b.contentWrapped, string(line))
continue
}
lineStr := string(line)
l := len(lineStr)
for start := 0; start < l; start += b.tab.wrapWidth {
end := start + b.tab.wrapWidth
if end > l {
end = l
}
b.contentWrapped = append(b.contentWrapped, lineStr[start:end])
}
}
}

18
go.mod
View File

@ -3,17 +3,17 @@ module code.rocketnine.space/tslocum/boxcars
go 1.17
require (
code.rocketnine.space/tslocum/fibs v0.0.0-20211001010223-882585bf240f
code.rocketnine.space/tslocum/kibodo v0.0.0-20211019025539-477569f21e2d
github.com/hajimehoshi/ebiten/v2 v2.2.0
code.rocketnine.space/tslocum/fibs v0.0.0-20211104004539-6041d6487dd3
code.rocketnine.space/tslocum/kibodo v0.0.0-20211027223129-7b870790d865
github.com/hajimehoshi/ebiten/v2 v2.2.1
github.com/llgcode/draw2d v0.0.0-20210904075650-80aa0a2a901d
github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646
golang.org/x/exp v0.0.0-20211012155715-ffe10e552389
golang.org/x/image v0.0.0-20210628002857-a66eb6448b8d
golang.org/x/exp v0.0.0-20211103171733-83d51122435b
golang.org/x/image v0.0.0-20211028202545-6944b10bf410
)
require (
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20210727001814-0db043d8d5be // indirect
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20211024062804-40e447a793be // indirect
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 // indirect
github.com/jezek/xgb v0.0.0-20210312150743-0e0f116e1240 // indirect
github.com/klauspost/compress v1.13.6 // indirect
@ -21,11 +21,9 @@ require (
github.com/modern-go/reflect2 v1.0.1 // indirect
github.com/reiver/go-oi v1.0.0 // indirect
github.com/reiver/go-telnet v0.0.0-20180421082511-9ff0b2ab096e // indirect
golang.org/x/mobile v0.0.0-20210924032853-1c027f395ef7 // indirect
golang.org/x/mobile v0.0.0-20211103151657-e68c98865fb2 // indirect
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c // indirect
golang.org/x/sys v0.0.0-20211015200801-69063c4bb744 // indirect
golang.org/x/sys v0.0.0-20211103235746-7861aae1554b // indirect
golang.org/x/text v0.3.7 // indirect
nhooyr.io/websocket v1.8.7 // indirect
)
replace code.rocketnine.space/tslocum/fibs => /home/trevor/programming/fibs

36
go.sum
View File

@ -1,7 +1,9 @@
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=
code.rocketnine.space/tslocum/kibodo v0.0.0-20211019025539-477569f21e2d h1:0rQEofP0UQB2YO+lfrAtY64y/1888EbLlT/EndQp1Jg=
code.rocketnine.space/tslocum/kibodo v0.0.0-20211019025539-477569f21e2d/go.mod h1:0eb5F1sENVoraSdHJCbC9DWkNM01iysfRFlMiA37ppk=
code.rocketnine.space/tslocum/fibs v0.0.0-20211104004539-6041d6487dd3 h1:3zQAtK2vsQq8BKVNWlAiNF5SRsscm2l4IqkorwXSYSU=
code.rocketnine.space/tslocum/fibs v0.0.0-20211104004539-6041d6487dd3/go.mod h1:f7Cz0zJWOnJ9DW7R/GTuE8z5XWQtkbXkKpksW9SDu2c=
code.rocketnine.space/tslocum/kibodo v0.0.0-20211027223129-7b870790d865 h1:Sm6hHfKceNAPvGw+zOmQm5u+TePLJgZzz8zyk2Q/HC0=
code.rocketnine.space/tslocum/kibodo v0.0.0-20211027223129-7b870790d865/go.mod h1:pQfyfr10kXO/Cqw/T+bTDEg3Xbhjxb4vn/vaPzPW/Vk=
dmitri.shuralyov.com/gpu/mtl v0.0.0-20201218220906-28db891af037/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
@ -65,8 +67,9 @@ github.com/go-gl/gl v0.0.0-20180407155706-68e253793080/go.mod h1:482civXOzJJCPzJ
github.com/go-gl/glfw v0.0.0-20180426074136-46a8d530c326 h1:QqWaXlVeUGwSH7hO8giZP2Y06Qjl1LWR+FWC22YQsU8=
github.com/go-gl/glfw v0.0.0-20180426074136-46a8d530c326/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20210727001814-0db043d8d5be h1:vEIVIuBApEBQTEJt19GfhoU+zFSV+sNTa9E9FdnRYfk=
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20210727001814-0db043d8d5be/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20211024062804-40e447a793be h1:Z28GdQBfKOL8tNHjvaDn3wHDO7AzTRkmAXvHvnopp98=
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20211024062804-40e447a793be/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/kit v0.10.0/go.mod h1:xUsJbQ/Fp4kEt7AFgCuvyX4a71u8h9jB8tj/ORgOZ7o=
@ -129,8 +132,8 @@ github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgf
github.com/grpc-ecosystem/grpc-gateway v1.9.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
github.com/hajimehoshi/bitmapfont/v2 v2.1.3 h1:JefUkL0M4nrdVwVq7MMZxSTh6mSxOylm+C4Anoucbb0=
github.com/hajimehoshi/bitmapfont/v2 v2.1.3/go.mod h1:2BnYrkTQGThpr/CY6LorYtt/zEPNzvE/ND69CRTaHMs=
github.com/hajimehoshi/ebiten/v2 v2.2.0 h1:2mP9HrLLqiH9X3MajElYZEjVZU/CGh22iFkjatxhT4w=
github.com/hajimehoshi/ebiten/v2 v2.2.0/go.mod h1:olKl/qqhMBBAm2oI7Zy292nCtE+nitlmYKNF3UpbFn0=
github.com/hajimehoshi/ebiten/v2 v2.2.1 h1:YhITMaBQmnwb4kzAXCCfSkSZmeQX7pfQ7BnC32cnPjc=
github.com/hajimehoshi/ebiten/v2 v2.2.1/go.mod h1:olKl/qqhMBBAm2oI7Zy292nCtE+nitlmYKNF3UpbFn0=
github.com/hajimehoshi/file2byteslice v0.0.0-20210813153925-5340248a8f41/go.mod h1:CqqAHp7Dk/AqQiwuhV1yT2334qbA/tFWQW0MD2dGqUE=
github.com/hajimehoshi/go-mp3 v0.3.2/go.mod h1:qMJj/CSDxx6CGHiZeCgbiq2DSUkbK0UbtXShQcnfyMM=
github.com/hajimehoshi/oto v0.6.1/go.mod h1:0QXGEkbuJRohbJaxr7ZQSxnju7hEhseiPx2hrh6raOI=
@ -312,6 +315,7 @@ github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q
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.0/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
github.com/yuin/goldmark v1.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
go.etcd.io/etcd v0.0.0-20191023171146-3cf2f69b5738/go.mod h1:dnLIgRNXwCJa5e+c6mIZCrds/GIG4ncV9HhK5PX7jPg=
go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk=
@ -341,17 +345,20 @@ golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8U
golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/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-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-20190731235908-ec7cb31e5a56/go.mod h1:JhuoJpWY28nO4Vef9tZUw9qufEGTyX1+7lmHxV5q5G4=
golang.org/x/exp v0.0.0-20211012155715-ffe10e552389 h1:qFfBYVpJAdBCk6Nmd7ZbcyhGmKmv8fps+OyoOfpjvu8=
golang.org/x/exp v0.0.0-20211012155715-ffe10e552389/go.mod h1:a3o/VtDNHN+dCVLEpzjjUHOzR+Ln3DHX056ZPzoZGGA=
golang.org/x/exp v0.0.0-20211103171733-83d51122435b h1:e+Rv1NiVC9bG9xDgJ2avTRqmdMJ6X5q1f8QQKr5uFww=
golang.org/x/exp v0.0.0-20211103171733-83d51122435b/go.mod h1:OyI624f2tQ/aU3IMa7GB16Hk54CHURAfHfj6tMqtyhA=
golang.org/x/image v0.0.0-20180708004352-c73c2afc3b81/go.mod h1:ux5Hcp/YLpHSI86hEcLt0YII63i6oz57MZXIpbrjZUs=
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
golang.org/x/image v0.0.0-20190703141733-d6a02ce849c9/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
golang.org/x/image v0.0.0-20210628002857-a66eb6448b8d h1:RNPAfi2nHY7C2srAV8A49jpsYr0ADedCk1wq6fTMTvs=
golang.org/x/image v0.0.0-20210628002857-a66eb6448b8d/go.mod h1:023OzeP/+EPmXeapQh35lcL3II3LrY8Ic+EFFKVhULM=
golang.org/x/image v0.0.0-20211028202545-6944b10bf410 h1:hTftEOvwiOq2+O8k2D5/Q7COC7k5Qcrgc2TFURJYnvQ=
golang.org/x/image v0.0.0-20211028202545-6944b10bf410/go.mod h1:023OzeP/+EPmXeapQh35lcL3II3LrY8Ic+EFFKVhULM=
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
@ -361,8 +368,9 @@ golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU
golang.org/x/mobile v0.0.0-20190415191353-3e0bab5405d6/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o=
golang.org/x/mobile v0.0.0-20201217150744-e6ae53a27f4f/go.mod h1:skQtrUTUwhdJvXM/2KKJzY8pDgNr9I/FOMqDVRPBUS4=
golang.org/x/mobile v0.0.0-20210902104108-5d9a33257ab5/go.mod h1:c4YKU3ZylDmvbw+H/PSvm42vhdWbuxCzbonauEAP9B8=
golang.org/x/mobile v0.0.0-20210924032853-1c027f395ef7 h1:CyFUjc175y/mbMjxe+WdqI72jguLyjQChKCDe9mfTvg=
golang.org/x/mobile v0.0.0-20210924032853-1c027f395ef7/go.mod h1:c4YKU3ZylDmvbw+H/PSvm42vhdWbuxCzbonauEAP9B8=
golang.org/x/mobile v0.0.0-20211103151657-e68c98865fb2 h1:SFpMH29/c2+VPCOcOlLPQiAVqU2sXiFvwfdtQfVEEJ8=
golang.org/x/mobile v0.0.0-20211103151657-e68c98865fb2/go.mod h1:pe2sM7Uk+2Su1y7u/6Z8KJ24D7lepUjFZbhFOrmDfuQ=
golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=
golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY=
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
@ -370,6 +378,8 @@ golang.org/x/mod v0.1.1-0.20191209134235-331c550502dd/go.mod h1:s0Qsj1ACt9ePp/hM
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.5.1-0.20210830214625-1b1db11ec8f4/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro=
golang.org/x/mod v0.5.1/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro=
golang.org/x/mod v0.6.0-dev.0.20211013180041-c96bc1413d57/go.mod h1:3p9vT2HGsQu2K1YbXdKPJLVgG5VJdoTa1poYQBtP1AY=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
@ -387,8 +397,10 @@ golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLL
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
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-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
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/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
@ -425,10 +437,12 @@ golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/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-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210917161153-d61c044b1678/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211015200801-69063c4bb744 h1:KzbpndAYEM+4oHRp9JmB2ewj0NHHxO3Z0g7Gus2O1kk=
golang.org/x/sys v0.0.0-20211015200801-69063c4bb744/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211103235746-7861aae1554b h1:1VkfZQv42XQlA/jchYumAnv1UPo6RgF9rJFkTgZIxO4=
golang.org/x/sys v0.0.0-20211103235746-7861aae1554b/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
@ -457,6 +471,8 @@ golang.org/x/tools v0.0.0-20200117012304-6edc0a871e69/go.mod h1:TB2adYChydJhpapK
golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0=
golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
golang.org/x/tools v0.1.6/go.mod h1:LGqMHiF4EqQNHR1JncWGqT5BVaXmza+X+BDGol+dOxo=
golang.org/x/tools v0.1.8-0.20211022200916-316ba0b74098/go.mod h1:LGqMHiF4EqQNHR1JncWGqT5BVaXmza+X+BDGol+dOxo=
golang.org/x/tools v0.1.8-0.20211029000441-d6a9af8af023/go.mod h1:nABZi5QlRsZVlzPpHl034qft6wpY4eDcsTt5AaioBiU=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=