diff --git a/app/darktile/cmd/root.go b/app/darktile/cmd/root.go index 76076c2..0a4f62c 100644 --- a/app/darktile/cmd/root.go +++ b/app/darktile/cmd/root.go @@ -7,6 +7,7 @@ import ( "log/slog" "os" + "anime.bike/slogutil/slogenv" "gfx.cafe/util/go/fxplus" "github.com/lmittmann/tint" "go.uber.org/fx" @@ -41,7 +42,7 @@ func (r *Term) Run(ctx *Context) error { func() *slog.Logger { return slog.New(tint.NewHandler(os.Stdout, &tint.Options{ AddSource: true, - Level: slog.LevelInfo.Level(), + Level: slogenv.EnvLevel(), })) }, fxplus.Context, diff --git a/app/darktile/config/lark.go b/app/darktile/config/lark.go index 7ed07c8..6745774 100644 --- a/app/darktile/config/lark.go +++ b/app/darktile/config/lark.go @@ -5,7 +5,7 @@ import ( "encoding/json" "fmt" "image/color" - "log" + "log/slog" "github.com/mazznoer/csscolorparser" mjson "go.starlark.net/lib/json" @@ -14,8 +14,10 @@ import ( ) type Lark struct { - t *starlark.Thread - g starlark.StringDict + t *starlark.Thread + config *starlark.Dict + + log *slog.Logger } var colorSchemes = map[string]string{"default": `{ @@ -41,39 +43,65 @@ var colorSchemes = map[string]string{"default": `{ }`} var defaultConfig = fmt.Sprintf(` -config = { - "title": "tebit", - "initialWidth": 600, - "startHeight": 600, +config.update({ + "title": "erm", + "initial_cols": 120, + "initial_rows": 24, "font": { - "style": "Fira Mono", - "size": 12.0, + "style": "Fira Mono", + "size": 12.0, }, -} +}) config.update({"colors": json.decode('%s')}) `, compact(colorSchemes["default"])) -func NewLark() (*Lark, error) { +func NewLark(log *slog.Logger) (*Lark, error) { t := &starlark.Thread{ Name: "config thread", } + config := starlark.NewDict(0) preConfig := starlark.StringDict{ "json": mjson.Module, - "config": starlark.NewDict(0), + "config": config, } - gb, err := starlark.ExecFileOptions(syntax.LegacyFileOptions(), t, "preload.star", defaultConfig, preConfig) + _, err := starlark.ExecFileOptions(syntax.LegacyFileOptions(), t, "preload.star", defaultConfig, preConfig) if err != nil { if evalErr, ok := err.(*starlark.EvalError); ok { - log.Fatal(evalErr.Backtrace()) + log.Error("failed to evaluate starlark preload", "trace", evalErr.Backtrace()) } return nil, err } - // TODO: search for config file - return &Lark{ - t: t, - g: gb, - }, nil + l := &Lark{ + t: t, + config: config, + log: log, + } + if err := l.loadConfig(); err != nil { + log.Error("failed to load config", "err", err) + } + log.Info("config", "conf", config) + return l, nil +} + +func (o *Lark) loadConfig() error { + path, err := getConfigPath() + if err != nil { + return err + } + o.log.Info("loading config", "path", path) + preConfig := starlark.StringDict{ + "json": mjson.Module, + "config": o.config, + } + _, err = starlark.ExecFileOptions(syntax.LegacyFileOptions(), o.t, path, nil, preConfig) + if err != nil { + if evalErr, ok := err.(*starlark.EvalError); ok { + o.log.Error("failed to evaluate starlark config", "path", path, "trace", evalErr.Backtrace()) + } + return err + } + return nil } func Must[T any](value T, err error) T { @@ -103,7 +131,7 @@ func (l *Lark) Truthy(path ...string) bool { } func (l *Lark) Val(path ...string) (starlark.Value, error) { - val := l.g["config"].(*starlark.Dict) + val := l.config for idx, item := range path { tmpVal, ok, err := val.Get(starlark.String(item)) if err != nil { @@ -135,6 +163,18 @@ func (l *Lark) Float64(path ...string) (float64, error) { return float64(str), nil } +func (l *Lark) Int(path ...string) (int, error) { + val, err := l.Val(path...) + if err != nil { + return 0, err + } + str, ok := val.(starlark.Int) + if !ok { + return 0, ErrWrongType + } + return int(str.BigInt().Int64()), nil +} + func (l *Lark) Str(path ...string) (string, error) { val, err := l.Val(path...) if err != nil { @@ -186,6 +226,5 @@ func compact(x string) string { if err := json.Compact(dst, []byte(x)); err != nil { panic(err) } - log.Println(string(dst.String())) return dst.String() } diff --git a/app/darktile/gui/gui.go b/app/darktile/gui/gui.go index 2c9deb4..ee09fab 100644 --- a/app/darktile/gui/gui.go +++ b/app/darktile/gui/gui.go @@ -54,9 +54,9 @@ const ( ) func New(terminal *termutil2.Terminal, c *config.Lark, log *slog.Logger) (*GUI, error) { + g := &GUI{ terminal: terminal, - size: image.Point{80, 30}, updateChan: make(chan struct{}), fontManager: font.NewManager(), activeHinter: -1, @@ -67,21 +67,9 @@ func New(terminal *termutil2.Terminal, c *config.Lark, log *slog.Logger) (*GUI, theme: termutil.ThemeFromLark(c), } terminal.SetWindowManipulator(NewManipulator(g)) - return g, nil -} - -func (g *GUI) Run(s fx.Shutdowner) error { - go func() { - if err := g.terminal.Run(g.updateChan, uint16(g.size.X), uint16(g.size.Y)); err != nil { - fmt.Fprintf(os.Stderr, "Fatal error: %s", err) - s.Shutdown(fx.ExitCode(1)) - } - s.Shutdown(fx.ExitCode(0)) - }() - font, err := g.c.Font("font") if err != nil { - return err + return nil, err } g.log.Info("running gui", "font", font) g.fontManager.SetFontByFamilyName(font.Family) @@ -93,8 +81,8 @@ func (g *GUI) Run(s fx.Shutdowner) error { } g.fontManager.SetDPI(96) g.enableLigatures = font.Ligatures - - ebiten.SetWindowTitle("erm") + title := config.Default("erm")(g.c.Str("title")) + ebiten.SetWindowTitle(title) ebiten.SetScreenClearedEveryFrame(true) ebiten.SetWindowResizingMode(ebiten.WindowResizingModeEnabled) ebiten.SetRunnableOnUnfocused(true) @@ -106,11 +94,39 @@ func (g *GUI) Run(s fx.Shutdowner) error { ebiten.SetVsyncEnabled(false) } + rows := config.Default(128)(g.c.Int("initial_rows")) + cols := config.Default(128)(g.c.Int("initial_cols")) + + scale := ebiten.Monitor().DeviceScaleFactor() + w := int(cols * g.fontManager.CharSize().X) + h := int(rows * g.fontManager.CharSize().Y) + initialSize := image.Point{ + int(float64(w) * scale), int(float64(h) * scale), + } + g.size = initialSize + ebiten.SetWindowSize(w, h) + return g, nil +} + +func (g *GUI) Run(s fx.Shutdowner) error { + rows := config.Default(128)(g.c.Int("initial_rows")) + cols := config.Default(128)(g.c.Int("initial_cols")) + go func() { + if err := g.terminal.Run(g.updateChan, uint16(rows), uint16(cols)); err != nil { + fmt.Fprintf(os.Stderr, "Fatal error: %s", err) + s.Shutdown(fx.ExitCode(1)) + } + s.Shutdown(fx.ExitCode(0)) + }() + + title := config.Default("erm")(g.c.Str("title")) for _, f := range g.startupFuncs { go f(g) } - - return ebiten.RunGame(g) + g.log.Info("initial size", "size", g.size) + return ebiten.RunGameWithOptions(g, &ebiten.RunGameOptions{ + X11ClassName: title, + }) } func (g *GUI) CellSize() image.Point { diff --git a/app/darktile/gui/resize.go b/app/darktile/gui/resize.go index 5aec96e..c3a63a9 100644 --- a/app/darktile/gui/resize.go +++ b/app/darktile/gui/resize.go @@ -14,8 +14,7 @@ func (g *GUI) Layout(outsideWidth, outsideHeight int) (int, int) { // Layout provides the terminal gui size in pixels. Required to implement the ebiten interface. func (g *GUI) LayoutF(outsideWidth, outsideHeight float64) (float64, float64) { - - scale := ebiten.DeviceScaleFactor() + scale := ebiten.Monitor().DeviceScaleFactor() sw, sh := math.Ceil(scale*outsideWidth), math.Ceil(scale*outsideHeight) w, h := int(sw), int(sh) @@ -43,6 +42,7 @@ func (g *GUI) resize(w, h int) { defer g.terminal.Unlock() if g.terminal.IsRunning() { + g.log.Info("terminal resizing", "w", w, "h", h, "rows", rows, "cols", cols) _ = g.terminal.SetSize(rows, cols) } } diff --git a/app/darktile/termutil/terminal.go b/app/darktile/termutil/terminal.go index e824628..76c0d1a 100644 --- a/app/darktile/termutil/terminal.go +++ b/app/darktile/termutil/terminal.go @@ -37,7 +37,8 @@ type Terminal struct { shell string initialCommand string - log *slog.Logger + config *config.Lark + log *slog.Logger } // NewTerminal creates a new terminal instance @@ -47,6 +48,7 @@ func New(c *config.Lark, log *slog.Logger) *Terminal { closeChan: make(chan struct{}), theme: ThemeFromLark(c), log: log, + config: c, } fg := term.theme.DefaultForeground() @@ -152,6 +154,7 @@ func (t *Terminal) Run(updateChan chan struct{}, rows uint16, cols uint16) error // Make sure to close the pty at the end. defer func() { _ = t.pty.Close() }() // Best effort. + t.log.Info("terminal started", "rows", rows, "cols", cols) if err := t.SetSize(rows, cols); err != nil { return err } @@ -170,7 +173,8 @@ func (t *Terminal) Run(updateChan chan struct{}, rows uint16, cols uint16) error t.running = true - t.windowManipulator.SetTitle("erm") + title := config.Default("erm")(t.config.Str("title")) + t.windowManipulator.SetTitle(title) if t.initialCommand != "" { if err := t.WriteToPty([]byte(t.initialCommand)); err != nil { diff --git a/go.mod b/go.mod index 3fd3f87..5f18d32 100644 --- a/go.mod +++ b/go.mod @@ -1,23 +1,24 @@ module tuxpa.in/t/erm -go 1.21.3 +go 1.22.0 -toolchain go1.22.0 +toolchain go1.22.5 require ( - gfx.cafe/util/go v1.1.0 - github.com/alecthomas/kong v0.7.1 - github.com/creack/pty v1.1.12 + anime.bike/slogutil v0.0.0-20240603065252-938fd61854c6 + gfx.cafe/util/go v1.14.0 + github.com/alecthomas/kong v1.2.1 + github.com/creack/pty v1.1.23 github.com/d-tsuji/clipboard v0.0.3 - github.com/hajimehoshi/ebiten/v2 v2.7.0-alpha.7 - github.com/lmittmann/tint v1.0.4 - github.com/mazznoer/csscolorparser v0.1.3 + github.com/hajimehoshi/ebiten/v2 v2.8.1 + github.com/lmittmann/tint v1.0.5 + github.com/mazznoer/csscolorparser v0.1.5 github.com/skratchdot/open-golang v0.0.0-20200116055534-eef842397966 - github.com/stretchr/testify v1.8.4 - go.starlark.net v0.0.0-20240123142251-f86470692795 - go.uber.org/fx v1.20.1 - golang.org/x/image v0.15.0 - golang.org/x/text v0.14.0 + github.com/stretchr/testify v1.9.0 + go.starlark.net v0.0.0-20240925182052-1207426daebd + go.uber.org/fx v1.23.0 + golang.org/x/image v0.21.0 + golang.org/x/text v0.19.0 mvdan.cc/xurls v1.1.0 ) @@ -26,21 +27,21 @@ require ( github.com/BurntSushi/xgb v0.0.0-20200324125942-20f126ea2843 // indirect github.com/c2h5oh/datasize v0.0.0-20231215233829-aa82cc1e6500 // indirect github.com/davecgh/go-spew v1.1.1 // indirect - github.com/ebitengine/hideconsole v0.1.1-0.20240128160611-57e7b6b00abd // indirect - github.com/ebitengine/purego v0.6.0-alpha.4.0.20240127153756-e7ad88ddfffe // indirect + github.com/ebitengine/gomobile v0.0.0-20240911145611-4856209ac325 // indirect + github.com/ebitengine/hideconsole v1.0.0 // indirect + github.com/ebitengine/purego v0.8.0 // indirect github.com/google/go-cmp v0.5.9 // indirect github.com/jezek/xgb v1.1.1 // indirect github.com/lxn/walk v0.0.0-20191128110447-55ccb3a9f5c1 // indirect github.com/lxn/win v0.0.0-20191128105842-2da648fda5b4 // indirect + github.com/modern-go/reflect2 v1.0.2 // indirect github.com/mvdan/xurls v1.1.0 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect - go.uber.org/dig v1.17.1 // indirect + go.uber.org/dig v1.18.0 // indirect go.uber.org/multierr v1.11.0 // indirect - go.uber.org/zap v1.26.0 // indirect - golang.org/x/exp/shiny v0.0.0-20240205201215-2c58cdc269a3 // indirect - golang.org/x/mobile v0.0.0-20240112133503-c713f31d574b // indirect - golang.org/x/sync v0.6.0 // indirect - golang.org/x/sys v0.16.0 // indirect + go.uber.org/zap v1.27.0 // indirect + golang.org/x/sync v0.8.0 // indirect + golang.org/x/sys v0.25.0 // indirect golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect gopkg.in/Knetic/govaluate.v3 v3.0.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect diff --git a/go.sum b/go.sum index 801eb06..6c014ed 100644 --- a/go.sum +++ b/go.sum @@ -1,88 +1,88 @@ -gfx.cafe/util/go v1.1.0 h1:0zn2DDjC6ervotcRgeqrvZpvFJkJlqYISU+WDjpvFiY= -gfx.cafe/util/go v1.1.0/go.mod h1:1jKv4bpEdBfr5jHw5yqwciUQW6Uztiq9XhVOpwDLUhI= +anime.bike/slogutil v0.0.0-20240603065252-938fd61854c6 h1:IwPf+xd2sxj2r4DJGsv0OYmG2Xm5dgUhm6OVrxE4asI= +anime.bike/slogutil v0.0.0-20240603065252-938fd61854c6/go.mod h1:iod7Bhpk1ewwZEu/kpUfQs0iR2TuPjiwj0ZtkyHY5ck= +gfx.cafe/util/go v1.14.0 h1:W15T4ZQSraASbl1eNZmF8pEsM435uAEIxTBzx691vRg= +gfx.cafe/util/go v1.14.0/go.mod h1:s6KPm1PUsYFL00XoMOI+Y2iorVPZ+9yBc1WWUjI0n9Y= git.wow.st/gmp/clip v0.0.0-20191001134149-1458ba6a7cf5 h1:OKeTjZST+/TKvtdA258NXJH+/gIx/xwyZxKrAezNFvk= git.wow.st/gmp/clip v0.0.0-20191001134149-1458ba6a7cf5/go.mod h1:NLdpaBoMQNFqncwP8OVRNWUDw1Kt9XWm3snfT7cXu24= github.com/BurntSushi/xgb v0.0.0-20200324125942-20f126ea2843 h1:3iF31c7rp7nGZVDv7YQ+VxOgpipVfPKotLXykjZmwM8= github.com/BurntSushi/xgb v0.0.0-20200324125942-20f126ea2843/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= -github.com/alecthomas/assert/v2 v2.1.0 h1:tbredtNcQnoSd3QBhQWI7QZ3XHOVkw1Moklp2ojoH/0= -github.com/alecthomas/assert/v2 v2.1.0/go.mod h1:b/+1DI2Q6NckYi+3mXyH3wFb8qG37K/DuK80n7WefXA= -github.com/alecthomas/kong v0.7.1 h1:azoTh0IOfwlAX3qN9sHWTxACE2oV8Bg2gAwBsMwDQY4= -github.com/alecthomas/kong v0.7.1/go.mod h1:n1iCIO2xS46oE8ZfYCNDqdR0b0wZNrXAIAqro/2132U= -github.com/alecthomas/repr v0.1.0 h1:ENn2e1+J3k09gyj2shc0dHr/yjaWSHRlrJ4DPMevDqE= -github.com/alecthomas/repr v0.1.0/go.mod h1:2kn6fqh/zIyPLmm3ugklbEi5hg5wS435eygvNfaDQL8= -github.com/benbjohnson/clock v1.3.0 h1:ip6w0uFQkncKQ979AypyG0ER7mqUSBdKLOgAle/AT8A= -github.com/benbjohnson/clock v1.3.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= +github.com/alecthomas/assert/v2 v2.10.0 h1:jjRCHsj6hBJhkmhznrCzoNpbA3zqy0fYiUcYZP/GkPY= +github.com/alecthomas/assert/v2 v2.10.0/go.mod h1:Bze95FyfUr7x34QZrjL+XP+0qgp/zg8yS+TtBj1WA3k= +github.com/alecthomas/kong v1.2.1 h1:E8jH4Tsgv6wCRX2nGrdPyHDUCSG83WH2qE4XLACD33Q= +github.com/alecthomas/kong v1.2.1/go.mod h1:rKTSFhbdp3Ryefn8x5MOEprnRFQ7nlmMC01GKhehhBM= +github.com/alecthomas/repr v0.4.0 h1:GhI2A8MACjfegCPVq9f1FLvIBS+DrQ2KQBFZP1iFzXc= +github.com/alecthomas/repr v0.4.0/go.mod h1:Fr0507jx4eOXV7AlPV6AVZLYrLIuIeSOWtW57eE/O/4= github.com/c2h5oh/datasize v0.0.0-20231215233829-aa82cc1e6500 h1:6lhrsTEnloDPXyeZBvSYvQf8u86jbKehZPVDDlkgDl4= github.com/c2h5oh/datasize v0.0.0-20231215233829-aa82cc1e6500/go.mod h1:S/7n9copUssQ56c7aAgHqftWO4LTf4xY6CGWt8Bc+3M= -github.com/creack/pty v1.1.12 h1:2QLiUCEbsI13vUyWH6026g0o4u7vxgg2hLUc+D7FPFU= -github.com/creack/pty v1.1.12/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= +github.com/creack/pty v1.1.23 h1:4M6+isWdcStXEf15G/RbrMPOQj1dZ7HPZCGwE4kOeP0= +github.com/creack/pty v1.1.23/go.mod h1:08sCNb52WyoAwi2QDyzUCTgcvVFhUzewun7wtTfvcwE= github.com/d-tsuji/clipboard v0.0.3 h1:ceGmYEF+uiuSZXnAfMu56DDZaSN+SgM2+3OHrNy0ABY= github.com/d-tsuji/clipboard v0.0.3/go.mod h1:hF88aLYx9LHNUFRrT6KPRkXEUm34nqP97IFgORGBRFs= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/ebitengine/hideconsole v0.1.1-0.20240128160611-57e7b6b00abd h1:ZOUjLrx0thTZUs43SlHbC/SnLX1ApeCV3S+wElVZfjE= -github.com/ebitengine/hideconsole v0.1.1-0.20240128160611-57e7b6b00abd/go.mod h1:hTTBTvVYWKBuxPr7peweneWdkUwEuHuB3C1R/ielR1A= -github.com/ebitengine/purego v0.6.0-alpha.4.0.20240127153756-e7ad88ddfffe h1:bac7sG+vDG+mBmjElwI0p1a2L09rxkY8xcmv5QEFyGA= -github.com/ebitengine/purego v0.6.0-alpha.4.0.20240127153756-e7ad88ddfffe/go.mod h1:ah1In8AOtksoNK6yk5z1HTJeUkC1Ez4Wk2idgGslMwQ= +github.com/ebitengine/gomobile v0.0.0-20240911145611-4856209ac325 h1:Gk1XUEttOk0/hb6Tq3WkmutWa0ZLhNn/6fc6XZpM7tM= +github.com/ebitengine/gomobile v0.0.0-20240911145611-4856209ac325/go.mod h1:ulhSQcbPioQrallSuIzF8l1NKQoD7xmMZc5NxzibUMY= +github.com/ebitengine/hideconsole v1.0.0 h1:5J4U0kXF+pv/DhiXt5/lTz0eO5ogJ1iXb8Yj1yReDqE= +github.com/ebitengine/hideconsole v1.0.0/go.mod h1:hTTBTvVYWKBuxPr7peweneWdkUwEuHuB3C1R/ielR1A= +github.com/ebitengine/purego v0.8.0 h1:JbqvnEzRvPpxhCJzJJ2y0RbiZ8nyjccVUrSM3q+GvvE= +github.com/ebitengine/purego v0.8.0/go.mod h1:iIjxzd6CiRiOG0UyXP+V1+jWqUXVjPKLAI0mRfJZTmQ= github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= -github.com/hajimehoshi/bitmapfont/v3 v3.0.0 h1:r2+6gYK38nfztS/et50gHAswb9hXgxXECYgE8Nczmi4= -github.com/hajimehoshi/bitmapfont/v3 v3.0.0/go.mod h1:+CxxG+uMmgU4mI2poq944i3uZ6UYFfAkj9V6WqmuvZA= -github.com/hajimehoshi/ebiten/v2 v2.7.0-alpha.7 h1:RnopmjZT7Nh0FWpwS1pH9oBLYGT+DOoRNp9Sr2gjhVU= -github.com/hajimehoshi/ebiten/v2 v2.7.0-alpha.7/go.mod h1:1Lvt+5rJa8DW8zzEP+1XrnpXQpSWPn/Hk7KjNXmHfq0= +github.com/hajimehoshi/bitmapfont/v3 v3.2.0 h1:0DISQM/rseKIJhdF29AkhvdzIULqNIIlXAGWit4ez1Q= +github.com/hajimehoshi/bitmapfont/v3 v3.2.0/go.mod h1:8gLqGatKVu0pwcNCJguW3Igg9WQqVXF0zg/RvrGQWyg= +github.com/hajimehoshi/ebiten/v2 v2.8.1 h1:6n6ZXnbeSCZccdqrH7s9Ut+dll9TEostUqbc72Tis/g= +github.com/hajimehoshi/ebiten/v2 v2.8.1/go.mod h1:SXx/whkvpfsavGo6lvZykprerakl+8Uo1X8d2U5aAnA= github.com/hexops/gotextdiff v1.0.3 h1:gitA9+qJrrTCsiCl7+kh75nPqQt1cx4ZkudSTLoUqJM= github.com/hexops/gotextdiff v1.0.3/go.mod h1:pSWU5MAI3yDq+fZBTazCSJysOMbxWL1BSow5/V2vxeg= github.com/jezek/xgb v1.1.1 h1:bE/r8ZZtSv7l9gk6nU0mYx51aXrvnyb44892TwSaqS4= github.com/jezek/xgb v1.1.1/go.mod h1:nrhwO0FX/enq75I7Y7G8iN1ubpSGZEiA3v9e9GyRFlk= -github.com/lmittmann/tint v1.0.4 h1:LeYihpJ9hyGvE0w+K2okPTGUdVLfng1+nDNVR4vWISc= -github.com/lmittmann/tint v1.0.4/go.mod h1:HIS3gSy7qNwGCj+5oRjAutErFBl4BzdQP6cJZ0NfMwE= +github.com/lmittmann/tint v1.0.5 h1:NQclAutOfYsqs2F1Lenue6OoWCajs5wJcP3DfWVpePw= +github.com/lmittmann/tint v1.0.5/go.mod h1:HIS3gSy7qNwGCj+5oRjAutErFBl4BzdQP6cJZ0NfMwE= github.com/lxn/walk v0.0.0-20191128110447-55ccb3a9f5c1 h1:/QwQcwWVOQXcoNuV9tHx30gQ3q7jCE/rKcGjwzsa5tg= github.com/lxn/walk v0.0.0-20191128110447-55ccb3a9f5c1/go.mod h1:E23UucZGqpuUANJooIbHWCufXvOcT6E7Stq81gU+CSQ= github.com/lxn/win v0.0.0-20191128105842-2da648fda5b4 h1:5BmtGkQbch91lglMHQ9JIDGiYCL3kBRBA0ItZTvOcEI= github.com/lxn/win v0.0.0-20191128105842-2da648fda5b4/go.mod h1:ouWl4wViUNh8tPSIwxTVMuS014WakR1hqvBc2I0bMoA= -github.com/mazznoer/csscolorparser v0.1.3 h1:vug4zh6loQxAUxfU1DZEu70gTPufDPspamZlHAkKcxE= -github.com/mazznoer/csscolorparser v0.1.3/go.mod h1:Aj22+L/rYN/Y6bj3bYqO3N6g1dtdHtGfQ32xZ5PJQic= +github.com/mazznoer/csscolorparser v0.1.5 h1:Wr4uNIE+pHWN3TqZn2SGpA2nLRG064gB7WdSfSS5cz4= +github.com/mazznoer/csscolorparser v0.1.5/go.mod h1:OQRVvgCyHDCAquR1YWfSwwaDcM0LhnSffGnlbOew/3I= +github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= +github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= github.com/mvdan/xurls v1.1.0 h1:OpuDelGQ1R1ueQ6sSryzi6P+1RtBpfQHM8fJwlE45ww= github.com/mvdan/xurls v1.1.0/go.mod h1:tQlNn3BED8bE/15hnSL2HLkDeLWpNPAwtw7wkEq44oU= +github.com/pierrec/lz4/v4 v4.1.21 h1:yOVMLb6qSIDP67pl/5F7RepeKYu/VmTyEXvuMI5d9mQ= +github.com/pierrec/lz4/v4 v4.1.21/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/skratchdot/open-golang v0.0.0-20200116055534-eef842397966 h1:JIAuq3EEf9cgbU6AtGPK4CTG3Zf6CKMNqf0MHTggAUA= github.com/skratchdot/open-golang v0.0.0-20200116055534-eef842397966/go.mod h1:sUM3LWHvSMaG192sy56D9F7CNvL7jUJVXoqM1QKLnog= -github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= -github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= -go.starlark.net v0.0.0-20240123142251-f86470692795 h1:LmbG8Pq7KDGkglKVn8VpZOZj6vb9b8nKEGcg9l03epM= -go.starlark.net v0.0.0-20240123142251-f86470692795/go.mod h1:LcLNIzVOMp4oV+uusnpk+VU+SzXaJakUuBjoCSWH5dM= -go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE= -go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= -go.uber.org/dig v1.17.1 h1:Tga8Lz8PcYNsWsyHMZ1Vm0OQOUaJNDyvPImgbAu9YSc= -go.uber.org/dig v1.17.1/go.mod h1:Us0rSJiThwCv2GteUN0Q7OKvU7n5J4dxZ9JKUXozFdE= -go.uber.org/fx v1.20.1 h1:zVwVQGS8zYvhh9Xxcu4w1M6ESyeMzebzj2NbSayZ4Mk= -go.uber.org/fx v1.20.1/go.mod h1:iSYNbHf2y55acNCwCXKx7LbWb5WG1Bnue5RDXz1OREg= -go.uber.org/goleak v1.2.0 h1:xqgm/S+aQvhWFTtR0XK3Jvg7z8kGV8P4X14IzwN3Eqk= -go.uber.org/goleak v1.2.0/go.mod h1:XJYK+MuIchqpmGmUSAzotztawfKvYLUIgg7guXrwVUo= +github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= +github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +go.starlark.net v0.0.0-20240925182052-1207426daebd h1:S+EMisJOHklQxnS3kqsY8jl2y5aF0FDEdcLnOw3q22E= +go.starlark.net v0.0.0-20240925182052-1207426daebd/go.mod h1:YKMCv9b1WrfWmeqdV5MAuEHWsu5iC+fe6kYl2sQjdI8= +go.uber.org/dig v1.18.0 h1:imUL1UiY0Mg4bqbFfsRQO5G4CGRBec/ZujWTvSVp3pw= +go.uber.org/dig v1.18.0/go.mod h1:Us0rSJiThwCv2GteUN0Q7OKvU7n5J4dxZ9JKUXozFdE= +go.uber.org/fx v1.23.0 h1:lIr/gYWQGfTwGcSXWXu4vP5Ws6iqnNEIY+F/aFzCKTg= +go.uber.org/fx v1.23.0/go.mod h1:o/D9n+2mLP6v1EG+qsdT1O8wKopYAsqZasju97SDFCU= +go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= +go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= -go.uber.org/zap v1.26.0 h1:sI7k6L95XOKS281NhVKOFCUNIvv9e0w4BF8N3u+tCRo= -go.uber.org/zap v1.26.0/go.mod h1:dtElttAiwGvoJ/vj4IwHBS/gXsEu/pZ50mUIRWuG0so= -golang.org/x/exp/shiny v0.0.0-20240205201215-2c58cdc269a3 h1:tImqKNm/Iclm3Rqb6GffLiURSp3m1iRx/C4mturH8Ys= -golang.org/x/exp/shiny v0.0.0-20240205201215-2c58cdc269a3/go.mod h1:3F+MieQB7dRYLTmnncoFbb1crS5lfQoTfDgQy6K4N0o= -golang.org/x/image v0.15.0 h1:kOELfmgrmJlw4Cdb7g/QGuB3CvDrXbqEIww/pNtNBm8= -golang.org/x/image v0.15.0/go.mod h1:HUYqC05R2ZcZ3ejNQsIHQDQiwWM4JBqmm6MKANTp4LE= -golang.org/x/mobile v0.0.0-20240112133503-c713f31d574b h1:kfWLZgb8iUBHdE9WydD5V5dHIS/F6HjlBZNyJfn2bs4= -golang.org/x/mobile v0.0.0-20240112133503-c713f31d574b/go.mod h1:4efzQnuA1nICq6h4kmZRMGzbPiP06lZvgADUu1VpJCE= -golang.org/x/sync v0.6.0 h1:5BMeUDZ7vkXGfEr1x9B4bRcTH4lpkTkpdh0T/J+qjbQ= -golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8= +go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= +golang.org/x/image v0.21.0 h1:c5qV36ajHpdj4Qi0GnE0jUc/yuo33OLFaa0d+crTD5s= +golang.org/x/image v0.21.0/go.mod h1:vUbsLavqK/W303ZroQQVKQ+Af3Yl6Uz1Ppu5J/cLz78= +golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= +golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200509044756-6aff5f38e54f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.16.0 h1:xWw16ngr6ZMtmxDyKyIgsE93KNKz5HKmMa3b8ALHidU= -golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= -golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= +golang.org/x/sys v0.25.0 h1:r+8e+loiHxRqhXVl6ML1nO3l1+oFoWbnlu2Ehimmi34= +golang.org/x/sys v0.25.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/text v0.19.0 h1:kTxAhCbGbxhK0IwgSKiMO5awPoDQ0RpfiVYBfK860YM= +golang.org/x/text v0.19.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -google.golang.org/protobuf v1.25.0 h1:Ejskq+SyPohKW+1uil0JJMtmHCgJPJ/qWTxr8qp+R4c= -google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= +google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= +google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= gopkg.in/Knetic/govaluate.v3 v3.0.0 h1:18mUyIt4ZlRlFZAAfVetz4/rzlJs9yhN+U02F4u1AOc= gopkg.in/Knetic/govaluate.v3 v3.0.0/go.mod h1:csKLBORsPbafmSCGTEh3U7Ozmsuq8ZSIlKk1bcqph0E= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=